Home | History | Annotate | Download | only in kiosk_mode
      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/chromeos/settings/cros_settings_names.h"
     17 #include "chrome/browser/lifetime/application_lifetime.h"
     18 #include "chrome/browser/policy/browser_policy_connector.h"
     19 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
     20 #include "chromeos/chromeos_switches.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     bool is_owner) {
    182   if (status != DeviceSettingsService::OWNERSHIP_TAKEN)
    183     return;
    184 
    185   if (g_browser_process) {
    186     policy::BrowserPolicyConnector* bpc =
    187         g_browser_process->browser_policy_connector();
    188     policy::DeviceMode device_mode = bpc->GetDeviceMode();
    189     // We retry asking for the mode until it becomes known.
    190     switch (device_mode) {
    191       case policy::DEVICE_MODE_PENDING:
    192         content::BrowserThread::PostDelayedTask(
    193             content::BrowserThread::UI, FROM_HERE,
    194             base::Bind(&KioskModeSettings::VerifyModeIsKnown,
    195                        base::Unretained(this), status, is_owner),
    196             base::TimeDelta::FromMilliseconds(kDeviceModeFetchRetryDelayMs));
    197         break;
    198       case policy::DEVICE_MODE_RETAIL_KIOSK:
    199         chrome::ExitCleanly();
    200         break;
    201       default:
    202         break;
    203     }
    204   }
    205 }
    206 
    207 
    208 }  // namespace chromeos
    209