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