1 // Copyright (c) 2012 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. 4 5 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" 6 7 #include <algorithm> 8 9 #include "base/bind.h" 10 #include "base/command_line.h" 11 #include "base/lazy_instance.h" 12 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h" 14 #include "chrome/browser/chromeos/login/user_manager.h" 15 #include "chrome/browser/chromeos/settings/cros_settings.h" 16 #include "chrome/browser/lifetime/application_lifetime.h" 17 #include "chrome/browser/policy/browser_policy_connector.h" 18 #include "chromeos/chromeos_switches.h" 19 #include "chromeos/settings/cros_settings_names.h" 20 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 21 #include "content/public/browser/browser_thread.h" 22 23 namespace chromeos { 24 25 namespace { 26 const int kDeviceModeFetchRetryDelayMs = 500; 27 } 28 29 const int KioskModeSettings::kMaxIdleLogoutTimeout = 600000; // ms 30 const int KioskModeSettings::kMinIdleLogoutTimeout = 5000; // ms 31 32 const int KioskModeSettings::kMaxIdleLogoutWarningDuration = 60000; // ms 33 const int KioskModeSettings::kMinIdleLogoutWarningDuration = 1000; // ms 34 35 static base::LazyInstance<KioskModeSettings> g_kiosk_mode_settings = 36 LAZY_INSTANCE_INITIALIZER; 37 38 // static 39 KioskModeSettings* KioskModeSettings::Get() { 40 return g_kiosk_mode_settings.Pointer(); 41 } 42 43 bool KioskModeSettings::IsKioskModeEnabled() { 44 return is_kiosk_mode_; 45 } 46 47 void KioskModeSettings::Initialize(const base::Closure& notify_initialized) { 48 // No need to call more than once. 49 if (is_initialized_) { 50 notify_initialized.Run(); 51 return; 52 } 53 54 CrosSettings* cros_settings = CrosSettings::Get(); 55 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues( 56 base::Bind(&KioskModeSettings::Initialize, 57 base::Unretained(this), 58 notify_initialized))) { 59 return; 60 } 61 62 // Ignored till we land the code to pull the screensaver path from the app 63 // packs with the screensaver id. 64 cros_settings->GetString(kScreenSaverExtensionId, &screensaver_id_); 65 66 int screensaver_timeout = 0; 67 int idle_logout_timeout = 0; 68 int idle_logout_warning_duration = 0; 69 cros_settings->GetInteger(kScreenSaverTimeout, &screensaver_timeout); 70 cros_settings->GetInteger(kIdleLogoutTimeout, &idle_logout_timeout); 71 cros_settings->GetInteger(kIdleLogoutWarningDuration, 72 &idle_logout_warning_duration); 73 74 // Restrict idle timeouts to safe values to prevent them from being turned off 75 // or otherwise misused. 76 idle_logout_timeout = std::min(idle_logout_timeout, 77 KioskModeSettings::kMaxIdleLogoutTimeout); 78 idle_logout_timeout = std::max(idle_logout_timeout, 79 KioskModeSettings::kMinIdleLogoutTimeout); 80 81 idle_logout_warning_duration = 82 std::min(idle_logout_warning_duration, 83 KioskModeSettings::kMaxIdleLogoutWarningDuration); 84 idle_logout_warning_duration = 85 std::max(idle_logout_warning_duration, 86 KioskModeSettings::kMinIdleLogoutWarningDuration); 87 88 screensaver_timeout_ = base::TimeDelta::FromMilliseconds( 89 screensaver_timeout); 90 idle_logout_timeout_ = 91 base::TimeDelta::FromMilliseconds(idle_logout_timeout); 92 idle_logout_warning_duration_ = 93 base::TimeDelta::FromMilliseconds(idle_logout_warning_duration); 94 95 is_initialized_ = true; 96 notify_initialized.Run(); 97 } 98 99 bool KioskModeSettings::is_initialized() const { 100 return is_initialized_; 101 } 102 103 void KioskModeSettings::GetScreensaverPath( 104 policy::AppPackUpdater::ScreenSaverUpdateCallback callback) const { 105 if (!is_initialized_) { 106 callback.Run(base::FilePath()); 107 return; 108 } 109 110 // Command line flag overrides policy since it can be used 111 // for testing and dev workflows. 112 if (CommandLine::ForCurrentProcess()->HasSwitch( 113 switches::kKioskModeScreensaverPath)) { 114 callback.Run(base::FilePath( 115 CommandLine::ForCurrentProcess()-> 116 GetSwitchValueASCII(switches::kKioskModeScreensaverPath))); 117 return; 118 } 119 120 if (g_browser_process) { 121 policy::BrowserPolicyConnector* bpc = 122 g_browser_process->browser_policy_connector(); 123 if (bpc && bpc->GetAppPackUpdater()) { 124 bpc->GetAppPackUpdater()->SetScreenSaverUpdateCallback(callback); 125 return; 126 } 127 } 128 } 129 130 base::TimeDelta KioskModeSettings::GetScreensaverTimeout() const { 131 if (!is_initialized_) 132 return base::TimeDelta::FromSeconds(-1); 133 134 return screensaver_timeout_; 135 } 136 137 base::TimeDelta KioskModeSettings::GetIdleLogoutTimeout() const { 138 if (!is_initialized_) 139 return base::TimeDelta::FromSeconds(-1); 140 141 return idle_logout_timeout_; 142 } 143 144 base::TimeDelta KioskModeSettings::GetIdleLogoutWarningDuration() const { 145 if (!is_initialized_) 146 return base::TimeDelta::FromSeconds(-1); 147 148 return idle_logout_warning_duration_; 149 } 150 151 KioskModeSettings::KioskModeSettings() : is_initialized_(false) { 152 // In case we've force-enabled kiosk mode. 153 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableKioskMode)) { 154 is_kiosk_mode_ = true; 155 return; 156 } 157 158 // Precache the value as we know it at construction time to avoid serving 159 // different values to different users. 160 if (g_browser_process) { 161 policy::BrowserPolicyConnector* bpc = 162 g_browser_process->browser_policy_connector(); 163 policy::DeviceMode device_mode = bpc->GetDeviceMode(); 164 if (device_mode == policy::DEVICE_MODE_RETAIL_KIOSK) { 165 is_kiosk_mode_ = true; 166 return; 167 } else if (device_mode == policy::DEVICE_MODE_PENDING){ 168 DeviceSettingsService::Get()->GetOwnershipStatusAsync( 169 base::Bind(&KioskModeSettings::VerifyModeIsKnown, 170 base::Unretained(this))); 171 } 172 } 173 is_kiosk_mode_ = false; 174 } 175 176 KioskModeSettings::~KioskModeSettings() { 177 } 178 179 void KioskModeSettings::VerifyModeIsKnown( 180 DeviceSettingsService::OwnershipStatus status) { 181 if (status != DeviceSettingsService::OWNERSHIP_TAKEN) 182 return; 183 184 if (g_browser_process) { 185 policy::BrowserPolicyConnector* bpc = 186 g_browser_process->browser_policy_connector(); 187 policy::DeviceMode device_mode = bpc->GetDeviceMode(); 188 // We retry asking for the mode until it becomes known. 189 switch (device_mode) { 190 case policy::DEVICE_MODE_PENDING: 191 content::BrowserThread::PostDelayedTask( 192 content::BrowserThread::UI, FROM_HERE, 193 base::Bind(&KioskModeSettings::VerifyModeIsKnown, 194 base::Unretained(this), status), 195 base::TimeDelta::FromMilliseconds(kDeviceModeFetchRetryDelayMs)); 196 break; 197 case policy::DEVICE_MODE_RETAIL_KIOSK: 198 chrome::ExitCleanly(); 199 break; 200 default: 201 break; 202 } 203 } 204 } 205 206 207 } // namespace chromeos 208