kiosk_app_manager.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_process.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_data.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings_names.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_notification_types.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/cryptohome/async_method_caller.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Domain that is used for kiosk-app account IDs. 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kKioskAppAccountDomain[] = "kiosk-apps"; 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string GenerateKioskAppAccountId(const std::string& app_id) { 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return app_id + '@' + kKioskAppAccountDomain; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OnRemoveAppCryptohomeComplete(const std::string& app, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cryptohome::MountError return_code) { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!success) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Remove cryptohome for " << app 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " failed, return code: " << return_code; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char KioskAppManager::kKioskDictionaryName[] = "kiosk"; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char KioskAppManager::kKeyApps[] = "apps"; 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char KioskAppManager::kKeyAutoLoginState[] = "auto_login_state"; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char KioskAppManager::kIconCacheDir[] = "kiosk"; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::LazyInstance<KioskAppManager> instance = LAZY_INSTANCE_INITIALIZER; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager* KioskAppManager::Get() { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return instance.Pointer(); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void KioskAppManager::Shutdown() { 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (instance == NULL) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) instance.Pointer()->CleanUp(); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::RegisterPrefs(PrefRegistrySimple* registry) { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterDictionaryPref(kKioskDictionaryName); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager::App::App(const KioskAppData& data) 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : app_id(data.app_id()), 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_id(data.user_id()), 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name(data.name()), 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon(data.icon()), 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_loading(data.IsLoading()) { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager::App::App() : is_loading(false) {} 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppManager::App::~App() {} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string KioskAppManager::GetAutoLaunchApp() const { 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return auto_launch_app_id_; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) { 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetAutoLoginState(AUTOLOGIN_REQUESTED); 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Clean first, so the proper change notifications are triggered even 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // if we are only changing AutoLoginState here. 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!auto_launch_app_id_.empty()) { 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CrosSettings::Get()->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId, 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string()); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrosSettings::Get()->SetString( 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kAccountsPrefDeviceLocalAccountAutoLoginId, 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) app_id.empty() ? std::string() : GenerateKioskAppAccountId(app_id)); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrosSettings::Get()->SetInteger( 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kAccountsPrefDeviceLocalAccountAutoLoginDelay, 0); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void KioskAppManager::SetEnableAutoLaunch(bool value) { 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetAutoLoginState(value ? AUTOLOGIN_APPROVED : AUTOLOGIN_REJECTED); 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool KioskAppManager::IsAutoLaunchRequested() const { 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (GetAutoLaunchApp().empty()) 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Apps that were installed by the policy don't require machine owner 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // consent through UI. 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GetAutoLoginState() == AUTOLOGIN_REQUESTED; 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool KioskAppManager::IsAutoLaunchEnabled() const { 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (GetAutoLaunchApp().empty()) 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Apps that were installed by the policy don't require machine owner 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // consent through UI. 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GetAutoLoginState() == AUTOLOGIN_APPROVED; 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::AddApp(const std::string& app_id) { 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<policy::DeviceLocalAccount> device_local_accounts = 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) policy::GetDeviceLocalAccounts(CrosSettings::Get()); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Don't insert the app if it's already in the list. 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::vector<policy::DeviceLocalAccount>::const_iterator 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it = device_local_accounts.begin(); 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != device_local_accounts.end(); ++it) { 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP && 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it->kiosk_app_id == app_id) { 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add the new account. 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) device_local_accounts.push_back(policy::DeviceLocalAccount( 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) policy::DeviceLocalAccount::TYPE_KIOSK_APP, 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GenerateKioskAppAccountId(app_id), 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) app_id, 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string())); 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::RemoveApp(const std::string& app_id) { 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<policy::DeviceLocalAccount> device_local_accounts = 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) policy::GetDeviceLocalAccounts(CrosSettings::Get()); 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (device_local_accounts.empty()) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Remove entries that match |app_id|. 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::vector<policy::DeviceLocalAccount>::iterator 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it = device_local_accounts.begin(); 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != device_local_accounts.end(); ++it) { 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP && 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it->kiosk_app_id == app_id) { 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) device_local_accounts.erase(it); 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::GetApps(Apps* apps) const { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps->reserve(apps_.size()); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < apps_.size(); ++i) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps->push_back(App(*apps_[i])); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool KioskAppManager::GetApp(const std::string& app_id, App* app) const { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const KioskAppData* data = GetAppData(app_id); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!data) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *app = App(*data); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::RefCountedString* KioskAppManager::GetAppRawIcon( 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& app_id) const { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const KioskAppData* data = GetAppData(app_id); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!data) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return data->raw_icon(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool KioskAppManager::GetDisableBailoutShortcut() const { 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool enable; 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (CrosSettings::Get()->GetBoolean( 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, &enable)) { 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !enable; 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.AddObserver(observer); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.RemoveObserver(observer); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)KioskAppManager::KioskAppManager() { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAppData(); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrosSettings::Get()->AddSettingsObserver( 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kAccountsPrefDeviceLocalAccounts, this); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrosSettings::Get()->AddSettingsObserver( 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kAccountsPrefDeviceLocalAccountAutoLoginId, this); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)KioskAppManager::~KioskAppManager() {} 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void KioskAppManager::CleanUp() { 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrosSettings::Get()->RemoveSettingsObserver( 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kAccountsPrefDeviceLocalAccounts, this); 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrosSettings::Get()->RemoveSettingsObserver( 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kAccountsPrefDeviceLocalAccountAutoLoginId, this); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) apps_.clear(); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const KioskAppData* KioskAppManager::GetAppData( 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& app_id) const { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < apps_.size(); ++i) { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const KioskAppData* data = apps_[i]; 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (data->app_id() == app_id) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return data; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::UpdateAppData() { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Gets app id to data mapping for existing apps. 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, KioskAppData*> old_apps; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < apps_.size(); ++i) 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) old_apps[apps_[i]->app_id()] = apps_[i]; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_.weak_clear(); // |old_apps| takes ownership 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auto_launch_app_id_.clear(); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string auto_login_account_id; 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId, 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &auto_login_account_id); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Re-populates |apps_| and reuses existing KioskAppData when possible. 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<policy::DeviceLocalAccount> device_local_accounts = 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) policy::GetDeviceLocalAccounts(CrosSettings::Get()); 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::vector<policy::DeviceLocalAccount>::const_iterator 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it = device_local_accounts.begin(); 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != device_local_accounts.end(); ++it) { 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it->account_id == auto_login_account_id) 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) auto_launch_app_id_ = it->kiosk_app_id; 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(mnissler): Support non-CWS update URLs. 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::map<std::string, KioskAppData*>::iterator old_it = 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) old_apps.find(it->kiosk_app_id); 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (old_it != old_apps.end()) { 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) apps_.push_back(old_it->second); 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) old_apps.erase(old_it); 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) KioskAppData* new_app = 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new KioskAppData(this, it->kiosk_app_id, it->user_id); 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) apps_.push_back(new_app); // Takes ownership of |new_app|. 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_app->Load(); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clears cache and deletes the remaining old data. 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != old_apps.end(); ++it) { 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->second->ClearCache(); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->first, base::Bind(&OnRemoveAppCryptohomeComplete, it->first)); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteValues(&old_apps); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(KioskAppManagerObserver, observers_, 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnKioskAppsSettingsChanged()); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void KioskAppManager::Observe(int type, 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const content::NotificationSource& source, 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const content::NotificationDetails& details) { 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, type); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAppData(); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath user_data_dir; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *cache_dir = user_data_dir.AppendASCII(kIconCacheDir); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) { 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(KioskAppManagerObserver, 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_, 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnKioskAppDataChanged(app_id)); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) { 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(KioskAppManagerObserver, 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_, 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnKioskAppDataLoadFailure(app_id)); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveApp(app_id); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KioskAppManager::AutoLoginState KioskAppManager::GetAutoLoginState() const { 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PrefService* prefs = g_browser_process->local_state(); 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::DictionaryValue* dict = 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) prefs->GetDictionary(KioskAppManager::kKioskDictionaryName); 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int value; 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!dict->GetInteger(kKeyAutoLoginState, &value)) 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return AUTOLOGIN_NONE; 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return static_cast<AutoLoginState>(value); 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void KioskAppManager::SetAutoLoginState(AutoLoginState state) { 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PrefService* prefs = g_browser_process->local_state(); 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DictionaryPrefUpdate dict_update(prefs, 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) KioskAppManager::kKioskDictionaryName); 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dict_update->SetInteger(kKeyAutoLoginState, state); 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) prefs->CommitPendingWrite(); 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 348