blob: 538636e697d114fe4525a4fc4a5cae4ff42fc5ca [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/managed_ui_handler.h"
#include <utility>
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/managed_ui.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(OS_CHROMEOS)
#include "ui/chromeos/devicetype_utils.h"
#endif
namespace {
policy::PolicyService* GetProfilePolicyService(Profile* profile) {
auto* profile_connector =
policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile);
return profile_connector->policy_service();
}
} // namespace
// static
void ManagedUIHandler::Initialize(content::WebUI* web_ui,
content::WebUIDataSource* source) {
InitializeInternal(web_ui, source, Profile::FromWebUI(web_ui));
}
// static
void ManagedUIHandler::InitializeInternal(content::WebUI* web_ui,
content::WebUIDataSource* source,
Profile* profile) {
auto handler = std::make_unique<ManagedUIHandler>(profile);
source->AddLocalizedStrings(*handler->GetDataSourceUpdate());
handler->source_name_ = source->GetSource();
web_ui->AddMessageHandler(std::move(handler));
}
ManagedUIHandler::ManagedUIHandler(Profile* profile)
: profile_(profile), managed_(chrome::ShouldDisplayManagedUi(profile_)) {
pref_registrar_.Init(profile_->GetPrefs());
}
ManagedUIHandler::~ManagedUIHandler() {
RemoveObservers();
}
void ManagedUIHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"observeManagedUI",
base::BindRepeating(&ManagedUIHandler::HandleObserveManagedUI,
base::Unretained(this)));
}
void ManagedUIHandler::HandleObserveManagedUI(const base::ListValue* /*args*/) {
AllowJavascript();
AddObservers();
}
void ManagedUIHandler::OnJavascriptDisallowed() {
RemoveObservers();
}
void ManagedUIHandler::OnPolicyUpdated(const policy::PolicyNamespace& ns,
const policy::PolicyMap& previous,
const policy::PolicyMap& current) {
NotifyIfChanged();
}
// Manually add/remove observers. ScopedObserver doesn't work with
// PolicyService::Observer because AddObserver() takes 2 arguments.
void ManagedUIHandler::AddObservers() {
if (has_observers_)
return;
has_observers_ = true;
auto* policy_service = GetProfilePolicyService(profile_);
for (int i = 0; i < policy::POLICY_DOMAIN_SIZE; i++) {
auto domain = static_cast<policy::PolicyDomain>(i);
policy_service->AddObserver(domain, this);
}
pref_registrar_.Add(prefs::kSupervisedUserId,
base::BindRepeating(&ManagedUIHandler::NotifyIfChanged,
base::Unretained(this)));
}
void ManagedUIHandler::RemoveObservers() {
if (!has_observers_)
return;
has_observers_ = false;
auto* policy_service = GetProfilePolicyService(profile_);
for (int i = 0; i < policy::POLICY_DOMAIN_SIZE; i++) {
auto domain = static_cast<policy::PolicyDomain>(i);
policy_service->RemoveObserver(domain, this);
}
pref_registrar_.RemoveAll();
}
std::unique_ptr<base::DictionaryValue> ManagedUIHandler::GetDataSourceUpdate()
const {
auto update = std::make_unique<base::DictionaryValue>();
update->SetKey("managedByOrg",
base::Value(l10n_util::GetStringFUTF16(
IDS_MANAGED_BY_ORG_WITH_HYPERLINK,
base::UTF8ToUTF16(chrome::kChromeUIManagementURL)
#if defined(OS_CHROMEOS)
,
ui::GetChromeOSDeviceName()
#endif
)));
update->SetKey("isManaged", base::Value(managed_));
return update;
}
void ManagedUIHandler::NotifyIfChanged() {
bool managed = chrome::ShouldDisplayManagedUi(profile_);
if (managed == managed_)
return;
managed_ = managed;
FireWebUIListener("is-managed-changed", base::Value(managed));
content::WebUIDataSource::Update(profile_, source_name_,
GetDataSourceUpdate());
}