15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDeviceModeFetchRetryDelayMs = 500;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int KioskModeSettings::kMaxIdleLogoutTimeout = 600000;  // ms
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int KioskModeSettings::kMinIdleLogoutTimeout = 5000;  // ms
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int KioskModeSettings::kMaxIdleLogoutWarningDuration = 60000;  // ms
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int KioskModeSettings::kMinIdleLogoutWarningDuration = 1000;  // ms
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::LazyInstance<KioskModeSettings> g_kiosk_mode_settings =
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KioskModeSettings* KioskModeSettings::Get() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_kiosk_mode_settings.Pointer();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool KioskModeSettings::IsKioskModeEnabled() {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_kiosk_mode_;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KioskModeSettings::Initialize(const base::Closure& notify_initialized) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No need to call more than once.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_initialized_) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notify_initialized.Run();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&KioskModeSettings::Initialize,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 notify_initialized))) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignored till we land the code to pull the screensaver path from the app
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // packs with the screensaver id.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cros_settings->GetString(kScreenSaverExtensionId, &screensaver_id_);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int screensaver_timeout = 0;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int idle_logout_timeout = 0;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int idle_logout_warning_duration = 0;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cros_settings->GetInteger(kScreenSaverTimeout, &screensaver_timeout);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cros_settings->GetInteger(kIdleLogoutTimeout, &idle_logout_timeout);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cros_settings->GetInteger(kIdleLogoutWarningDuration,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &idle_logout_warning_duration);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restrict idle timeouts to safe values to prevent them from being turned off
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or otherwise misused.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  idle_logout_timeout = std::min(idle_logout_timeout,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 KioskModeSettings::kMaxIdleLogoutTimeout);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  idle_logout_timeout = std::max(idle_logout_timeout,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 KioskModeSettings::kMinIdleLogoutTimeout);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  idle_logout_warning_duration =
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::min(idle_logout_warning_duration,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               KioskModeSettings::kMaxIdleLogoutWarningDuration);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  idle_logout_warning_duration =
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::max(idle_logout_warning_duration,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               KioskModeSettings::kMinIdleLogoutWarningDuration);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  screensaver_timeout_ = base::TimeDelta::FromMilliseconds(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      screensaver_timeout);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  idle_logout_timeout_ =
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(idle_logout_timeout);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  idle_logout_warning_duration_ =
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(idle_logout_warning_duration);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_initialized_ = true;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notify_initialized.Run();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool KioskModeSettings::is_initialized() const {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_initialized_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KioskModeSettings::GetScreensaverPath(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    policy::AppPackUpdater::ScreenSaverUpdateCallback callback) const {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_initialized_) {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(base::FilePath());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Command line flag overrides policy since it can be used
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for testing and dev workflows.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          switches::kKioskModeScreensaverPath)) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(base::FilePath(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CommandLine::ForCurrentProcess()->
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetSwitchValueASCII(switches::kKioskModeScreensaverPath)));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_browser_process) {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy::BrowserPolicyConnectorChromeOS* connector =
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        g_browser_process->platform_part()->browser_policy_connector_chromeos();
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (connector && connector->GetAppPackUpdater()) {
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      connector->GetAppPackUpdater()->SetScreenSaverUpdateCallback(callback);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta KioskModeSettings::GetScreensaverTimeout() const {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_initialized_)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta::FromSeconds(-1);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return screensaver_timeout_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta KioskModeSettings::GetIdleLogoutTimeout() const {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_initialized_)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta::FromSeconds(-1);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return idle_logout_timeout_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta KioskModeSettings::GetIdleLogoutWarningDuration() const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_initialized_)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta::FromSeconds(-1);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return idle_logout_warning_duration_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KioskModeSettings::KioskModeSettings() : is_initialized_(false) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In case we've force-enabled kiosk mode.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableKioskMode)) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_kiosk_mode_ = true;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Precache the value as we know it at construction time to avoid serving
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // different values to different users.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_browser_process) {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy::BrowserPolicyConnectorChromeOS* connector =
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        g_browser_process->platform_part()->browser_policy_connector_chromeos();
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy::DeviceMode device_mode = connector->GetDeviceMode();
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (device_mode == policy::DEVICE_MODE_RETAIL_KIOSK) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_kiosk_mode_ = true;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (device_mode == policy::DEVICE_MODE_PENDING){
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DeviceSettingsService::Get()->GetOwnershipStatusAsync(
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&KioskModeSettings::VerifyModeIsKnown,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this)));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_kiosk_mode_ = false;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KioskModeSettings::~KioskModeSettings() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KioskModeSettings::VerifyModeIsKnown(
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DeviceSettingsService::OwnershipStatus status) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != DeviceSettingsService::OWNERSHIP_TAKEN)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_browser_process) {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy::BrowserPolicyConnectorChromeOS* connector =
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        g_browser_process->platform_part()->browser_policy_connector_chromeos();
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy::DeviceMode device_mode = connector->GetDeviceMode();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We retry asking for the mode until it becomes known.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (device_mode) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case policy::DEVICE_MODE_PENDING:
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::BrowserThread::PostDelayedTask(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            content::BrowserThread::UI, FROM_HERE,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::Bind(&KioskModeSettings::VerifyModeIsKnown,
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       base::Unretained(this), status),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::TimeDelta::FromMilliseconds(kDeviceModeFetchRetryDelayMs));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      case policy::DEVICE_MODE_RETAIL_KIOSK:
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        chrome::AttemptRestart();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
207