kiosk_app_manager.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <set>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_service.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_process.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_data.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/chromeos/settings/owner_key_util.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/cryptohome/async_method_caller.h"
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Domain that is used for kiosk-app account IDs.
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kKioskAppAccountDomain[] = "kiosk-apps";
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string GenerateKioskAppAccountId(const std::string& app_id) {
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return app_id + '@' + kKioskAppAccountDomain;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OnRemoveAppCryptohomeComplete(const std::string& app,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   bool success,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   cryptohome::MountError return_code) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!success) {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Remove cryptohome for " << app
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << " failed, return code: " << return_code;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Check for presence of machine owner public key file.
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void CheckOwnerFilePresence(bool *present) {
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<OwnerKeyUtil> util = OwnerKeyUtil::Create();
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  *present = util->IsPublicKeyPresent();
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char KioskAppManager::kKioskDictionaryName[] = "kiosk";
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char KioskAppManager::kKeyApps[] = "apps";
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char KioskAppManager::kKeyAutoLoginState[] = "auto_login_state";
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char KioskAppManager::kIconCacheDir[] = "kiosk";
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::LazyInstance<KioskAppManager> instance = LAZY_INSTANCE_INITIALIZER;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager* KioskAppManager::Get() {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return instance.Pointer();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void KioskAppManager::Shutdown() {
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (instance == NULL)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  instance.Pointer()->CleanUp();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::RegisterPrefs(PrefRegistrySimple* registry) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterDictionaryPref(kKioskDictionaryName);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager::App::App(const KioskAppData& data)
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : app_id(data.app_id()),
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      user_id(data.user_id()),
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name(data.name()),
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      icon(data.icon()),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_loading(data.IsLoading()) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager::App::App() : is_loading(false) {}
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager::App::~App() {}
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string KioskAppManager::GetAutoLaunchApp() const {
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return auto_launch_app_id_;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) {
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SetAutoLoginState(AUTOLOGIN_REQUESTED);
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Clean first, so the proper change callbacks are triggered even
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // if we are only changing AutoLoginState here.
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!auto_launch_app_id_.empty()) {
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CrosSettings::Get()->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                   std::string());
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CrosSettings::Get()->SetString(
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kAccountsPrefDeviceLocalAccountAutoLoginId,
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      app_id.empty() ? std::string() : GenerateKioskAppAccountId(app_id));
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CrosSettings::Get()->SetInteger(
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kAccountsPrefDeviceLocalAccountAutoLoginDelay, 0);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppManager::EnableConsumerKioskAutoLaunch(
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const KioskAppManager::EnableKioskAutoLaunchCallback& callback) {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  connector->GetInstallAttributes()->LockDevice(
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string(),  // user
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string(),  // device_id
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          &KioskAppManager::OnLockDevice, base::Unretained(this), callback));
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppManager::GetConsumerKioskAutoLaunchStatus(
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback& callback) {
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  connector->GetInstallAttributes()->ReadImmutableAttributes(
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&KioskAppManager::OnReadImmutableAttributes,
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this),
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 callback));
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void KioskAppManager::OnLockDevice(
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const KioskAppManager::EnableKioskAutoLaunchCallback& callback,
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    policy::EnterpriseInstallAttributes::LockResult result) {
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (callback.is_null())
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  callback.Run(result == policy::EnterpriseInstallAttributes::LOCK_SUCCESS);
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void KioskAppManager::OnOwnerFileChecked(
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback& callback,
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool* owner_present) {
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ownership_established_ = *owner_present;
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (callback.is_null())
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If we have owner already established on the machine, don't let
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // consumer kiosk to be enabled.
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (ownership_established_)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED);
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE);
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void KioskAppManager::OnReadImmutableAttributes(
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback&
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        callback) {
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (callback.is_null())
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConsumerKioskAutoLaunchStatus status =
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  policy::EnterpriseInstallAttributes* attributes =
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      connector->GetInstallAttributes();
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  switch (attributes->GetMode()) {
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case policy::DEVICE_MODE_NOT_SET: {
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (!base::SysInfo::IsRunningOnChromeOS()) {
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        status = CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE;
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      } else if (!ownership_established_) {
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        bool* owner_present = new bool(false);
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        content::BrowserThread::PostBlockingPoolTaskAndReply(
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            FROM_HERE,
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            base::Bind(&CheckOwnerFilePresence,
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       owner_present),
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            base::Bind(&KioskAppManager::OnOwnerFileChecked,
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::Unretained(this),
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       callback,
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::Owned(owner_present)));
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return;
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH:
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      status = CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED;
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    default:
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  callback.Run(status);
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void KioskAppManager::SetEnableAutoLaunch(bool value) {
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SetAutoLoginState(value ? AUTOLOGIN_APPROVED : AUTOLOGIN_REJECTED);
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool KioskAppManager::IsAutoLaunchRequested() const {
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (GetAutoLaunchApp().empty())
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Apps that were installed by the policy don't require machine owner
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // consent through UI.
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (connector->IsEnterpriseManaged())
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetAutoLoginState() == AUTOLOGIN_REQUESTED;
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool KioskAppManager::IsAutoLaunchEnabled() const {
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (GetAutoLaunchApp().empty())
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Apps that were installed by the policy don't require machine owner
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // consent through UI.
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (connector->IsEnterpriseManaged())
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return true;
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetAutoLoginState() == AUTOLOGIN_APPROVED;
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::AddApp(const std::string& app_id) {
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<policy::DeviceLocalAccount> device_local_accounts =
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      policy::GetDeviceLocalAccounts(CrosSettings::Get());
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Don't insert the app if it's already in the list.
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (std::vector<policy::DeviceLocalAccount>::const_iterator
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           it = device_local_accounts.begin();
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != device_local_accounts.end(); ++it) {
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP &&
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        it->kiosk_app_id == app_id) {
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Add the new account.
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  device_local_accounts.push_back(policy::DeviceLocalAccount(
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      policy::DeviceLocalAccount::TYPE_KIOSK_APP,
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GenerateKioskAppAccountId(app_id),
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      app_id));
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::RemoveApp(const std::string& app_id) {
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Resets auto launch app if it is the removed app.
259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (auto_launch_app_id_ == app_id)
260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SetAutoLaunchApp(std::string());
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<policy::DeviceLocalAccount> device_local_accounts =
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      policy::GetDeviceLocalAccounts(CrosSettings::Get());
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (device_local_accounts.empty())
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Remove entries that match |app_id|.
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (std::vector<policy::DeviceLocalAccount>::iterator
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           it = device_local_accounts.begin();
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != device_local_accounts.end(); ++it) {
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP &&
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        it->kiosk_app_id == app_id) {
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      device_local_accounts.erase(it);
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::GetApps(Apps* apps) const {
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  apps->clear();
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  apps->reserve(apps_.size());
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < apps_.size(); ++i)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    apps->push_back(App(*apps_[i]));
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool KioskAppManager::GetApp(const std::string& app_id, App* app) const {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const KioskAppData* data = GetAppData(app_id);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!data)
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *app = App(*data);
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::RefCountedString* KioskAppManager::GetAppRawIcon(
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& app_id) const {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const KioskAppData* data = GetAppData(app_id);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!data)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return data->raw_icon();
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool KioskAppManager::GetDisableBailoutShortcut() const {
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool enable;
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (CrosSettings::Get()->GetBoolean(
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, &enable)) {
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return !enable;
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppManager::ClearAppData(const std::string& app_id) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  KioskAppData* app_data = GetAppDataMutable(app_id);
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!app_data)
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  app_data->ClearCache();
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppManager::UpdateAppDataFromProfile(
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& app_id,
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* profile,
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const extensions::Extension* app) {
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  KioskAppData* app_data = GetAppDataMutable(app_id);
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!app_data)
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  app_data->LoadFromInstalledApp(profile, app);
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) {
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)KioskAppManager::KioskAppManager() : ownership_established_(false) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAppData();
34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  local_accounts_subscription_ =
34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      CrosSettings::Get()->AddSettingsObserver(
34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          kAccountsPrefDeviceLocalAccounts,
34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          base::Bind(&KioskAppManager::UpdateAppData, base::Unretained(this)));
34968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  local_account_auto_login_id_subscription_ =
35068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      CrosSettings::Get()->AddSettingsObserver(
35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          kAccountsPrefDeviceLocalAccountAutoLoginId,
35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          base::Bind(&KioskAppManager::UpdateAppData, base::Unretained(this)));
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)KioskAppManager::~KioskAppManager() {}
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void KioskAppManager::CleanUp() {
35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  local_accounts_subscription_.reset();
35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  local_account_auto_login_id_subscription_.reset();
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  apps_.clear();
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const KioskAppData* KioskAppManager::GetAppData(
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& app_id) const {
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < apps_.size(); ++i) {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const KioskAppData* data = apps_[i];
36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (data->app_id() == app_id)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return data;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)KioskAppData* KioskAppManager::GetAppDataMutable(const std::string& app_id) {
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return const_cast<KioskAppData*>(GetAppData(app_id));
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::UpdateAppData() {
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Gets app id to data mapping for existing apps.
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, KioskAppData*> old_apps;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < apps_.size(); ++i)
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    old_apps[apps_[i]->app_id()] = apps_[i];
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  apps_.weak_clear();  // |old_apps| takes ownership
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  auto_launch_app_id_.clear();
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string auto_login_account_id;
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 &auto_login_account_id);
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Re-populates |apps_| and reuses existing KioskAppData when possible.
39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::vector<policy::DeviceLocalAccount> device_local_accounts =
39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      policy::GetDeviceLocalAccounts(CrosSettings::Get());
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (std::vector<policy::DeviceLocalAccount>::const_iterator
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           it = device_local_accounts.begin();
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != device_local_accounts.end(); ++it) {
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP)
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      continue;
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (it->account_id == auto_login_account_id)
40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      auto_launch_app_id_ = it->kiosk_app_id;
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // TODO(mnissler): Support non-CWS update URLs.
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::map<std::string, KioskAppData*>::iterator old_it =
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        old_apps.find(it->kiosk_app_id);
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (old_it != old_apps.end()) {
40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      apps_.push_back(old_it->second);
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      old_apps.erase(old_it);
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      KioskAppData* new_app =
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          new KioskAppData(this, it->kiosk_app_id, it->user_id);
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      apps_.push_back(new_app);  // Takes ownership of |new_app|.
41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new_app->Load();
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clears cache and deletes the remaining old data.
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin();
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != old_apps.end(); ++it) {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    it->second->ClearCache();
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        it->second->user_id(),
423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::Bind(&OnRemoveAppCryptohomeComplete, it->first));
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  STLDeleteValues(&old_apps);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FOR_EACH_OBSERVER(KioskAppManagerObserver, observers_,
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    OnKioskAppsSettingsChanged());
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath user_data_dir;
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *cache_dir = user_data_dir.AppendASCII(kIconCacheDir);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) {
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(KioskAppManagerObserver,
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observers_,
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnKioskAppDataChanged(app_id));
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) {
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(KioskAppManagerObserver,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observers_,
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnKioskAppDataLoadFailure(app_id));
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RemoveApp(app_id);
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KioskAppManager::AutoLoginState KioskAppManager::GetAutoLoginState() const {
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const base::DictionaryValue* dict =
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      prefs->GetDictionary(KioskAppManager::kKioskDictionaryName);
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int value;
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!dict->GetInteger(kKeyAutoLoginState, &value))
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return AUTOLOGIN_NONE;
457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return static_cast<AutoLoginState>(value);
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void KioskAppManager::SetAutoLoginState(AutoLoginState state) {
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DictionaryPrefUpdate dict_update(prefs,
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                   KioskAppManager::kKioskDictionaryName);
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  dict_update->SetInteger(kKeyAutoLoginState, state);
466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  prefs->CommitPendingWrite();
467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
470