Home | History | Annotate | Download | only in app_mode
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
      6 
      7 #include <map>
      8 #include <set>
      9 
     10 #include "base/bind.h"
     11 #include "base/files/file_path.h"
     12 #include "base/files/file_util.h"
     13 #include "base/logging.h"
     14 #include "base/path_service.h"
     15 #include "base/prefs/pref_registry_simple.h"
     16 #include "base/prefs/pref_service.h"
     17 #include "base/prefs/scoped_user_pref_update.h"
     18 #include "base/stl_util.h"
     19 #include "base/sys_info.h"
     20 #include "chrome/browser/browser_process.h"
     21 #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h"
     22 #include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h"
     23 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
     24 #include "chrome/browser/chromeos/app_mode/kiosk_external_updater.h"
     25 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
     26 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
     27 #include "chrome/browser/chromeos/policy/device_local_account.h"
     28 #include "chrome/browser/chromeos/settings/cros_settings.h"
     29 #include "chrome/browser/extensions/external_loader.h"
     30 #include "chrome/browser/extensions/external_provider_impl.h"
     31 #include "chrome/common/chrome_paths.h"
     32 #include "chrome/common/extensions/extension_constants.h"
     33 #include "chromeos/chromeos_paths.h"
     34 #include "chromeos/cryptohome/async_method_caller.h"
     35 #include "chromeos/settings/cros_settings_names.h"
     36 #include "components/ownership/owner_key_util.h"
     37 #include "content/public/browser/browser_thread.h"
     38 
     39 namespace chromeos {
     40 
     41 namespace {
     42 
     43 // Domain that is used for kiosk-app account IDs.
     44 const char kKioskAppAccountDomain[] = "kiosk-apps";
     45 
     46 std::string GenerateKioskAppAccountId(const std::string& app_id) {
     47   return app_id + '@' + kKioskAppAccountDomain;
     48 }
     49 
     50 void OnRemoveAppCryptohomeComplete(const std::string& app,
     51                                    bool success,
     52                                    cryptohome::MountError return_code) {
     53   if (!success) {
     54     LOG(ERROR) << "Remove cryptohome for " << app
     55         << " failed, return code: " << return_code;
     56   }
     57 }
     58 
     59 // Check for presence of machine owner public key file.
     60 void CheckOwnerFilePresence(bool *present) {
     61   scoped_refptr<ownership::OwnerKeyUtil> util =
     62       OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil();
     63   *present = util.get() && util->IsPublicKeyPresent();
     64 }
     65 
     66 scoped_refptr<base::SequencedTaskRunner> GetBackgroundTaskRunner() {
     67   base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
     68   CHECK(pool);
     69   return pool->GetSequencedTaskRunnerWithShutdownBehavior(
     70       pool->GetSequenceToken(), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
     71 }
     72 
     73 }  // namespace
     74 
     75 // static
     76 const char KioskAppManager::kKioskDictionaryName[] = "kiosk";
     77 const char KioskAppManager::kKeyApps[] = "apps";
     78 const char KioskAppManager::kKeyAutoLoginState[] = "auto_login_state";
     79 const char KioskAppManager::kIconCacheDir[] = "kiosk/icon";
     80 const char KioskAppManager::kCrxCacheDir[] = "kiosk/crx";
     81 const char KioskAppManager::kCrxUnpackDir[] = "kiosk_unpack";
     82 
     83 // static
     84 static base::LazyInstance<KioskAppManager> instance = LAZY_INSTANCE_INITIALIZER;
     85 KioskAppManager* KioskAppManager::Get() {
     86   return instance.Pointer();
     87 }
     88 
     89 // static
     90 void KioskAppManager::Shutdown() {
     91   if (instance == NULL)
     92     return;
     93 
     94   instance.Pointer()->CleanUp();
     95 }
     96 
     97 // static
     98 void KioskAppManager::RegisterPrefs(PrefRegistrySimple* registry) {
     99   registry->RegisterDictionaryPref(kKioskDictionaryName);
    100 }
    101 
    102 KioskAppManager::App::App(const KioskAppData& data, bool is_extension_pending)
    103     : app_id(data.app_id()),
    104       user_id(data.user_id()),
    105       name(data.name()),
    106       icon(data.icon()),
    107       is_loading(data.IsLoading() || is_extension_pending) {
    108 }
    109 
    110 KioskAppManager::App::App() : is_loading(false) {}
    111 KioskAppManager::App::~App() {}
    112 
    113 std::string KioskAppManager::GetAutoLaunchApp() const {
    114   return auto_launch_app_id_;
    115 }
    116 
    117 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) {
    118   SetAutoLoginState(AUTOLOGIN_REQUESTED);
    119   // Clean first, so the proper change callbacks are triggered even
    120   // if we are only changing AutoLoginState here.
    121   if (!auto_launch_app_id_.empty()) {
    122     CrosSettings::Get()->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
    123                                    std::string());
    124   }
    125 
    126   CrosSettings::Get()->SetString(
    127       kAccountsPrefDeviceLocalAccountAutoLoginId,
    128       app_id.empty() ? std::string() : GenerateKioskAppAccountId(app_id));
    129   CrosSettings::Get()->SetInteger(
    130       kAccountsPrefDeviceLocalAccountAutoLoginDelay, 0);
    131 }
    132 
    133 void KioskAppManager::EnableConsumerKioskAutoLaunch(
    134     const KioskAppManager::EnableKioskAutoLaunchCallback& callback) {
    135   policy::BrowserPolicyConnectorChromeOS* connector =
    136       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    137   connector->GetInstallAttributes()->LockDevice(
    138       std::string(),  // user
    139       policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
    140       std::string(),  // device_id
    141       base::Bind(
    142           &KioskAppManager::OnLockDevice, base::Unretained(this), callback));
    143 }
    144 
    145 void KioskAppManager::GetConsumerKioskAutoLaunchStatus(
    146     const KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback& callback) {
    147   policy::BrowserPolicyConnectorChromeOS* connector =
    148       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    149   connector->GetInstallAttributes()->ReadImmutableAttributes(
    150       base::Bind(&KioskAppManager::OnReadImmutableAttributes,
    151                  base::Unretained(this),
    152                  callback));
    153 }
    154 
    155 bool KioskAppManager::IsConsumerKioskDeviceWithAutoLaunch() {
    156   policy::BrowserPolicyConnectorChromeOS* connector =
    157       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    158   return connector->GetInstallAttributes() &&
    159          connector->GetInstallAttributes()
    160              ->IsConsumerKioskDeviceWithAutoLaunch();
    161 }
    162 
    163 void KioskAppManager::OnLockDevice(
    164     const KioskAppManager::EnableKioskAutoLaunchCallback& callback,
    165     policy::EnterpriseInstallAttributes::LockResult result) {
    166   if (callback.is_null())
    167     return;
    168 
    169   callback.Run(result == policy::EnterpriseInstallAttributes::LOCK_SUCCESS);
    170 }
    171 
    172 void KioskAppManager::OnOwnerFileChecked(
    173     const KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback& callback,
    174     bool* owner_present) {
    175   ownership_established_ = *owner_present;
    176 
    177   if (callback.is_null())
    178     return;
    179 
    180   // If we have owner already established on the machine, don't let
    181   // consumer kiosk to be enabled.
    182   if (ownership_established_)
    183     callback.Run(CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED);
    184   else
    185     callback.Run(CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE);
    186 }
    187 
    188 void KioskAppManager::OnReadImmutableAttributes(
    189     const KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback&
    190         callback) {
    191   if (callback.is_null())
    192     return;
    193 
    194   ConsumerKioskAutoLaunchStatus status =
    195       CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED;
    196   policy::BrowserPolicyConnectorChromeOS* connector =
    197       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    198   policy::EnterpriseInstallAttributes* attributes =
    199       connector->GetInstallAttributes();
    200   switch (attributes->GetMode()) {
    201     case policy::DEVICE_MODE_NOT_SET: {
    202       if (!base::SysInfo::IsRunningOnChromeOS()) {
    203         status = CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE;
    204       } else if (!ownership_established_) {
    205         bool* owner_present = new bool(false);
    206         content::BrowserThread::PostBlockingPoolTaskAndReply(
    207             FROM_HERE,
    208             base::Bind(&CheckOwnerFilePresence,
    209                        owner_present),
    210             base::Bind(&KioskAppManager::OnOwnerFileChecked,
    211                        base::Unretained(this),
    212                        callback,
    213                        base::Owned(owner_present)));
    214         return;
    215       }
    216       break;
    217     }
    218     case policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH:
    219       status = CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED;
    220       break;
    221     default:
    222       break;
    223   }
    224 
    225   callback.Run(status);
    226 }
    227 
    228 void KioskAppManager::SetEnableAutoLaunch(bool value) {
    229   SetAutoLoginState(value ? AUTOLOGIN_APPROVED : AUTOLOGIN_REJECTED);
    230 }
    231 
    232 bool KioskAppManager::IsAutoLaunchRequested() const {
    233   if (GetAutoLaunchApp().empty())
    234     return false;
    235 
    236   // Apps that were installed by the policy don't require machine owner
    237   // consent through UI.
    238   policy::BrowserPolicyConnectorChromeOS* connector =
    239       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    240   if (connector->IsEnterpriseManaged())
    241     return false;
    242 
    243   return GetAutoLoginState() == AUTOLOGIN_REQUESTED;
    244 }
    245 
    246 bool KioskAppManager::IsAutoLaunchEnabled() const {
    247   if (GetAutoLaunchApp().empty())
    248     return false;
    249 
    250   // Apps that were installed by the policy don't require machine owner
    251   // consent through UI.
    252   policy::BrowserPolicyConnectorChromeOS* connector =
    253       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    254   if (connector->IsEnterpriseManaged())
    255     return true;
    256 
    257   return GetAutoLoginState() == AUTOLOGIN_APPROVED;
    258 }
    259 
    260 void KioskAppManager::AddApp(const std::string& app_id) {
    261   std::vector<policy::DeviceLocalAccount> device_local_accounts =
    262       policy::GetDeviceLocalAccounts(CrosSettings::Get());
    263 
    264   // Don't insert the app if it's already in the list.
    265   for (std::vector<policy::DeviceLocalAccount>::const_iterator
    266            it = device_local_accounts.begin();
    267        it != device_local_accounts.end(); ++it) {
    268     if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP &&
    269         it->kiosk_app_id == app_id) {
    270       return;
    271     }
    272   }
    273 
    274   // Add the new account.
    275   device_local_accounts.push_back(policy::DeviceLocalAccount(
    276       policy::DeviceLocalAccount::TYPE_KIOSK_APP,
    277       GenerateKioskAppAccountId(app_id),
    278       app_id));
    279 
    280   policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts);
    281 }
    282 
    283 void KioskAppManager::RemoveApp(const std::string& app_id) {
    284   // Resets auto launch app if it is the removed app.
    285   if (auto_launch_app_id_ == app_id)
    286     SetAutoLaunchApp(std::string());
    287 
    288   std::vector<policy::DeviceLocalAccount> device_local_accounts =
    289       policy::GetDeviceLocalAccounts(CrosSettings::Get());
    290   if (device_local_accounts.empty())
    291     return;
    292 
    293   // Remove entries that match |app_id|.
    294   for (std::vector<policy::DeviceLocalAccount>::iterator
    295            it = device_local_accounts.begin();
    296        it != device_local_accounts.end(); ++it) {
    297     if (it->type == policy::DeviceLocalAccount::TYPE_KIOSK_APP &&
    298         it->kiosk_app_id == app_id) {
    299       device_local_accounts.erase(it);
    300       break;
    301     }
    302   }
    303 
    304   policy::SetDeviceLocalAccounts(CrosSettings::Get(), device_local_accounts);
    305 }
    306 
    307 void KioskAppManager::GetApps(Apps* apps) const {
    308   apps->clear();
    309   apps->reserve(apps_.size());
    310   for (size_t i = 0; i < apps_.size(); ++i) {
    311     const KioskAppData& app_data = *apps_[i];
    312     if (app_data.status() != KioskAppData::STATUS_ERROR)
    313       apps->push_back(App(
    314           app_data, external_cache_->IsExtensionPending(app_data.app_id())));
    315   }
    316 }
    317 
    318 bool KioskAppManager::GetApp(const std::string& app_id, App* app) const {
    319   const KioskAppData* data = GetAppData(app_id);
    320   if (!data)
    321     return false;
    322 
    323   *app = App(*data, external_cache_->IsExtensionPending(app_id));
    324   return true;
    325 }
    326 
    327 const base::RefCountedString* KioskAppManager::GetAppRawIcon(
    328     const std::string& app_id) const {
    329   const KioskAppData* data = GetAppData(app_id);
    330   if (!data)
    331     return NULL;
    332 
    333   return data->raw_icon();
    334 }
    335 
    336 bool KioskAppManager::GetDisableBailoutShortcut() const {
    337   bool enable;
    338   if (CrosSettings::Get()->GetBoolean(
    339           kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, &enable)) {
    340     return !enable;
    341   }
    342 
    343   return false;
    344 }
    345 
    346 void KioskAppManager::ClearAppData(const std::string& app_id) {
    347   KioskAppData* app_data = GetAppDataMutable(app_id);
    348   if (!app_data)
    349     return;
    350 
    351   app_data->ClearCache();
    352 }
    353 
    354 void KioskAppManager::UpdateAppDataFromProfile(
    355     const std::string& app_id,
    356     Profile* profile,
    357     const extensions::Extension* app) {
    358   KioskAppData* app_data = GetAppDataMutable(app_id);
    359   if (!app_data)
    360     return;
    361 
    362   app_data->LoadFromInstalledApp(profile, app);
    363 }
    364 
    365 void KioskAppManager::RetryFailedAppDataFetch() {
    366   for (size_t i = 0; i < apps_.size(); ++i) {
    367     if (apps_[i]->status() == KioskAppData::STATUS_ERROR)
    368       apps_[i]->Load();
    369   }
    370 }
    371 
    372 bool KioskAppManager::HasCachedCrx(const std::string& app_id) const {
    373   base::FilePath crx_path;
    374   std::string version;
    375   return GetCachedCrx(app_id, &crx_path, &version);
    376 }
    377 
    378 bool KioskAppManager::GetCachedCrx(const std::string& app_id,
    379                                    base::FilePath* file_path,
    380                                    std::string* version) const {
    381   return external_cache_->GetExtension(app_id, file_path, version);
    382 }
    383 
    384 void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) {
    385   observers_.AddObserver(observer);
    386 }
    387 
    388 void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) {
    389   observers_.RemoveObserver(observer);
    390 }
    391 
    392 extensions::ExternalLoader* KioskAppManager::CreateExternalLoader() {
    393   if (external_loader_created_) {
    394     NOTREACHED();
    395     return NULL;
    396   }
    397   external_loader_created_ = true;
    398   KioskAppExternalLoader* loader = new KioskAppExternalLoader();
    399   external_loader_ = loader->AsWeakPtr();
    400 
    401   return loader;
    402 }
    403 
    404 void KioskAppManager::InstallFromCache(const std::string& id) {
    405   const base::DictionaryValue* extension = NULL;
    406   if (external_cache_->cached_extensions()->GetDictionary(id, &extension)) {
    407     scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
    408     base::DictionaryValue* extension_copy = extension->DeepCopy();
    409     prefs->Set(id, extension_copy);
    410     external_loader_->SetCurrentAppExtensions(prefs.Pass());
    411   } else {
    412     LOG(ERROR) << "Can't find app in the cached externsions"
    413                << " id = " << id;
    414   }
    415 }
    416 
    417 void KioskAppManager::UpdateExternalCache() {
    418   UpdateAppData();
    419 }
    420 
    421 void KioskAppManager::OnKioskAppCacheUpdated(const std::string& app_id) {
    422   FOR_EACH_OBSERVER(
    423       KioskAppManagerObserver, observers_, OnKioskAppCacheUpdated(app_id));
    424 }
    425 
    426 void KioskAppManager::OnKioskAppExternalUpdateComplete(bool success) {
    427   FOR_EACH_OBSERVER(KioskAppManagerObserver,
    428                     observers_,
    429                     OnKioskAppExternalUpdateComplete(success));
    430 }
    431 
    432 void KioskAppManager::PutValidatedExternalExtension(
    433     const std::string& app_id,
    434     const base::FilePath& crx_path,
    435     const std::string& version,
    436     const ExternalCache::PutExternalExtensionCallback& callback) {
    437   external_cache_->PutExternalExtension(app_id, crx_path, version, callback);
    438 }
    439 
    440 KioskAppManager::KioskAppManager()
    441     : ownership_established_(false), external_loader_created_(false) {
    442   base::FilePath cache_dir;
    443   GetCrxCacheDir(&cache_dir);
    444   external_cache_.reset(
    445       new ExternalCache(cache_dir,
    446                         g_browser_process->system_request_context(),
    447                         GetBackgroundTaskRunner(),
    448                         this,
    449                         true /* always_check_updates */,
    450                         false /* wait_for_cache_initialization */));
    451   UpdateAppData();
    452   local_accounts_subscription_ =
    453       CrosSettings::Get()->AddSettingsObserver(
    454           kAccountsPrefDeviceLocalAccounts,
    455           base::Bind(&KioskAppManager::UpdateAppData, base::Unretained(this)));
    456   local_account_auto_login_id_subscription_ =
    457       CrosSettings::Get()->AddSettingsObserver(
    458           kAccountsPrefDeviceLocalAccountAutoLoginId,
    459           base::Bind(&KioskAppManager::UpdateAppData, base::Unretained(this)));
    460 }
    461 
    462 KioskAppManager::~KioskAppManager() {}
    463 
    464 void KioskAppManager::MonitorKioskExternalUpdate() {
    465   base::FilePath cache_dir;
    466   GetCrxCacheDir(&cache_dir);
    467   base::FilePath unpack_dir;
    468   GetCrxUnpackDir(&unpack_dir);
    469   usb_stick_updater_.reset(new KioskExternalUpdater(
    470       GetBackgroundTaskRunner(), cache_dir, unpack_dir));
    471 }
    472 
    473 void KioskAppManager::CleanUp() {
    474   local_accounts_subscription_.reset();
    475   local_account_auto_login_id_subscription_.reset();
    476   apps_.clear();
    477   usb_stick_updater_.reset();
    478   external_cache_.reset();
    479 }
    480 
    481 const KioskAppData* KioskAppManager::GetAppData(
    482     const std::string& app_id) const {
    483   for (size_t i = 0; i < apps_.size(); ++i) {
    484     const KioskAppData* data = apps_[i];
    485     if (data->app_id() == app_id)
    486       return data;
    487   }
    488 
    489   return NULL;
    490 }
    491 
    492 KioskAppData* KioskAppManager::GetAppDataMutable(const std::string& app_id) {
    493   return const_cast<KioskAppData*>(GetAppData(app_id));
    494 }
    495 
    496 void KioskAppManager::UpdateAppData() {
    497   // Gets app id to data mapping for existing apps.
    498   std::map<std::string, KioskAppData*> old_apps;
    499   for (size_t i = 0; i < apps_.size(); ++i)
    500     old_apps[apps_[i]->app_id()] = apps_[i];
    501   apps_.weak_clear();  // |old_apps| takes ownership
    502 
    503   auto_launch_app_id_.clear();
    504   std::string auto_login_account_id;
    505   CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
    506                                  &auto_login_account_id);
    507 
    508   // Re-populates |apps_| and reuses existing KioskAppData when possible.
    509   const std::vector<policy::DeviceLocalAccount> device_local_accounts =
    510       policy::GetDeviceLocalAccounts(CrosSettings::Get());
    511   for (std::vector<policy::DeviceLocalAccount>::const_iterator
    512            it = device_local_accounts.begin();
    513        it != device_local_accounts.end(); ++it) {
    514     if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP)
    515       continue;
    516 
    517     if (it->account_id == auto_login_account_id)
    518       auto_launch_app_id_ = it->kiosk_app_id;
    519 
    520     // TODO(mnissler): Support non-CWS update URLs.
    521 
    522     std::map<std::string, KioskAppData*>::iterator old_it =
    523         old_apps.find(it->kiosk_app_id);
    524     if (old_it != old_apps.end()) {
    525       apps_.push_back(old_it->second);
    526       old_apps.erase(old_it);
    527     } else {
    528       KioskAppData* new_app =
    529           new KioskAppData(this, it->kiosk_app_id, it->user_id);
    530       apps_.push_back(new_app);  // Takes ownership of |new_app|.
    531       new_app->Load();
    532     }
    533   }
    534 
    535   // Clears cache and deletes the remaining old data.
    536   std::vector<std::string> apps_to_remove;
    537   for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin();
    538        it != old_apps.end(); ++it) {
    539     it->second->ClearCache();
    540     cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
    541         it->second->user_id(),
    542         base::Bind(&OnRemoveAppCryptohomeComplete, it->first));
    543     apps_to_remove.push_back(it->second->app_id());
    544   }
    545   STLDeleteValues(&old_apps);
    546   external_cache_->RemoveExtensions(apps_to_remove);
    547 
    548   // Request external_cache_ to download new apps and update the existing
    549   // apps.
    550   scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
    551   for (size_t i = 0; i < apps_.size(); ++i) {
    552     scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
    553     entry->SetBoolean(extensions::ExternalProviderImpl::kIsFromWebstore, true);
    554     prefs->Set(apps_[i]->app_id(), entry.release());
    555   }
    556   external_cache_->UpdateExtensionsList(prefs.Pass());
    557 
    558   RetryFailedAppDataFetch();
    559 
    560   FOR_EACH_OBSERVER(KioskAppManagerObserver, observers_,
    561                     OnKioskAppsSettingsChanged());
    562 }
    563 
    564 void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) {
    565   base::FilePath user_data_dir;
    566   CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
    567   *cache_dir = user_data_dir.AppendASCII(kIconCacheDir);
    568 }
    569 
    570 void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) {
    571   FOR_EACH_OBSERVER(KioskAppManagerObserver,
    572                     observers_,
    573                     OnKioskAppDataChanged(app_id));
    574 }
    575 
    576 void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) {
    577   FOR_EACH_OBSERVER(KioskAppManagerObserver,
    578                     observers_,
    579                     OnKioskAppDataLoadFailure(app_id));
    580 }
    581 
    582 void KioskAppManager::OnExtensionListsUpdated(
    583     const base::DictionaryValue* prefs) {
    584 }
    585 
    586 void KioskAppManager::OnExtensionLoadedInCache(const std::string& id) {
    587   KioskAppData* app_data = GetAppDataMutable(id);
    588   if (!app_data)
    589     return;
    590   FOR_EACH_OBSERVER(KioskAppManagerObserver,
    591                     observers_,
    592                     OnKioskExtensionLoadedInCache(id));
    593 
    594 }
    595 
    596 void KioskAppManager::OnExtensionDownloadFailed(
    597     const std::string& id,
    598     extensions::ExtensionDownloaderDelegate::Error error) {
    599   KioskAppData* app_data = GetAppDataMutable(id);
    600   if (!app_data)
    601     return;
    602   FOR_EACH_OBSERVER(KioskAppManagerObserver,
    603                     observers_,
    604                     OnKioskExtensionDownloadFailed(id));
    605 }
    606 
    607 KioskAppManager::AutoLoginState KioskAppManager::GetAutoLoginState() const {
    608   PrefService* prefs = g_browser_process->local_state();
    609   const base::DictionaryValue* dict =
    610       prefs->GetDictionary(KioskAppManager::kKioskDictionaryName);
    611   int value;
    612   if (!dict->GetInteger(kKeyAutoLoginState, &value))
    613     return AUTOLOGIN_NONE;
    614 
    615   return static_cast<AutoLoginState>(value);
    616 }
    617 
    618 void KioskAppManager::SetAutoLoginState(AutoLoginState state) {
    619   PrefService* prefs = g_browser_process->local_state();
    620   DictionaryPrefUpdate dict_update(prefs,
    621                                    KioskAppManager::kKioskDictionaryName);
    622   dict_update->SetInteger(kKeyAutoLoginState, state);
    623   prefs->CommitPendingWrite();
    624 }
    625 
    626 void KioskAppManager::GetCrxCacheDir(base::FilePath* cache_dir) {
    627   base::FilePath user_data_dir;
    628   CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
    629   *cache_dir = user_data_dir.AppendASCII(kCrxCacheDir);
    630 }
    631 
    632 void KioskAppManager::GetCrxUnpackDir(base::FilePath* unpack_dir) {
    633   base::FilePath temp_dir;
    634   base::GetTempDir(&temp_dir);
    635   *unpack_dir = temp_dir.AppendASCII(kCrxUnpackDir);
    636 }
    637 
    638 }  // namespace chromeos
    639