diff options
19 files changed, 816 insertions, 67 deletions
diff --git a/chrome/browser/browser_process_platform_part_chromeos.cc b/chrome/browser/browser_process_platform_part_chromeos.cc index 85de24b..9ae7863 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.cc +++ b/chrome/browser/browser_process_platform_part_chromeos.cc @@ -14,10 +14,13 @@ #include "chrome/browser/chromeos/memory/oom_priority_manager.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/system/automatic_reboot_manager.h" #include "chrome/browser/chromeos/system/device_disabling_manager.h" +#include "chrome/browser/chromeos/system/device_disabling_manager_default_delegate.h" #include "chrome/browser/profiles/profile.h" #include "components/session_manager/core/session_manager.h" +#include "components/user_manager/user_manager.h" BrowserProcessPlatformPart::BrowserProcessPlatformPart() : created_profile_helper_(false) { @@ -52,12 +55,17 @@ void BrowserProcessPlatformPart::DestroyChromeUserManager() { void BrowserProcessPlatformPart::InitializeDeviceDisablingManager() { DCHECK(!device_disabling_manager_); + device_disabling_manager_delegate_.reset( + new chromeos::system::DeviceDisablingManagerDefaultDelegate); device_disabling_manager_.reset(new chromeos::system::DeviceDisablingManager( - browser_policy_connector_chromeos())); + device_disabling_manager_delegate_.get(), + chromeos::CrosSettings::Get(), + user_manager::UserManager::Get())); } void BrowserProcessPlatformPart::ShutdownDeviceDisablingManager() { device_disabling_manager_.reset(); + device_disabling_manager_delegate_.reset(); } void BrowserProcessPlatformPart::InitializeSessionManager( diff --git a/chrome/browser/browser_process_platform_part_chromeos.h b/chrome/browser/browser_process_platform_part_chromeos.h index ef354ec..311a7c8 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.h +++ b/chrome/browser/browser_process_platform_part_chromeos.h @@ -24,6 +24,7 @@ namespace chromeos { namespace system { class AutomaticRebootManager; class DeviceDisablingManager; +class DeviceDisablingManagerDefaultDelegate; } } @@ -106,6 +107,8 @@ class BrowserProcessPlatformPart : public BrowserProcessPlatformPartBase, scoped_ptr<chromeos::ChromeUserManager> chrome_user_manager_; + scoped_ptr<chromeos::system::DeviceDisablingManagerDefaultDelegate> + device_disabling_manager_delegate_; scoped_ptr<chromeos::system::DeviceDisablingManager> device_disabling_manager_; diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 512b528..c2d7a3c 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -751,6 +751,8 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() { WallpaperManager::Get()->Shutdown(); #endif + // Let the DeviceDisablingManager unregister itself as an observer of the + // CrosSettings singleton before it is destroyed. g_browser_process->platform_part()->ShutdownDeviceDisablingManager(); // Let the AutomaticRebootManager unregister itself as an observer of several diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index 7fce49e..883dd94 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc @@ -41,6 +41,7 @@ #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/chromeos/system/device_disabling_manager.h" #include "chrome/browser/signin/easy_unlock_service.h" #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" #include "chrome/common/chrome_switches.h" @@ -435,13 +436,26 @@ void ExistingUserController::Login(const UserContext& user_context, 1, HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); - // Reenable clicking on other windows and the status area. Do not start the + // Re-enable clicking on other windows and the status area. Do not start the // auto-login timer though. Without trusted |cros_settings_|, no auto-login // can succeed. login_display_->SetUIEnabled(true); return; } + bool device_disabled = false; + cros_settings_->GetBoolean(kDeviceDisabled, &device_disabled); + if (device_disabled && system::DeviceDisablingManager:: + HonorDeviceDisablingDuringNormalOperation()) { + // If the device is disabled, bail out. A device disabled screen will be + // shown by the DeviceDisablingManager. + + // Re-enable clicking on other windows and the status area. Do not start the + // auto-login timer though. On a disabled device, no auto-login can succeed. + login_display_->SetUIEnabled(true); + return; + } + if (is_login_in_progress_) { // If there is another login in progress, bail out. Do not re-enable // clicking on other windows and the status area. Do not start the diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen.cc b/chrome/browser/chromeos/login/screens/device_disabled_screen.cc index e7c5d7e..bcd4395 100644 --- a/chrome/browser/chromeos/login/screens/device_disabled_screen.cc +++ b/chrome/browser/chromeos/login/screens/device_disabled_screen.cc @@ -10,7 +10,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/login/wizard_controller.h" -#include "chrome/browser/chromeos/system/device_disabling_manager.h" namespace chromeos { @@ -18,16 +17,20 @@ DeviceDisabledScreen::DeviceDisabledScreen( BaseScreenDelegate* base_screen_delegate, DeviceDisabledScreenActor* actor) : BaseScreen(base_screen_delegate), - showing_(false), - actor_(actor) { + actor_(actor), + device_disabling_manager_(g_browser_process->platform_part()-> + device_disabling_manager()), + showing_(false) { DCHECK(actor_); if (actor_) actor_->SetDelegate(this); + device_disabling_manager_->AddObserver(this); } DeviceDisabledScreen::~DeviceDisabledScreen() { if (actor_) actor_->SetDelegate(nullptr); + device_disabling_manager_->RemoveObserver(this); } void DeviceDisabledScreen::PrepareToShow() { @@ -38,8 +41,7 @@ void DeviceDisabledScreen::Show() { return; showing_ = true; - actor_->Show(g_browser_process->platform_part()->device_disabling_manager()-> - disabled_message()); + actor_->Show(device_disabling_manager_->disabled_message()); } void DeviceDisabledScreen::Hide() { @@ -60,4 +62,10 @@ void DeviceDisabledScreen::OnActorDestroyed(DeviceDisabledScreenActor* actor) { actor_ = nullptr; } +void DeviceDisabledScreen::OnDisabledMessageChanged( + const std::string& disabled_message) { + if (actor_) + actor_->UpdateMessage(disabled_message); +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen.h b/chrome/browser/chromeos/login/screens/device_disabled_screen.h index 35bd8c1..b51ceb2 100644 --- a/chrome/browser/chromeos/login/screens/device_disabled_screen.h +++ b/chrome/browser/chromeos/login/screens/device_disabled_screen.h @@ -8,14 +8,20 @@ #include "base/macros.h" #include "chrome/browser/chromeos/login/screens/base_screen.h" #include "chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h" +#include "chrome/browser/chromeos/system/device_disabling_manager.h" namespace chromeos { +namespace system { +class DeviceDisablingManager; +} + class BaseScreenDelegate; // Screen informing the user that the device has been disabled by its owner. class DeviceDisabledScreen : public BaseScreen, - public DeviceDisabledScreenActor::Delegate { + public DeviceDisabledScreenActor::Delegate, + public system::DeviceDisablingManager::Observer { public: DeviceDisabledScreen(BaseScreenDelegate* base_screen_delegate, DeviceDisabledScreenActor* actor); @@ -30,12 +36,16 @@ class DeviceDisabledScreen : public BaseScreen, // DeviceDisabledScreenActor::Delegate: void OnActorDestroyed(DeviceDisabledScreenActor* actor) override; + // system::DeviceDisablingManager::Observer: + void OnDisabledMessageChanged(const std::string& disabled_message) override; + private: + DeviceDisabledScreenActor* actor_; + system::DeviceDisablingManager* device_disabling_manager_; + // Whether the screen is currently showing. bool showing_; - DeviceDisabledScreenActor* actor_; - DISALLOW_COPY_AND_ASSIGN(DeviceDisabledScreen); }; diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h b/chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h index bbfae36..ab86330 100644 --- a/chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h +++ b/chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h @@ -29,6 +29,7 @@ class DeviceDisabledScreenActor { virtual void Show(const std::string& message) = 0; virtual void Hide() = 0; virtual void SetDelegate(Delegate* delegate) = 0; + virtual void UpdateMessage(const std::string& message) = 0; }; } // namespace chromeos diff --git a/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h b/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h index 3d18683..a8a631f 100644 --- a/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h +++ b/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h @@ -19,6 +19,7 @@ class MockDeviceDisabledScreenActor : public DeviceDisabledScreenActor { MOCK_METHOD1(Show, void(const std::string&)); MOCK_METHOD0(Hide, void()); + MOCK_METHOD1(UpdateMessage, void(const std::string& message)); private: MOCK_METHOD1(MockSetDelegate, void(Delegate* delegate)); diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 8253a2e..5d0ee9d 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc @@ -1119,6 +1119,15 @@ void WizardController::AutoLaunchKioskApp() { return; } + bool device_disabled = false; + CrosSettings::Get()->GetBoolean(kDeviceDisabled, &device_disabled); + if (device_disabled && system::DeviceDisablingManager:: + HonorDeviceDisablingDuringNormalOperation()) { + // If the device is disabled, bail out. A device disabled screen will be + // shown by the DeviceDisablingManager. + return; + } + host_->StartAppLaunch(app_id, false /* diagnostic_mode */); } diff --git a/chrome/browser/chromeos/system/device_disabling_browsertest.cc b/chrome/browser/chromeos/system/device_disabling_browsertest.cc new file mode 100644 index 0000000..79250c8 --- /dev/null +++ b/chrome/browser/chromeos/system/device_disabling_browsertest.cc @@ -0,0 +1,94 @@ +// Copyright 2014 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 "base/command_line.h" +#include "base/memory/scoped_ptr.h" +#include "base/run_loop.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" +#include "chrome/browser/chromeos/policy/device_policy_builder.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/chromeos_switches.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_session_manager_client.h" +#include "chromeos/settings/cros_settings_names.h" +#include "policy/proto/device_management_backend.pb.h" + +namespace chromeos { +namespace system { + +class DeviceDisablingTest : public InProcessBrowserTest { + public: + DeviceDisablingTest(); + + // Device policy is updated in two steps: + // - First, set up the policy builder that GetDevicePolicyBuilder() returns. + // - Second, call SimulatePolicyFetch() to build and flush the resulting + // policy blob to the browser. + policy::DevicePolicyBuilder* GetDevicePolicyBuilder(); + void SimulatePolicyFetch(); + + private: + // InProcessBrowserTest: + void SetUpInProcessBrowserTestFixture() override; + void SetUpCommandLine(CommandLine* command_line) override; + + FakeSessionManagerClient* fake_session_manager_client_; + policy::DevicePolicyCrosTestHelper test_helper_; + + DISALLOW_COPY_AND_ASSIGN(DeviceDisablingTest); +}; + + +DeviceDisablingTest::DeviceDisablingTest() + : fake_session_manager_client_(new FakeSessionManagerClient) { +} + +policy::DevicePolicyBuilder* DeviceDisablingTest::GetDevicePolicyBuilder() { + return test_helper_.device_policy(); +} + +void DeviceDisablingTest::SimulatePolicyFetch() { + GetDevicePolicyBuilder()->Build(); + fake_session_manager_client_->set_device_policy( + GetDevicePolicyBuilder()->GetBlob()); + fake_session_manager_client_->OnPropertyChangeComplete(true); +} + +void DeviceDisablingTest::SetUpInProcessBrowserTestFixture() { + DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( + scoped_ptr<SessionManagerClient>(fake_session_manager_client_)); + + test_helper_.InstallOwnerKey(); + test_helper_.MarkAsEnterpriseOwned(); +} + +void DeviceDisablingTest::SetUpCommandLine(CommandLine* command_line) { + command_line->AppendSwitch(switches::kLoginManager); + command_line->AppendSwitch(switches::kForceLoginManagerInTests); +} + +IN_PROC_BROWSER_TEST_F(DeviceDisablingTest, DisableDuringNormalOperation) { + // Mark the device as disabled and wait until cros settings update. + base::RunLoop run_loop; + scoped_ptr<CrosSettings::ObserverSubscription> observer = + CrosSettings::Get()->AddSettingsObserver( + kDeviceDisabled, + run_loop.QuitClosure()); + GetDevicePolicyBuilder()->policy_data().mutable_device_state()-> + set_device_mode(enterprise_management::DeviceState::DEVICE_MODE_DISABLED); + SimulatePolicyFetch(); + run_loop.Run(); + + // Verify that the device disabled screen is being shown. + WizardController* wizard_controller = WizardController::default_controller(); + ASSERT_TRUE(wizard_controller); + EXPECT_EQ(wizard_controller->GetScreen( + WizardController::kDeviceDisabledScreenName), + wizard_controller->current_screen()); +} + +} // namespace system +} // namespace chromeos diff --git a/chrome/browser/chromeos/system/device_disabling_manager.cc b/chrome/browser/chromeos/system/device_disabling_manager.cc index ae2410e..59a3807 100644 --- a/chrome/browser/chromeos/system/device_disabling_manager.cc +++ b/chrome/browser/chromeos/system/device_disabling_manager.cc @@ -10,25 +10,84 @@ #include "base/prefs/pref_service.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" #include "chrome/browser/chromeos/policy/server_backed_device_state.h" #include "chrome/common/pref_names.h" #include "chromeos/chromeos_switches.h" +#include "chromeos/settings/cros_settings_names.h" +#include "chromeos/settings/cros_settings_provider.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/user_manager/user_manager.h" namespace chromeos { namespace system { +DeviceDisablingManager::Observer::~Observer() { +} + +DeviceDisablingManager::Delegate::~Delegate() { +} + DeviceDisablingManager::DeviceDisablingManager( - policy::BrowserPolicyConnectorChromeOS* browser_policy_connector) - : browser_policy_connector_(browser_policy_connector), + Delegate* delegate, + CrosSettings* cros_settings, + user_manager::UserManager* user_manager) + : delegate_(delegate), + browser_policy_connector_(g_browser_process->platform_part()-> + browser_policy_connector_chromeos()), + cros_settings_(cros_settings), + user_manager_(user_manager), + device_disabled_(false), weak_factory_(this) { + CHECK(delegate_); + Init(); } DeviceDisablingManager::~DeviceDisablingManager() { } +void DeviceDisablingManager::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void DeviceDisablingManager::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void DeviceDisablingManager::Init() { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableDeviceDisabling)) { + // If device disabling is turned off by flags, do not start monitoring cros + // settings. + return; + } + + device_disabled_subscription_ = cros_settings_->AddSettingsObserver( + kDeviceDisabled, + base::Bind(&DeviceDisablingManager::UpdateFromCrosSettings, + weak_factory_.GetWeakPtr())); + disabled_message_subscription_ = cros_settings_->AddSettingsObserver( + kDeviceDisabledMessage, + base::Bind(&DeviceDisablingManager::UpdateFromCrosSettings, + weak_factory_.GetWeakPtr())); + + UpdateFromCrosSettings(); +} + +void DeviceDisablingManager::CacheDisabledMessageAndNotify( + const std::string& disabled_message) { + if (disabled_message == disabled_message_) + return; + + disabled_message_ = disabled_message; + FOR_EACH_OBSERVER(Observer, + observers_, + OnDisabledMessageChanged(disabled_message_)); +} + void DeviceDisablingManager::CheckWhetherDeviceDisabledDuringOOBE( const DeviceDisabledCheckCallback& callback) { if (policy::GetRestoreMode() != policy::RESTORE_MODE_DISABLED || @@ -68,16 +127,88 @@ void DeviceDisablingManager::CheckWhetherDeviceDisabledDuringOOBE( // off by flag and the device is still unowned, we honor the information in // local state and consider the device disabled. - // Cache the disabled message. - disabled_message_.clear(); + // Update the disabled message. + std::string disabled_message; g_browser_process->local_state()->GetDictionary( prefs::kServerBackedDeviceState)->GetString( policy::kDeviceStateDisabledMessage, - &disabled_message_); + &disabled_message); + CacheDisabledMessageAndNotify(disabled_message); // Indicate that the device is disabled. callback.Run(true); } +// static +bool DeviceDisablingManager::HonorDeviceDisablingDuringNormalOperation() { + // Device disabling should be honored when the device is enterprise managed + // and device disabling has not been turned off by flag. + return g_browser_process->platform_part()-> + browser_policy_connector_chromeos()->IsEnterpriseManaged() && + !CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableDeviceDisabling); +} + +void DeviceDisablingManager::UpdateFromCrosSettings() { + if (cros_settings_->PrepareTrustedValues(base::Bind( + &DeviceDisablingManager::UpdateFromCrosSettings, + weak_factory_.GetWeakPtr())) != CrosSettingsProvider::TRUSTED) { + // If the cros settings are not trusted yet, request to be called back + // later. + return; + } + + if (!HonorDeviceDisablingDuringNormalOperation()) { + // If the device is not enterprise managed or device disabling has been + // turned of by flag, device disabling is not available. + return; + } + + bool device_disabled = false; + if (!cros_settings_->GetBoolean(kDeviceDisabled, &device_disabled) || + !device_disabled) { + if (!device_disabled_) { + // If the device was not disabled and has not been disabled, there is + // nothing to do. + return; + } + device_disabled_ = false; + + // The device was disabled and has been re-enabled. Normal function should + // be resumed. Since the device disabled screen abruptly interrupts the + // regular login screen flows, Chrome should be restarted to return to a + // well-defined state. + delegate_->RestartToLoginScreen(); + return; + } + + // Update the disabled message. + std::string disabled_message; + cros_settings_->GetString(kDeviceDisabledMessage, &disabled_message); + CacheDisabledMessageAndNotify(disabled_message); + + if (device_disabled_) { + // If the device was disabled already, updating the disabled message is the + // only action required. + return; + } + device_disabled_ = true; + + const ExistingUserController* existing_user_controller = + ExistingUserController::current_controller(); + if (user_manager_->GetActiveUser() || + (existing_user_controller && + existing_user_controller->IsSigninInProgress())) { + // If a session or a login is in progress, restart Chrome and return to the + // login screen. Chrome will show the device disabled screen after the + // restart. + delegate_->RestartToLoginScreen(); + return; + } + + // If no session or login is in progress, show the device disabled screen. + delegate_->ShowDeviceDisabledScreen(); +} + } // namespace system } // namespace chromeos diff --git a/chrome/browser/chromeos/system/device_disabling_manager.h b/chrome/browser/chromeos/system/device_disabling_manager.h index eeded82..7dbf2cb 100644 --- a/chrome/browser/chromeos/system/device_disabling_manager.h +++ b/chrome/browser/chromeos/system/device_disabling_manager.h @@ -9,12 +9,19 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" namespace policy { class BrowserPolicyConnectorChromeOS; } +namespace user_manager { +class UserManager; +} + namespace chromeos { namespace system { @@ -31,29 +38,91 @@ namespace system { // device disabled screen. // - If the device has not been wiped, the disabled state is retrieved with // every device policy fetch as part of the |PolicyData| protobuf, parsed and -// written to the |chromeos::kDeviceDisabled| cros setting. -// -// TODO(bartfab): Make this class subscribe to the cros setting and trigger -// the device disabled screen. http://crbug.com/425574 +// written to the |chromeos::kDeviceDisabled| cros setting. This class +// monitors the cros setting. When the device becomes disabled, one of two +// actions is taken: +// 1) If no session is in progress, the device disabled screen is shown +// immediately. +// 2) If a session is in progress, the session is terminated. After Chrome has +// restarted on the login screen, the disabled screen is shown per 1). +// This ensures that when a device is disabled, there is never any user +// session running in the backround. +// When the device is re-enabled, Chrome is restarted once more to resume the +// regular login screen flows from a known-good point. class DeviceDisablingManager { public: using DeviceDisabledCheckCallback = base::Callback<void(bool)>; - explicit DeviceDisablingManager( - policy::BrowserPolicyConnectorChromeOS* browser_policy_connector); + class Observer { + public: + virtual ~Observer(); + + virtual void OnDisabledMessageChanged( + const std::string& disabled_message) = 0; + + private: + DISALLOW_ASSIGN(Observer); + }; + + class Delegate { + public: + virtual ~Delegate(); + + // Terminate the current session (if any) and restart Chrome to show the + // login screen. + virtual void RestartToLoginScreen() = 0; + + // Show the device disabled screen. + virtual void ShowDeviceDisabledScreen() = 0; + + private: + DISALLOW_ASSIGN(Delegate); + }; + + // |delegate| must outlive |this|. + DeviceDisablingManager(Delegate* delegate, + CrosSettings* cros_settings, + user_manager::UserManager* user_manager); ~DeviceDisablingManager(); + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + // Returns the cached disabled message. The message is only guaranteed to be // up to date if the disabled screen was triggered. const std::string& disabled_message() const { return disabled_message_; } - // Checks whether the device is disabled. |callback| will be invoked with the - // result of the check. + // Performs a check whether the device is disabled during OOBE. |callback| + // will be invoked with the result of the check. void CheckWhetherDeviceDisabledDuringOOBE( const DeviceDisabledCheckCallback& callback); + // Whenever trusted cros settings indicate that the device is disabled, this + // method should be used to check whether the device disabling is to be + // honored. If this method returns false, the device should not be disabled. + static bool HonorDeviceDisablingDuringNormalOperation(); + private: + void Init(); + + // Cache the disabled message and inform observers if it changed. + void CacheDisabledMessageAndNotify(const std::string& disabled_message); + + void UpdateFromCrosSettings(); + + Delegate* delegate_; policy::BrowserPolicyConnectorChromeOS* browser_policy_connector_; + CrosSettings* cros_settings_; + user_manager::UserManager* user_manager_; + + ObserverList<Observer> observers_; + + scoped_ptr<CrosSettings::ObserverSubscription> device_disabled_subscription_; + scoped_ptr<CrosSettings::ObserverSubscription> disabled_message_subscription_; + + // Indicates whether the device was disabled when the cros settings were last + // read. + bool device_disabled_; // A cached copy of the message to show on the device disabled screen. std::string disabled_message_; diff --git a/chrome/browser/chromeos/system/device_disabling_manager_default_delegate.cc b/chrome/browser/chromeos/system/device_disabling_manager_default_delegate.cc new file mode 100644 index 0000000..1ddf9e8 --- /dev/null +++ b/chrome/browser/chromeos/system/device_disabling_manager_default_delegate.cc @@ -0,0 +1,29 @@ +// Copyright 2014 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/chromeos/system/device_disabling_manager_default_delegate.h" + +#include "chrome/browser/chromeos/login/ui/login_display_host.h" +#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" +#include "chrome/browser/lifetime/application_lifetime.h" + +namespace chromeos { +namespace system { + +DeviceDisablingManagerDefaultDelegate::DeviceDisablingManagerDefaultDelegate() { +} + +void DeviceDisablingManagerDefaultDelegate::RestartToLoginScreen() { + chrome::AttemptUserExit(); +} + +void DeviceDisablingManagerDefaultDelegate::ShowDeviceDisabledScreen() { + LoginDisplayHostImpl::default_host()->StartWizard( + WizardController::kDeviceDisabledScreenName, + nullptr); +} + +} // namespace system +} // namespace chromeos diff --git a/chrome/browser/chromeos/system/device_disabling_manager_default_delegate.h b/chrome/browser/chromeos/system/device_disabling_manager_default_delegate.h new file mode 100644 index 0000000..2316e70 --- /dev/null +++ b/chrome/browser/chromeos/system/device_disabling_manager_default_delegate.h @@ -0,0 +1,30 @@ +// Copyright 2014 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. + +#ifndef CHROME_BROWSER_CHROMEOS_SYSTEM_DEVICE_DISABLING_MANAGER_DEFAULT_DELEGATE_H_ +#define CHROME_BROWSER_CHROMEOS_SYSTEM_DEVICE_DISABLING_MANAGER_DEFAULT_DELEGATE_H_ + +#include "base/macros.h" +#include "chrome/browser/chromeos/system/device_disabling_manager.h" + +namespace chromeos { +namespace system { + +class DeviceDisablingManagerDefaultDelegate + : public DeviceDisablingManager::Delegate { + public: + DeviceDisablingManagerDefaultDelegate(); + + private: + // DeviceDisablingManager::Delegate: + void RestartToLoginScreen() override; + void ShowDeviceDisabledScreen() override; + + DISALLOW_COPY_AND_ASSIGN(DeviceDisablingManagerDefaultDelegate); +}; + +} // namespace system +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_SYSTEM_DEVICE_DISABLING_MANAGER_DEFAULT_DELEGATE_H_ diff --git a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc index 4ef3eef3..c10c6e7 100644 --- a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc +++ b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc @@ -7,92 +7,168 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" #include "base/prefs/scoped_user_pref_update.h" #include "base/prefs/testing_pref_service.h" #include "base/run_loop.h" #include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" +#include "chrome/browser/chromeos/policy/device_policy_builder.h" #include "chrome/browser/chromeos/policy/server_backed_device_state.h" #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h" +#include "chrome/browser/chromeos/settings/device_settings_service.h" +#include "chrome/browser/chromeos/settings/device_settings_test_helper.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chromeos/chromeos_switches.h" +#include "components/ownership/mock_owner_key_util.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "policy/proto/device_management_backend.pb.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::_; +using testing::Mock; + namespace chromeos { namespace system { namespace { -const char kDisabledMessage[] = "Device disabled."; +const char kTestUser[] = "user@example.com"; +const char kDisabledMessage1[] = "Device disabled 1."; +const char kDisabledMessage2[] = "Device disabled 2."; } -class DeviceDisablingManagerTest : public testing::Test { +class DeviceDisablingManagerTestBase : public testing::Test, + public DeviceDisablingManager::Delegate { public: - DeviceDisablingManagerTest(); + DeviceDisablingManagerTestBase(); // testing::Test: + void TearDown() override; + + virtual void CreateDeviceDisablingManager(); + virtual void DestroyDeviceDisablingManager(); + + void SetRegistrationUser(const std::string& registration_user); + void SetDeviceMode(policy::DeviceMode device_mode); + void LogIn(); + + // DeviceDisablingManager::Delegate: + MOCK_METHOD0(RestartToLoginScreen, void()); + MOCK_METHOD0(ShowDeviceDisabledScreen, void()); + + DeviceDisablingManager* GetDeviceDisablingManager() { + return device_disabling_manager_.get(); + } + + private: + policy::ScopedStubEnterpriseInstallAttributes install_attributes_; + chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; + chromeos::ScopedTestCrosSettings test_cros_settings_; + FakeUserManager fake_user_manager_; + scoped_ptr<DeviceDisablingManager> device_disabling_manager_; + + DISALLOW_COPY_AND_ASSIGN(DeviceDisablingManagerTestBase); +}; + +DeviceDisablingManagerTestBase::DeviceDisablingManagerTestBase() + : install_attributes_("", "", "", policy::DEVICE_MODE_NOT_SET) { +} + +void DeviceDisablingManagerTestBase::TearDown() { + DestroyDeviceDisablingManager(); +} + +void DeviceDisablingManagerTestBase::CreateDeviceDisablingManager() { + device_disabling_manager_.reset(new DeviceDisablingManager( + this, + CrosSettings::Get(), + &fake_user_manager_)); +} + +void DeviceDisablingManagerTestBase::DestroyDeviceDisablingManager() { + device_disabling_manager_.reset(); +} + +void DeviceDisablingManagerTestBase::SetRegistrationUser( + const std::string& registration_user) { + reinterpret_cast<policy::StubEnterpriseInstallAttributes*>( + TestingBrowserProcess::GetGlobal()->platform_part()-> + browser_policy_connector_chromeos()->GetInstallAttributes())-> + SetRegistrationUser(registration_user); +} + +void DeviceDisablingManagerTestBase::SetDeviceMode( + policy::DeviceMode device_mode) { + reinterpret_cast<policy::StubEnterpriseInstallAttributes*>( + TestingBrowserProcess::GetGlobal()->platform_part()-> + browser_policy_connector_chromeos()->GetInstallAttributes())-> + SetMode(device_mode); +} + +void DeviceDisablingManagerTestBase::LogIn() { + fake_user_manager_.AddUser(kTestUser); +} + +// Base class for tests that verify device disabling behavior during OOBE, when +// the device is not owned yet. +class DeviceDisablingManagerOOBETest : public DeviceDisablingManagerTestBase { + public: + DeviceDisablingManagerOOBETest(); + + // DeviceDisablingManagerTestBase: void SetUp() override; void TearDown() override; bool device_disabled() const { return device_disabled_; } - const std::string& GetDisabledMessage() const; void CheckWhetherDeviceDisabledDuringOOBE(); void SetDeviceDisabled(bool disabled); - void SetDeviceMode(policy::DeviceMode device_mode); private: void OnDeviceDisabledChecked(bool device_disabled); - policy::ScopedStubEnterpriseInstallAttributes install_attributes_; TestingPrefServiceSimple local_state_; - scoped_ptr<DeviceDisablingManager> device_disabling_manager_; - base::RunLoop run_loop_; bool device_disabled_; - DISALLOW_COPY_AND_ASSIGN(DeviceDisablingManagerTest); + DISALLOW_COPY_AND_ASSIGN(DeviceDisablingManagerOOBETest); }; -DeviceDisablingManagerTest::DeviceDisablingManagerTest() - : install_attributes_("", "", "", policy::DEVICE_MODE_NOT_SET), - device_disabled_(false) { +DeviceDisablingManagerOOBETest::DeviceDisablingManagerOOBETest() + : device_disabled_(false) { + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); } -void DeviceDisablingManagerTest::SetUp() { +void DeviceDisablingManagerOOBETest::SetUp() { TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_); policy::DeviceCloudPolicyManagerChromeOS::RegisterPrefs( local_state_.registry()); - - device_disabling_manager_.reset(new DeviceDisablingManager( - TestingBrowserProcess::GetGlobal()->platform_part()-> - browser_policy_connector_chromeos())); + CreateDeviceDisablingManager(); } -void DeviceDisablingManagerTest::TearDown() { +void DeviceDisablingManagerOOBETest::TearDown() { + DeviceDisablingManagerTestBase::TearDown(); TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); } -const std::string& DeviceDisablingManagerTest::GetDisabledMessage() const { - return device_disabling_manager_->disabled_message(); - -} - -void DeviceDisablingManagerTest::CheckWhetherDeviceDisabledDuringOOBE() { - device_disabling_manager_->CheckWhetherDeviceDisabledDuringOOBE( - base::Bind(&DeviceDisablingManagerTest::OnDeviceDisabledChecked, +void DeviceDisablingManagerOOBETest::CheckWhetherDeviceDisabledDuringOOBE() { + GetDeviceDisablingManager()->CheckWhetherDeviceDisabledDuringOOBE( + base::Bind(&DeviceDisablingManagerOOBETest::OnDeviceDisabledChecked, base::Unretained(this))); run_loop_.Run(); } -void DeviceDisablingManagerTest::SetDeviceDisabled(bool disabled) { +void DeviceDisablingManagerOOBETest::SetDeviceDisabled(bool disabled) { DictionaryPrefUpdate dict(&local_state_, prefs::kServerBackedDeviceState); if (disabled) { dict->SetString(policy::kDeviceStateRestoreMode, @@ -100,30 +176,24 @@ void DeviceDisablingManagerTest::SetDeviceDisabled(bool disabled) { } else { dict->Remove(policy::kDeviceStateRestoreMode, nullptr); } - dict->SetString(policy::kDeviceStateDisabledMessage, kDisabledMessage); -} - -void DeviceDisablingManagerTest::SetDeviceMode(policy::DeviceMode device_mode) { - reinterpret_cast<policy::StubEnterpriseInstallAttributes*>( - TestingBrowserProcess::GetGlobal()->platform_part()-> - browser_policy_connector_chromeos()->GetInstallAttributes())-> - SetMode(device_mode); + dict->SetString(policy::kDeviceStateDisabledMessage, kDisabledMessage1); } -void DeviceDisablingManagerTest::OnDeviceDisabledChecked(bool device_disabled) { +void DeviceDisablingManagerOOBETest::OnDeviceDisabledChecked( + bool device_disabled) { device_disabled_ = device_disabled; run_loop_.Quit(); } // Verifies that the device is not considered disabled during OOBE by default. -TEST_F(DeviceDisablingManagerTest, NotDisabledByDefault) { +TEST_F(DeviceDisablingManagerOOBETest, NotDisabledByDefault) { CheckWhetherDeviceDisabledDuringOOBE(); EXPECT_FALSE(device_disabled()); } // Verifies that the device is not considered disabled during OOBE when it is // explicitly marked as not disabled. -TEST_F(DeviceDisablingManagerTest, NotDisabledWhenExplicitlyNotDisabled) { +TEST_F(DeviceDisablingManagerOOBETest, NotDisabledWhenExplicitlyNotDisabled) { SetDeviceDisabled(false); CheckWhetherDeviceDisabledDuringOOBE(); EXPECT_FALSE(device_disabled()); @@ -131,7 +201,7 @@ TEST_F(DeviceDisablingManagerTest, NotDisabledWhenExplicitlyNotDisabled) { // Verifies that the device is not considered disabled during OOBE when device // disabling is turned off by flag, even if the device is marked as disabled. -TEST_F(DeviceDisablingManagerTest, NotDisabledWhenTurnedOffByFlag) { +TEST_F(DeviceDisablingManagerOOBETest, NotDisabledWhenTurnedOffByFlag) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kDisableDeviceDisabling); SetDeviceDisabled(true); @@ -141,7 +211,7 @@ TEST_F(DeviceDisablingManagerTest, NotDisabledWhenTurnedOffByFlag) { // Verifies that the device is not considered disabled during OOBE when it is // already enrolled, even if the device is marked as disabled. -TEST_F(DeviceDisablingManagerTest, DoNotShowWhenEnterpriseOwned) { +TEST_F(DeviceDisablingManagerOOBETest, NotDisabledWhenEnterpriseOwned) { SetDeviceMode(policy::DEVICE_MODE_ENTERPRISE); SetDeviceDisabled(true); CheckWhetherDeviceDisabledDuringOOBE(); @@ -150,7 +220,7 @@ TEST_F(DeviceDisablingManagerTest, DoNotShowWhenEnterpriseOwned) { // Verifies that the device is not considered disabled during OOBE when it is // already owned by a consumer, even if the device is marked as disabled. -TEST_F(DeviceDisablingManagerTest, DoNotShowWhenConsumerOwned) { +TEST_F(DeviceDisablingManagerOOBETest, NotDisabledWhenConsumerOwned) { SetDeviceMode(policy::DEVICE_MODE_CONSUMER); SetDeviceDisabled(true); CheckWhetherDeviceDisabledDuringOOBE(); @@ -160,11 +230,271 @@ TEST_F(DeviceDisablingManagerTest, DoNotShowWhenConsumerOwned) { // Verifies that the device is considered disabled during OOBE when it is marked // as disabled, device disabling is not turned off by flag and the device is not // owned yet. -TEST_F(DeviceDisablingManagerTest, ShowWhenDisabledAndNotOwned) { +TEST_F(DeviceDisablingManagerOOBETest, ShowWhenDisabledAndNotOwned) { SetDeviceDisabled(true); CheckWhetherDeviceDisabledDuringOOBE(); EXPECT_TRUE(device_disabled()); - EXPECT_EQ(kDisabledMessage, GetDisabledMessage()); + EXPECT_EQ(kDisabledMessage1, GetDeviceDisablingManager()->disabled_message()); +} + +// Base class for tests that verify device disabling behavior once the device is +// owned. +class DeviceDisablingManagerTest : public DeviceDisablingManagerTestBase, + public DeviceDisablingManager::Observer { + public: + DeviceDisablingManagerTest(); + + // DeviceDisablingManagerTestBase: + void TearDown() override; + void CreateDeviceDisablingManager() override; + void DestroyDeviceDisablingManager() override; + + //DeviceDisablingManager::Observer: + MOCK_METHOD1(OnDisabledMessageChanged, void(const std::string&)); + + void SetUnowned(); + void SetEnterpriseOwned(); + void SetConsumerOwned(); + void MakeCrosSettingsTrusted(); + + void SetDeviceDisabled(bool disabled); + void SetDisabledMessage(const std::string& disabled_message); + + private: + void SimulatePolicyFetch(); + + content::TestBrowserThreadBundle thread_bundle_; + chromeos::DeviceSettingsTestHelper device_settings_test_helper_; + policy::DevicePolicyBuilder device_policy_; + + DISALLOW_COPY_AND_ASSIGN(DeviceDisablingManagerTest); +}; + +DeviceDisablingManagerTest::DeviceDisablingManagerTest() { +} + +void DeviceDisablingManagerTest::TearDown() { + chromeos::DeviceSettingsService::Get()->UnsetSessionManager(); + DeviceDisablingManagerTestBase::TearDown(); +} + +void DeviceDisablingManagerTest::CreateDeviceDisablingManager() { + DeviceDisablingManagerTestBase::CreateDeviceDisablingManager(); + GetDeviceDisablingManager()->AddObserver(this); +} + +void DeviceDisablingManagerTest::DestroyDeviceDisablingManager() { + if (GetDeviceDisablingManager()) + GetDeviceDisablingManager()->RemoveObserver(this); + DeviceDisablingManagerTestBase::DestroyDeviceDisablingManager(); +} + +void DeviceDisablingManagerTest::SetUnowned() { + SetRegistrationUser(std::string()); + SetDeviceMode(policy::DEVICE_MODE_NOT_SET); +} + +void DeviceDisablingManagerTest::SetEnterpriseOwned() { + SetRegistrationUser(kTestUser); + SetDeviceMode(policy::DEVICE_MODE_ENTERPRISE); +} + +void DeviceDisablingManagerTest::SetConsumerOwned() { + SetDeviceMode(policy::DEVICE_MODE_CONSUMER); +} + +void DeviceDisablingManagerTest::MakeCrosSettingsTrusted() { + scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util( + new ownership::MockOwnerKeyUtil); + owner_key_util->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey()); + chromeos::DeviceSettingsService::Get()->SetSessionManager( + &device_settings_test_helper_, + owner_key_util); + SimulatePolicyFetch(); +} + +void DeviceDisablingManagerTest::SetDeviceDisabled(bool disabled) { + if (disabled) { + device_policy_.policy_data().mutable_device_state()->set_device_mode( + enterprise_management::DeviceState::DEVICE_MODE_DISABLED); + } else { + device_policy_.policy_data().mutable_device_state()->clear_device_mode(); + } + SimulatePolicyFetch(); +} + +void DeviceDisablingManagerTest::SetDisabledMessage( + const std::string& disabled_message) { + device_policy_.policy_data().mutable_device_state()-> + mutable_disabled_state()->set_message(disabled_message); + SimulatePolicyFetch(); +} + +void DeviceDisablingManagerTest::SimulatePolicyFetch() { + device_policy_.Build(); + device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); + chromeos::DeviceSettingsService::Get()->OwnerKeySet(true); + device_settings_test_helper_.Flush(); +} + +// Verifies that the device is not considered disabled by default when it is +// enrolled for enterprise management. +TEST_F(DeviceDisablingManagerTest, NotDisabledByDefault) { + SetEnterpriseOwned(); + MakeCrosSettingsTrusted(); + + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + CreateDeviceDisablingManager(); +} + +// Verifies that the device is not considered disabled when it is explicitly +// marked as not disabled. +TEST_F(DeviceDisablingManagerTest, NotDisabledWhenExplicitlyNotDisabled) { + SetEnterpriseOwned(); + MakeCrosSettingsTrusted(); + SetDeviceDisabled(false); + + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + CreateDeviceDisablingManager(); +} + +// Verifies that the device is not considered disabled when device disabling is +// turned off by flag, even if the device is marked as disabled. +TEST_F(DeviceDisablingManagerTest, NotDisabledWhenTurnedOffByFlag) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisableDeviceDisabling); + SetEnterpriseOwned(); + MakeCrosSettingsTrusted(); + SetDeviceDisabled(true); + + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + CreateDeviceDisablingManager(); +} + +// Verifies that the device is not considered disabled when it is owned by a +// consumer, even if the device is marked as disabled. +TEST_F(DeviceDisablingManagerTest, NotDisabledWhenConsumerOwned) { + SetConsumerOwned(); + MakeCrosSettingsTrusted(); + SetDeviceDisabled(true); + + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + CreateDeviceDisablingManager(); +} + +// Verifies that the device disabled screen is shown immediately when the device +// is already marked as disabled on start-up. +TEST_F(DeviceDisablingManagerTest, DisabledOnLoginScreen) { + SetEnterpriseOwned(); + MakeCrosSettingsTrusted(); + SetDisabledMessage(kDisabledMessage1); + SetDeviceDisabled(true); + + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(1); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + CreateDeviceDisablingManager(); + EXPECT_EQ(kDisabledMessage1, GetDeviceDisablingManager()->disabled_message()); +} + +// Verifies that the device disabled screen is shown immediately when the device +// becomes disabled while the login screen is showing. Also verifies that Chrome +// restarts when the device becomes enabled again. +TEST_F(DeviceDisablingManagerTest, DisableAndReEnableOnLoginScreen) { + SetEnterpriseOwned(); + MakeCrosSettingsTrusted(); + SetDisabledMessage(kDisabledMessage1); + + // Verify that initially, the disabled screen is not shown and Chrome does not + // restart. + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + CreateDeviceDisablingManager(); + Mock::VerifyAndClearExpectations(this); + + // Mark the device as disabled. Verify that the device disabled screen is + // shown. + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(1); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(kDisabledMessage1)).Times(1); + SetDeviceDisabled(true); + Mock::VerifyAndClearExpectations(this); + EXPECT_EQ(kDisabledMessage1, GetDeviceDisablingManager()->disabled_message()); + + // Update the disabled message. Verify that the device disabled screen is + // updated. + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(kDisabledMessage2)).Times(1); + SetDisabledMessage(kDisabledMessage2); + Mock::VerifyAndClearExpectations(this); + EXPECT_EQ(kDisabledMessage2, GetDeviceDisablingManager()->disabled_message()); + + // Mark the device as enabled again. Verify that Chrome restarts. + EXPECT_CALL(*this, RestartToLoginScreen()).Times(1); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + SetDeviceDisabled(false); +} + +// Verifies that Chrome restarts when the device becomes disabled while a +// session is in progress. +TEST_F(DeviceDisablingManagerTest, DisableDuringSession) { + SetEnterpriseOwned(); + MakeCrosSettingsTrusted(); + SetDisabledMessage(kDisabledMessage1); + LogIn(); + + // Verify that initially, the disabled screen is not shown and Chrome does not + // restart. + EXPECT_CALL(*this, RestartToLoginScreen()).Times(0); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + CreateDeviceDisablingManager(); + Mock::VerifyAndClearExpectations(this); + + // Mark the device as disabled. Verify that Chrome restarts. + EXPECT_CALL(*this, RestartToLoginScreen()).Times(1); + EXPECT_CALL(*this, ShowDeviceDisabledScreen()).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(_)).Times(0); + EXPECT_CALL(*this, OnDisabledMessageChanged(kDisabledMessage1)).Times(1); + SetDeviceDisabled(true); +} + +// Verifies that the HonorDeviceDisablingDuringNormalOperation() method returns +// true iff the device is enterprise enrolled and device disabling is not turned +// off by flag. +TEST_F(DeviceDisablingManagerTest, HonorDeviceDisablingDuringNormalOperation) { + // Not enterprise owned, not disabled by flag. + EXPECT_FALSE( + DeviceDisablingManager::HonorDeviceDisablingDuringNormalOperation()); + + // Enterprise owned, not disabled by flag. + SetEnterpriseOwned(); + EXPECT_TRUE( + DeviceDisablingManager::HonorDeviceDisablingDuringNormalOperation()); + + // Enterprise owned, disabled by flag. + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisableDeviceDisabling); + EXPECT_FALSE( + DeviceDisablingManager::HonorDeviceDisablingDuringNormalOperation()); + + // Not enterprise owned, disabled by flag. + SetUnowned(); + EXPECT_FALSE( + DeviceDisablingManager::HonorDeviceDisablingDuringNormalOperation()); } } // namespace system diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc index 0ec8a0c..62a99d3 100644 --- a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc @@ -48,6 +48,12 @@ void DeviceDisabledScreenHandler::SetDelegate(Delegate* delegate) { Initialize(); } +void DeviceDisabledScreenHandler::UpdateMessage(const std::string& message) { + message_ = message; + if (page_is_ready()) + CallJS("setMessage", message); +} + void DeviceDisabledScreenHandler::DeclareLocalizedValues( LocalizedValuesBuilder* builder) { builder->Add("deviceDisabledHeading", IDS_DEVICE_DISABLED_HEADING); diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h index f794b3c..4fee52b 100644 --- a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h @@ -24,6 +24,7 @@ class DeviceDisabledScreenHandler : public DeviceDisabledScreenActor, void Show(const std::string& message) override; void Hide() override; void SetDelegate(Delegate* delegate) override; + void UpdateMessage(const std::string& message) override; // BaseScreenHandler: void DeclareLocalizedValues(LocalizedValuesBuilder* builder) override; diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 331d78e..98bfada 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -869,6 +869,8 @@ 'browser/chromeos/system/device_change_handler.h', 'browser/chromeos/system/device_disabling_manager.cc', 'browser/chromeos/system/device_disabling_manager.h', + 'browser/chromeos/system/device_disabling_manager_default_delegate.cc', + 'browser/chromeos/system/device_disabling_manager_default_delegate.h', 'browser/chromeos/system/input_device_settings.cc', 'browser/chromeos/system/input_device_settings.h', 'browser/chromeos/system/pointer_device_observer.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 5b9c7ed..44f7018 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -210,6 +210,7 @@ 'browser/chromeos/power/peripheral_battery_observer_browsertest.cc', 'browser/chromeos/preferences_browsertest.cc', 'browser/chromeos/profiles/profile_helper_browsertest.cc', + 'browser/chromeos/system/device_disabling_browsertest.cc', 'browser/chromeos/system/tray_accessibility_browsertest.cc', 'browser/chromeos/ui/idle_logout_dialog_view_browsertest.cc', 'browser/collected_cookies_browsertest.cc', |