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