Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / system / device_disabling_manager.cc
blob9bc2b4114ddb3cd8f44a49982c2ec8e2b2844731
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/system/device_disabling_manager.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/browser_process_platform_part.h"
14 #include "chrome/browser/chromeos/login/existing_user_controller.h"
15 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
16 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
17 #include "chrome/browser/chromeos/policy/server_backed_device_state.h"
18 #include "chrome/common/pref_names.h"
19 #include "chromeos/chromeos_switches.h"
20 #include "chromeos/settings/cros_settings_names.h"
21 #include "chromeos/settings/cros_settings_provider.h"
22 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
23 #include "components/user_manager/user_manager.h"
25 namespace chromeos {
26 namespace system {
28 DeviceDisablingManager::Observer::~Observer() {
31 DeviceDisablingManager::Delegate::~Delegate() {
34 DeviceDisablingManager::DeviceDisablingManager(
35 Delegate* delegate,
36 CrosSettings* cros_settings,
37 user_manager::UserManager* user_manager)
38 : delegate_(delegate),
39 browser_policy_connector_(g_browser_process->platform_part()->
40 browser_policy_connector_chromeos()),
41 cros_settings_(cros_settings),
42 user_manager_(user_manager),
43 device_disabled_(false),
44 weak_factory_(this) {
45 CHECK(delegate_);
46 Init();
49 DeviceDisablingManager::~DeviceDisablingManager() {
52 void DeviceDisablingManager::AddObserver(Observer* observer) {
53 observers_.AddObserver(observer);
56 void DeviceDisablingManager::RemoveObserver(Observer* observer) {
57 observers_.RemoveObserver(observer);
60 void DeviceDisablingManager::Init() {
61 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
62 switches::kDisableDeviceDisabling)) {
63 // If device disabling is turned off by flags, do not start monitoring cros
64 // settings.
65 return;
68 device_disabled_subscription_ = cros_settings_->AddSettingsObserver(
69 kDeviceDisabled,
70 base::Bind(&DeviceDisablingManager::UpdateFromCrosSettings,
71 weak_factory_.GetWeakPtr()));
72 disabled_message_subscription_ = cros_settings_->AddSettingsObserver(
73 kDeviceDisabledMessage,
74 base::Bind(&DeviceDisablingManager::UpdateFromCrosSettings,
75 weak_factory_.GetWeakPtr()));
77 UpdateFromCrosSettings();
80 void DeviceDisablingManager::CacheDisabledMessageAndNotify(
81 const std::string& disabled_message) {
82 if (disabled_message == disabled_message_)
83 return;
85 disabled_message_ = disabled_message;
86 FOR_EACH_OBSERVER(Observer,
87 observers_,
88 OnDisabledMessageChanged(disabled_message_));
91 void DeviceDisablingManager::CheckWhetherDeviceDisabledDuringOOBE(
92 const DeviceDisabledCheckCallback& callback) {
93 if (policy::GetRestoreMode() != policy::RESTORE_MODE_DISABLED ||
94 base::CommandLine::ForCurrentProcess()->HasSwitch(
95 switches::kDisableDeviceDisabling)) {
96 // Indicate that the device is not disabled if it is not marked as such in
97 // local state or device disabling has been turned off by flag.
98 callback.Run(false);
99 return;
102 if (browser_policy_connector_->GetDeviceMode() ==
103 policy::DEVICE_MODE_PENDING) {
104 // If the device mode is not known yet, request to be called back once it
105 // becomes known.
106 browser_policy_connector_->GetInstallAttributes()->ReadImmutableAttributes(
107 base::Bind(
108 &DeviceDisablingManager::CheckWhetherDeviceDisabledDuringOOBE,
109 weak_factory_.GetWeakPtr(),
110 callback));
111 return;
114 if (browser_policy_connector_->GetDeviceMode() !=
115 policy::DEVICE_MODE_NOT_SET) {
116 // If the device is owned already, this method must have been called after
117 // OOBE, which is an error. Indicate that the device is not disabled to
118 // prevent spurious disabling. Actual device disabling after OOBE will be
119 // handled elsewhere, by checking for disabled state in cros settings.
120 LOG(ERROR) << "CheckWhetherDeviceDisabledDuringOOBE() called after OOBE.";
121 callback.Run(false);
122 return;
125 // The device is marked as disabled in local state (based on the device state
126 // retrieved early during OOBE). Since device disabling has not been turned
127 // off by flag and the device is still unowned, we honor the information in
128 // local state and consider the device disabled.
130 // Update the enrollment domain.
131 enrollment_domain_.clear();
132 g_browser_process->local_state()->GetDictionary(
133 prefs::kServerBackedDeviceState)->GetString(
134 policy::kDeviceStateManagementDomain,
135 &enrollment_domain_);
137 // Update the disabled message.
138 std::string disabled_message;
139 g_browser_process->local_state()->GetDictionary(
140 prefs::kServerBackedDeviceState)->GetString(
141 policy::kDeviceStateDisabledMessage,
142 &disabled_message);
143 CacheDisabledMessageAndNotify(disabled_message);
145 // Indicate that the device is disabled.
146 callback.Run(true);
149 // static
150 bool DeviceDisablingManager::HonorDeviceDisablingDuringNormalOperation() {
151 // Device disabling should be honored when the device is enterprise managed
152 // and device disabling has not been turned off by flag.
153 return g_browser_process->platform_part()
154 ->browser_policy_connector_chromeos()
155 ->IsEnterpriseManaged() &&
156 !base::CommandLine::ForCurrentProcess()->HasSwitch(
157 switches::kDisableDeviceDisabling);
160 void DeviceDisablingManager::UpdateFromCrosSettings() {
161 if (cros_settings_->PrepareTrustedValues(base::Bind(
162 &DeviceDisablingManager::UpdateFromCrosSettings,
163 weak_factory_.GetWeakPtr())) != CrosSettingsProvider::TRUSTED) {
164 // If the cros settings are not trusted yet, request to be called back
165 // later.
166 return;
169 if (!HonorDeviceDisablingDuringNormalOperation()) {
170 // If the device is not enterprise managed or device disabling has been
171 // turned of by flag, device disabling is not available.
172 return;
175 bool should_device_be_disabled = false;
176 if (!cros_settings_->GetBoolean(kDeviceDisabled,
177 &should_device_be_disabled) ||
178 !should_device_be_disabled) {
179 // The device should not be disabled.
181 if (!device_disabled_) {
182 // If the device is currently not disabled, there is nothing to do.
183 return;
186 // Re-enable the device.
187 device_disabled_ = false;
189 // The device was disabled and has been re-enabled. Normal function should
190 // be resumed. Since the device disabled screen abruptly interrupts the
191 // regular login screen flows, Chrome should be restarted to return to a
192 // well-defined state.
193 delegate_->RestartToLoginScreen();
194 return;
197 // Update the disabled message.
198 std::string disabled_message;
199 cros_settings_->GetString(kDeviceDisabledMessage, &disabled_message);
200 CacheDisabledMessageAndNotify(disabled_message);
202 if (device_disabled_) {
203 // If the device was disabled already, updating the disabled message is the
204 // only action required.
205 return;
207 device_disabled_ = true;
209 const ExistingUserController* existing_user_controller =
210 ExistingUserController::current_controller();
211 if (user_manager_->GetActiveUser() ||
212 (existing_user_controller &&
213 existing_user_controller->IsSigninInProgress())) {
214 // If a session or a login is in progress, restart Chrome and return to the
215 // login screen. Chrome will show the device disabled screen after the
216 // restart.
217 delegate_->RestartToLoginScreen();
218 return;
221 // Cache the enrollment domain.
222 enrollment_domain_ = browser_policy_connector_->GetEnterpriseDomain();
224 // If no session or login is in progress, show the device disabled screen.
225 delegate_->ShowDeviceDisabledScreen();
228 } // namespace system
229 } // namespace chromeos