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