1 // Copyright (c) 2012 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/extensions/extension_prefs.h" 6 7 #include "base/prefs/pref_notifier.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_util.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/value_conversions.h" 13 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/extensions/admin_policy.h" 15 #include "chrome/browser/extensions/api/content_settings/content_settings_store.h" 16 #include "chrome/browser/extensions/api/preference/preference_api.h" 17 #include "chrome/browser/extensions/event_router.h" 18 #include "chrome/browser/extensions/extension_pref_store.h" 19 #include "chrome/browser/extensions/extension_prefs_factory.h" 20 #include "chrome/browser/extensions/extension_sorting.h" 21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/ui/host_desktop.h" 23 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/extensions/feature_switch.h" 25 #include "chrome/common/extensions/manifest.h" 26 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 27 #include "chrome/common/extensions/permissions/permission_set.h" 28 #include "chrome/common/extensions/permissions/permissions_info.h" 29 #include "chrome/common/pref_names.h" 30 #include "chrome/common/url_constants.h" 31 #include "components/user_prefs/pref_registry_syncable.h" 32 #include "content/public/browser/notification_service.h" 33 #include "extensions/browser/pref_names.h" 34 #include "extensions/common/url_pattern.h" 35 #include "extensions/common/user_script.h" 36 #include "grit/generated_resources.h" 37 #include "ui/base/l10n/l10n_util.h" 38 39 #if defined(USE_ASH) 40 #include "ash/shell.h" 41 #endif 42 #if defined(OS_WIN) 43 #include "win8/util/win8_util.h" 44 #endif // OS_WIN 45 46 using base::Value; 47 using base::DictionaryValue; 48 using base::ListValue; 49 50 namespace extensions { 51 52 namespace { 53 54 // Additional preferences keys, which are not needed by external clients. 55 56 // True if this extension is running. Note this preference stops getting updated 57 // during Chrome shutdown (and won't be updated on a browser crash) and so can 58 // be used at startup to determine whether the extension was running when Chrome 59 // was last terminated. 60 const char kPrefRunning[] = "running"; 61 62 // Whether this extension had windows when it was last running. 63 const char kIsActive[] = "is_active"; 64 65 // Where an extension was installed from. (see Manifest::Location) 66 const char kPrefLocation[] = "location"; 67 68 // Enabled, disabled, killed, etc. (see Extension::State) 69 const char kPrefState[] = "state"; 70 71 // The path to the current version's manifest file. 72 const char kPrefPath[] = "path"; 73 74 // The dictionary containing the extension's manifest. 75 const char kPrefManifest[] = "manifest"; 76 77 // The version number. 78 const char kPrefVersion[] = "manifest.version"; 79 80 // Indicates whether an extension is blacklisted. 81 const char kPrefBlacklist[] = "blacklist"; 82 83 // The count of how many times we prompted the user to acknowledge an 84 // extension. 85 const char kPrefAcknowledgePromptCount[] = "ack_prompt_count"; 86 87 // Indicates whether the user has acknowledged various types of extensions. 88 const char kPrefExternalAcknowledged[] = "ack_external"; 89 const char kPrefBlacklistAcknowledged[] = "ack_blacklist"; 90 91 // Indicates whether the external extension was installed during the first 92 // run of this profile. 93 const char kPrefExternalInstallFirstRun[] = "external_first_run"; 94 95 // Indicates whether to show an install warning when the user enables. 96 const char kExtensionDidEscalatePermissions[] = "install_warning_on_enable"; 97 98 // DO NOT USE, use kPrefDisableReasons instead. 99 // Indicates whether the extension was updated while it was disabled. 100 const char kDeprecatedPrefDisableReason[] = "disable_reason"; 101 102 // A bitmask of all the reasons an extension is disabled. 103 const char kPrefDisableReasons[] = "disable_reasons"; 104 105 // The key for a serialized Time value indicating the start of the day (from the 106 // server's perspective) an extension last included a "ping" parameter during 107 // its update check. 108 const char kLastPingDay[] = "lastpingday"; 109 110 // Similar to kLastPingDay, but for "active" instead of "rollcall" pings. 111 const char kLastActivePingDay[] = "last_active_pingday"; 112 113 // A bit we use to keep track of whether we need to do an "active" ping. 114 const char kActiveBit[] = "active_bit"; 115 116 // Path for settings specific to blacklist update. 117 const char kExtensionsBlacklistUpdate[] = "extensions.blacklistupdate"; 118 119 // Path for the delayed install info dictionary preference. The actual string 120 // value is a legacy artifact for when delayed installs only pertained to 121 // updates that were waiting for idle. 122 const char kDelayedInstallInfo[] = "idle_install_info"; 123 124 // Reason why the extension's install was delayed. 125 const char kDelayedInstallReason[] = "delay_install_reason"; 126 127 // Path for the suggested page ordinal of a delayed extension install. 128 const char kPrefSuggestedPageOrdinal[] = "suggested_page_ordinal"; 129 130 // A preference that, if true, will allow this extension to run in incognito 131 // mode. 132 const char kPrefIncognitoEnabled[] = "incognito"; 133 134 // A preference to control whether an extension is allowed to inject script in 135 // pages with file URLs. 136 const char kPrefAllowFileAccess[] = "newAllowFileAccess"; 137 // TODO(jstritar): As part of fixing http://crbug.com/91577, we revoked all 138 // extension file access by renaming the pref. We should eventually clean up 139 // the old flag and possibly go back to that name. 140 // const char kPrefAllowFileAccessOld[] = "allowFileAccess"; 141 142 // A preference set by the the NTP to persist the desired launch container type 143 // used for apps. 144 const char kPrefLaunchType[] = "launchType"; 145 146 // A preference specifying if the user dragged the app on the NTP. 147 const char kPrefUserDraggedApp[] = "user_dragged_app_ntp"; 148 149 // Preferences that hold which permissions the user has granted the extension. 150 // We explicitly keep track of these so that extensions can contain unknown 151 // permissions, for backwards compatibility reasons, and we can still prompt 152 // the user to accept them once recognized. We store the active permission 153 // permissions because they may differ from those defined in the manifest. 154 const char kPrefActivePermissions[] = "active_permissions"; 155 const char kPrefGrantedPermissions[] = "granted_permissions"; 156 157 // The preference names for PermissionSet values. 158 const char kPrefAPIs[] = "api"; 159 const char kPrefExplicitHosts[] = "explicit_host"; 160 const char kPrefScriptableHosts[] = "scriptable_host"; 161 162 // The preference names for the old granted permissions scheme. 163 const char kPrefOldGrantedFullAccess[] = "granted_permissions.full"; 164 const char kPrefOldGrantedHosts[] = "granted_permissions.host"; 165 const char kPrefOldGrantedAPIs[] = "granted_permissions.api"; 166 167 // A preference that indicates when an extension was installed. 168 const char kPrefInstallTime[] = "install_time"; 169 170 // A preference which saves the creation flags for extensions. 171 const char kPrefCreationFlags[] = "creation_flags"; 172 173 // A preference that indicates whether the extension was installed from the 174 // Chrome Web Store. 175 const char kPrefFromWebStore[] = "from_webstore"; 176 177 // A preference that indicates whether the extension was installed from a 178 // mock App created from a bookmark. 179 const char kPrefFromBookmark[] = "from_bookmark"; 180 181 // A preference that indicates whether the extension was installed as 182 // default apps. 183 const char kPrefWasInstalledByDefault[] = "was_installed_by_default"; 184 185 // Key for Geometry Cache preference. 186 const char kPrefGeometryCache[] = "geometry_cache"; 187 188 // Provider of write access to a dictionary storing extension prefs. 189 class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate { 190 public: 191 ScopedExtensionPrefUpdate(PrefService* service, 192 const std::string& extension_id) : 193 DictionaryPrefUpdate(service, ExtensionPrefs::kExtensionsPref), 194 extension_id_(extension_id) {} 195 196 virtual ~ScopedExtensionPrefUpdate() { 197 } 198 199 // DictionaryPrefUpdate overrides: 200 virtual DictionaryValue* Get() OVERRIDE { 201 DictionaryValue* dict = DictionaryPrefUpdate::Get(); 202 DictionaryValue* extension = NULL; 203 if (!dict->GetDictionary(extension_id_, &extension)) { 204 // Extension pref does not exist, create it. 205 extension = new DictionaryValue(); 206 dict->SetWithoutPathExpansion(extension_id_, extension); 207 } 208 return extension; 209 } 210 211 private: 212 const std::string extension_id_; 213 214 DISALLOW_COPY_AND_ASSIGN(ScopedExtensionPrefUpdate); 215 }; 216 217 std::string JoinPrefs(const std::string& parent, const char* child) { 218 return parent + "." + child; 219 } 220 221 // Checks if kPrefBlacklist is set to true in the DictionaryValue. 222 // Return false if the value is false or kPrefBlacklist does not exist. 223 // This is used to decide if an extension is blacklisted. 224 bool IsBlacklistBitSet(const DictionaryValue* ext) { 225 bool bool_value; 226 return ext->GetBoolean(kPrefBlacklist, &bool_value) && bool_value; 227 } 228 229 } // namespace 230 231 // 232 // TimeProvider 233 // 234 235 ExtensionPrefs::TimeProvider::TimeProvider() { 236 } 237 238 ExtensionPrefs::TimeProvider::~TimeProvider() { 239 } 240 241 base::Time ExtensionPrefs::TimeProvider::GetCurrentTime() const { 242 return base::Time::Now(); 243 } 244 245 // 246 // ScopedUpdate 247 // 248 template <typename T, base::Value::Type type_enum_value> 249 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::ScopedUpdate( 250 ExtensionPrefs* prefs, 251 const std::string& extension_id, 252 const std::string& key) 253 : update_(prefs->pref_service(), kExtensionsPref), 254 extension_id_(extension_id), 255 key_(key) { 256 DCHECK(Extension::IdIsValid(extension_id_)); 257 } 258 259 template <typename T, base::Value::Type type_enum_value> 260 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::~ScopedUpdate() { 261 } 262 263 template <typename T, base::Value::Type type_enum_value> 264 T* ExtensionPrefs::ScopedUpdate<T, type_enum_value>::Get() { 265 DictionaryValue* dict = update_.Get(); 266 DictionaryValue* extension = NULL; 267 Value* key_value = NULL; 268 if (!dict->GetDictionary(extension_id_, &extension) || 269 !extension->Get(key_, &key_value)) { 270 return NULL; 271 } 272 return key_value->GetType() == type_enum_value ? 273 static_cast<T*>(key_value) : 274 NULL; 275 } 276 277 template <typename T, base::Value::Type type_enum_value> 278 T* ExtensionPrefs::ScopedUpdate<T, type_enum_value>::Create() { 279 DictionaryValue* dict = update_.Get(); 280 DictionaryValue* extension = NULL; 281 Value* key_value = NULL; 282 T* value_as_t = NULL; 283 if (!dict->GetDictionary(extension_id_, &extension)) { 284 extension = new base::DictionaryValue; 285 dict->SetWithoutPathExpansion(extension_id_, extension); 286 } 287 if (!extension->Get(key_, &key_value)) { 288 value_as_t = new T; 289 extension->SetWithoutPathExpansion(key_, value_as_t); 290 } else { 291 CHECK(key_value->GetType() == type_enum_value); 292 value_as_t = static_cast<T*>(key_value); 293 } 294 return value_as_t; 295 } 296 297 // Explicit instantiations for Dictionary and List value types. 298 template class ExtensionPrefs::ScopedUpdate<DictionaryValue, 299 Value::TYPE_DICTIONARY>; 300 template class ExtensionPrefs::ScopedUpdate<ListValue, Value::TYPE_LIST>; 301 302 // 303 // ExtensionPrefs 304 // 305 306 // static 307 ExtensionPrefs* ExtensionPrefs::Create( 308 PrefService* prefs, 309 const base::FilePath& root_dir, 310 ExtensionPrefValueMap* extension_pref_value_map, 311 bool extensions_disabled) { 312 return ExtensionPrefs::Create(prefs, 313 root_dir, 314 extension_pref_value_map, 315 extensions_disabled, 316 make_scoped_ptr(new TimeProvider())); 317 } 318 319 // static 320 ExtensionPrefs* ExtensionPrefs::Create( 321 PrefService* pref_service, 322 const base::FilePath& root_dir, 323 ExtensionPrefValueMap* extension_pref_value_map, 324 bool extensions_disabled, 325 scoped_ptr<TimeProvider> time_provider) { 326 scoped_ptr<ExtensionPrefs> prefs( 327 new ExtensionPrefs(pref_service, 328 root_dir, 329 extension_pref_value_map, 330 time_provider.Pass(), 331 extensions_disabled)); 332 return prefs.release(); 333 } 334 335 ExtensionPrefs::~ExtensionPrefs() { 336 } 337 338 // static 339 ExtensionPrefs* ExtensionPrefs::Get(Profile* profile) { 340 return ExtensionPrefsFactory::GetInstance()->GetForProfile(profile); 341 } 342 343 // static 344 const char ExtensionPrefs::kExtensionsPref[] = "extensions.settings"; 345 // static 346 const char ExtensionPrefs::kExtensionsLastChromeVersion[] = 347 "extensions.last_chrome_version"; 348 349 static base::FilePath::StringType MakePathRelative(const base::FilePath& parent, 350 const base::FilePath& child) { 351 if (!parent.IsParent(child)) 352 return child.value(); 353 354 base::FilePath::StringType retval = child.value().substr( 355 parent.value().length()); 356 if (base::FilePath::IsSeparator(retval[0])) 357 return retval.substr(1); 358 else 359 return retval; 360 } 361 362 void ExtensionPrefs::MakePathsRelative() { 363 const DictionaryValue* dict = prefs_->GetDictionary(kExtensionsPref); 364 if (!dict || dict->empty()) 365 return; 366 367 // Collect all extensions ids with absolute paths in |absolute_keys|. 368 std::set<std::string> absolute_keys; 369 for (DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) { 370 const DictionaryValue* extension_dict = NULL; 371 if (!i.value().GetAsDictionary(&extension_dict)) 372 continue; 373 int location_value; 374 if (extension_dict->GetInteger(kPrefLocation, &location_value) && 375 Manifest::IsUnpackedLocation( 376 static_cast<Manifest::Location>(location_value))) { 377 // Unpacked extensions can have absolute paths. 378 continue; 379 } 380 base::FilePath::StringType path_string; 381 if (!extension_dict->GetString(kPrefPath, &path_string)) 382 continue; 383 base::FilePath path(path_string); 384 if (path.IsAbsolute()) 385 absolute_keys.insert(i.key()); 386 } 387 if (absolute_keys.empty()) 388 return; 389 390 // Fix these paths. 391 DictionaryPrefUpdate update(prefs_, kExtensionsPref); 392 DictionaryValue* update_dict = update.Get(); 393 for (std::set<std::string>::iterator i = absolute_keys.begin(); 394 i != absolute_keys.end(); ++i) { 395 DictionaryValue* extension_dict = NULL; 396 if (!update_dict->GetDictionaryWithoutPathExpansion(*i, &extension_dict)) { 397 NOTREACHED() << "Control should never reach here for extension " << *i; 398 continue; 399 } 400 base::FilePath::StringType path_string; 401 extension_dict->GetString(kPrefPath, &path_string); 402 base::FilePath path(path_string); 403 extension_dict->SetString(kPrefPath, 404 MakePathRelative(install_directory_, path)); 405 } 406 } 407 408 const DictionaryValue* ExtensionPrefs::GetExtensionPref( 409 const std::string& extension_id) const { 410 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); 411 const DictionaryValue* extension_dict = NULL; 412 if (!extensions || 413 !extensions->GetDictionary(extension_id, &extension_dict)) { 414 return NULL; 415 } 416 return extension_dict; 417 } 418 419 void ExtensionPrefs::UpdateExtensionPref(const std::string& extension_id, 420 const std::string& key, 421 Value* data_value) { 422 if (!Extension::IdIsValid(extension_id)) { 423 NOTREACHED() << "Invalid extension_id " << extension_id; 424 return; 425 } 426 ScopedExtensionPrefUpdate update(prefs_, extension_id); 427 if (data_value) 428 update->Set(key, data_value); 429 else 430 update->Remove(key, NULL); 431 } 432 433 void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) { 434 extension_pref_value_map_->UnregisterExtension(extension_id); 435 content_settings_store_->UnregisterExtension(extension_id); 436 DictionaryPrefUpdate update(prefs_, kExtensionsPref); 437 DictionaryValue* dict = update.Get(); 438 dict->Remove(extension_id, NULL); 439 } 440 441 bool ExtensionPrefs::ReadPrefAsBoolean(const std::string& extension_id, 442 const std::string& pref_key, 443 bool* out_value) const { 444 const DictionaryValue* ext = GetExtensionPref(extension_id); 445 if (!ext || !ext->GetBoolean(pref_key, out_value)) 446 return false; 447 448 return true; 449 } 450 451 bool ExtensionPrefs::ReadPrefAsInteger(const std::string& extension_id, 452 const std::string& pref_key, 453 int* out_value) const { 454 const DictionaryValue* ext = GetExtensionPref(extension_id); 455 if (!ext || !ext->GetInteger(pref_key, out_value)) 456 return false; 457 458 return true; 459 } 460 461 bool ExtensionPrefs::ReadPrefAsString(const std::string& extension_id, 462 const std::string& pref_key, 463 std::string* out_value) const { 464 const DictionaryValue* ext = GetExtensionPref(extension_id); 465 if (!ext || !ext->GetString(pref_key, out_value)) 466 return false; 467 468 return true; 469 } 470 471 bool ExtensionPrefs::ReadPrefAsList(const std::string& extension_id, 472 const std::string& pref_key, 473 const ListValue** out_value) const { 474 const DictionaryValue* ext = GetExtensionPref(extension_id); 475 const ListValue* out = NULL; 476 if (!ext || !ext->GetList(pref_key, &out)) 477 return false; 478 if (out_value) 479 *out_value = out; 480 481 return true; 482 } 483 484 bool ExtensionPrefs::ReadPrefAsDictionary( 485 const std::string& extension_id, 486 const std::string& pref_key, 487 const DictionaryValue** out_value) const { 488 const DictionaryValue* ext = GetExtensionPref(extension_id); 489 const DictionaryValue* out = NULL; 490 if (!ext || !ext->GetDictionary(pref_key, &out)) 491 return false; 492 if (out_value) 493 *out_value = out; 494 495 return true; 496 } 497 498 bool ExtensionPrefs::HasPrefForExtension( 499 const std::string& extension_id) const { 500 return GetExtensionPref(extension_id) != NULL; 501 } 502 503 bool ExtensionPrefs::ReadPrefAsURLPatternSet(const std::string& extension_id, 504 const std::string& pref_key, 505 URLPatternSet* result, 506 int valid_schemes) { 507 const ListValue* value = NULL; 508 if (!ReadPrefAsList(extension_id, pref_key, &value)) 509 return false; 510 511 bool allow_file_access = AllowFileAccess(extension_id); 512 return result->Populate(*value, valid_schemes, allow_file_access, NULL); 513 } 514 515 void ExtensionPrefs::SetExtensionPrefURLPatternSet( 516 const std::string& extension_id, 517 const std::string& pref_key, 518 const URLPatternSet& new_value) { 519 UpdateExtensionPref(extension_id, pref_key, new_value.ToValue().release()); 520 } 521 522 bool ExtensionPrefs::ReadPrefAsBooleanAndReturn( 523 const std::string& extension_id, 524 const std::string& pref_key) const { 525 bool out_value = false; 526 return ReadPrefAsBoolean(extension_id, pref_key, &out_value) && out_value; 527 } 528 529 PermissionSet* ExtensionPrefs::ReadPrefAsPermissionSet( 530 const std::string& extension_id, 531 const std::string& pref_key) { 532 if (!GetExtensionPref(extension_id)) 533 return NULL; 534 535 // Retrieve the API permissions. Please refer SetExtensionPrefPermissionSet() 536 // for api_values format. 537 APIPermissionSet apis; 538 const ListValue* api_values = NULL; 539 std::string api_pref = JoinPrefs(pref_key, kPrefAPIs); 540 if (ReadPrefAsList(extension_id, api_pref, &api_values)) { 541 APIPermissionSet::ParseFromJSON(api_values, 542 APIPermissionSet::kAllowInternalPermissions, 543 &apis, NULL, NULL); 544 } 545 546 // Retrieve the explicit host permissions. 547 URLPatternSet explicit_hosts; 548 ReadPrefAsURLPatternSet( 549 extension_id, JoinPrefs(pref_key, kPrefExplicitHosts), 550 &explicit_hosts, Extension::kValidHostPermissionSchemes); 551 552 // Retrieve the scriptable host permissions. 553 URLPatternSet scriptable_hosts; 554 ReadPrefAsURLPatternSet( 555 extension_id, JoinPrefs(pref_key, kPrefScriptableHosts), 556 &scriptable_hosts, UserScript::ValidUserScriptSchemes()); 557 558 return new PermissionSet(apis, explicit_hosts, scriptable_hosts); 559 } 560 561 void ExtensionPrefs::SetExtensionPrefPermissionSet( 562 const std::string& extension_id, 563 const std::string& pref_key, 564 const PermissionSet* new_value) { 565 // Set the API permissions. 566 // The format of api_values is: 567 // [ "permission_name1", // permissions do not support detail. 568 // "permission_name2", 569 // {"permission_name3": value }, 570 // // permission supports detail, permission detail will be stored in value. 571 // ... 572 // ] 573 ListValue* api_values = new ListValue(); 574 APIPermissionSet apis = new_value->apis(); 575 std::string api_pref = JoinPrefs(pref_key, kPrefAPIs); 576 for (APIPermissionSet::const_iterator i = apis.begin(); 577 i != apis.end(); ++i) { 578 scoped_ptr<Value> detail(i->ToValue()); 579 if (detail) { 580 DictionaryValue* tmp = new DictionaryValue(); 581 tmp->Set(i->name(), detail.release()); 582 api_values->Append(tmp); 583 } else { 584 api_values->Append(Value::CreateStringValue(i->name())); 585 } 586 } 587 UpdateExtensionPref(extension_id, api_pref, api_values); 588 589 // Set the explicit host permissions. 590 if (!new_value->explicit_hosts().is_empty()) { 591 SetExtensionPrefURLPatternSet(extension_id, 592 JoinPrefs(pref_key, kPrefExplicitHosts), 593 new_value->explicit_hosts()); 594 } 595 596 // Set the scriptable host permissions. 597 if (!new_value->scriptable_hosts().is_empty()) { 598 SetExtensionPrefURLPatternSet(extension_id, 599 JoinPrefs(pref_key, kPrefScriptableHosts), 600 new_value->scriptable_hosts()); 601 } 602 } 603 604 int ExtensionPrefs::IncrementAcknowledgePromptCount( 605 const std::string& extension_id) { 606 int count = 0; 607 ReadPrefAsInteger(extension_id, kPrefAcknowledgePromptCount, &count); 608 ++count; 609 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, 610 Value::CreateIntegerValue(count)); 611 return count; 612 } 613 614 bool ExtensionPrefs::IsExternalExtensionAcknowledged( 615 const std::string& extension_id) { 616 return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalAcknowledged); 617 } 618 619 void ExtensionPrefs::AcknowledgeExternalExtension( 620 const std::string& extension_id) { 621 DCHECK(Extension::IdIsValid(extension_id)); 622 UpdateExtensionPref(extension_id, kPrefExternalAcknowledged, 623 Value::CreateBooleanValue(true)); 624 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL); 625 } 626 627 bool ExtensionPrefs::IsBlacklistedExtensionAcknowledged( 628 const std::string& extension_id) { 629 return ReadPrefAsBooleanAndReturn(extension_id, kPrefBlacklistAcknowledged); 630 } 631 632 void ExtensionPrefs::AcknowledgeBlacklistedExtension( 633 const std::string& extension_id) { 634 DCHECK(Extension::IdIsValid(extension_id)); 635 UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged, 636 Value::CreateBooleanValue(true)); 637 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL); 638 } 639 640 bool ExtensionPrefs::IsExternalInstallFirstRun( 641 const std::string& extension_id) { 642 return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalInstallFirstRun); 643 } 644 645 void ExtensionPrefs::SetExternalInstallFirstRun( 646 const std::string& extension_id) { 647 DCHECK(Extension::IdIsValid(extension_id)); 648 UpdateExtensionPref(extension_id, kPrefExternalInstallFirstRun, 649 Value::CreateBooleanValue(true)); 650 } 651 652 bool ExtensionPrefs::SetAlertSystemFirstRun() { 653 if (prefs_->GetBoolean(prefs::kExtensionAlertsInitializedPref)) { 654 return true; 655 } 656 prefs_->SetBoolean(prefs::kExtensionAlertsInitializedPref, true); 657 return false; 658 } 659 660 bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const { 661 return admin_policy::BlacklistedByDefault( 662 prefs_->GetList(prefs::kExtensionInstallDenyList)); 663 } 664 665 bool ExtensionPrefs::DidExtensionEscalatePermissions( 666 const std::string& extension_id) { 667 return ReadPrefAsBooleanAndReturn(extension_id, 668 kExtensionDidEscalatePermissions); 669 } 670 671 void ExtensionPrefs::SetDidExtensionEscalatePermissions( 672 const Extension* extension, bool did_escalate) { 673 UpdateExtensionPref(extension->id(), kExtensionDidEscalatePermissions, 674 Value::CreateBooleanValue(did_escalate)); 675 } 676 677 int ExtensionPrefs::GetDisableReasons(const std::string& extension_id) { 678 int value = -1; 679 if (ReadPrefAsInteger(extension_id, kPrefDisableReasons, &value) && 680 value >= 0) { 681 return value; 682 } 683 return Extension::DISABLE_NONE; 684 } 685 686 void ExtensionPrefs::AddDisableReason(const std::string& extension_id, 687 Extension::DisableReason disable_reason) { 688 int new_value = GetDisableReasons(extension_id) | 689 static_cast<int>(disable_reason); 690 UpdateExtensionPref(extension_id, kPrefDisableReasons, 691 Value::CreateIntegerValue(new_value)); 692 } 693 694 void ExtensionPrefs::RemoveDisableReason( 695 const std::string& extension_id, 696 Extension::DisableReason disable_reason) { 697 int new_value = GetDisableReasons(extension_id) & 698 ~static_cast<int>(disable_reason); 699 if (new_value == Extension::DISABLE_NONE) { 700 UpdateExtensionPref(extension_id, kPrefDisableReasons, NULL); 701 } else { 702 UpdateExtensionPref(extension_id, kPrefDisableReasons, 703 Value::CreateIntegerValue(new_value)); 704 } 705 } 706 707 void ExtensionPrefs::ClearDisableReasons(const std::string& extension_id) { 708 UpdateExtensionPref(extension_id, kPrefDisableReasons, NULL); 709 } 710 711 std::set<std::string> ExtensionPrefs::GetBlacklistedExtensions() { 712 std::set<std::string> ids; 713 714 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); 715 if (!extensions) 716 return ids; 717 718 for (DictionaryValue::Iterator it(*extensions); !it.IsAtEnd(); it.Advance()) { 719 if (!it.value().IsType(Value::TYPE_DICTIONARY)) { 720 NOTREACHED() << "Invalid pref for extension " << it.key(); 721 continue; 722 } 723 if (IsBlacklistBitSet(static_cast<const DictionaryValue*>(&it.value()))) 724 ids.insert(it.key()); 725 } 726 727 return ids; 728 } 729 730 void ExtensionPrefs::SetExtensionBlacklisted(const std::string& extension_id, 731 bool is_blacklisted) { 732 bool currently_blacklisted = IsExtensionBlacklisted(extension_id); 733 if (is_blacklisted == currently_blacklisted) { 734 NOTREACHED() << extension_id << " is " << 735 (currently_blacklisted ? "already" : "not") << 736 " blacklisted"; 737 return; 738 } 739 740 // Always make sure the "acknowledged" bit is cleared since the blacklist bit 741 // is changing. 742 UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged, NULL); 743 744 if (is_blacklisted) { 745 UpdateExtensionPref(extension_id, 746 kPrefBlacklist, 747 new base::FundamentalValue(true)); 748 } else { 749 UpdateExtensionPref(extension_id, kPrefBlacklist, NULL); 750 const DictionaryValue* dict = GetExtensionPref(extension_id); 751 if (dict && dict->empty()) 752 DeleteExtensionPrefs(extension_id); 753 } 754 } 755 756 bool ExtensionPrefs::IsExtensionBlacklisted(const std::string& id) const { 757 const DictionaryValue* ext_prefs = GetExtensionPref(id); 758 return ext_prefs && IsBlacklistBitSet(ext_prefs); 759 } 760 761 namespace { 762 763 // Serializes |time| as a string value mapped to |key| in |dictionary|. 764 void SaveTime(DictionaryValue* dictionary, 765 const char* key, 766 const base::Time& time) { 767 if (!dictionary) 768 return; 769 std::string string_value = base::Int64ToString(time.ToInternalValue()); 770 dictionary->SetString(key, string_value); 771 } 772 773 // The opposite of SaveTime. If |key| is not found, this returns an empty Time 774 // (is_null() will return true). 775 base::Time ReadTime(const DictionaryValue* dictionary, const char* key) { 776 if (!dictionary) 777 return base::Time(); 778 std::string string_value; 779 int64 value; 780 if (dictionary->GetString(key, &string_value)) { 781 if (base::StringToInt64(string_value, &value)) { 782 return base::Time::FromInternalValue(value); 783 } 784 } 785 return base::Time(); 786 } 787 788 } // namespace 789 790 base::Time ExtensionPrefs::LastPingDay(const std::string& extension_id) const { 791 DCHECK(Extension::IdIsValid(extension_id)); 792 return ReadTime(GetExtensionPref(extension_id), kLastPingDay); 793 } 794 795 void ExtensionPrefs::SetLastPingDay(const std::string& extension_id, 796 const base::Time& time) { 797 DCHECK(Extension::IdIsValid(extension_id)); 798 ScopedExtensionPrefUpdate update(prefs_, extension_id); 799 SaveTime(update.Get(), kLastPingDay, time); 800 } 801 802 base::Time ExtensionPrefs::BlacklistLastPingDay() const { 803 return ReadTime(prefs_->GetDictionary(kExtensionsBlacklistUpdate), 804 kLastPingDay); 805 } 806 807 void ExtensionPrefs::SetBlacklistLastPingDay(const base::Time& time) { 808 DictionaryPrefUpdate update(prefs_, kExtensionsBlacklistUpdate); 809 SaveTime(update.Get(), kLastPingDay, time); 810 } 811 812 base::Time ExtensionPrefs::LastActivePingDay(const std::string& extension_id) { 813 DCHECK(Extension::IdIsValid(extension_id)); 814 return ReadTime(GetExtensionPref(extension_id), kLastActivePingDay); 815 } 816 817 void ExtensionPrefs::SetLastActivePingDay(const std::string& extension_id, 818 const base::Time& time) { 819 DCHECK(Extension::IdIsValid(extension_id)); 820 ScopedExtensionPrefUpdate update(prefs_, extension_id); 821 SaveTime(update.Get(), kLastActivePingDay, time); 822 } 823 824 bool ExtensionPrefs::GetActiveBit(const std::string& extension_id) { 825 const DictionaryValue* dictionary = GetExtensionPref(extension_id); 826 bool result = false; 827 if (dictionary && dictionary->GetBoolean(kActiveBit, &result)) 828 return result; 829 return false; 830 } 831 832 void ExtensionPrefs::SetActiveBit(const std::string& extension_id, 833 bool active) { 834 UpdateExtensionPref(extension_id, kActiveBit, 835 Value::CreateBooleanValue(active)); 836 } 837 838 void ExtensionPrefs::MigratePermissions(const ExtensionIdList& extension_ids) { 839 PermissionsInfo* info = PermissionsInfo::GetInstance(); 840 for (ExtensionIdList::const_iterator ext_id = 841 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) { 842 843 // An extension's granted permissions need to be migrated if the 844 // full_access bit is present. This bit was always present in the previous 845 // scheme and is never present now. 846 bool full_access; 847 const DictionaryValue* ext = GetExtensionPref(*ext_id); 848 if (!ext || !ext->GetBoolean(kPrefOldGrantedFullAccess, &full_access)) 849 continue; 850 851 // Remove the full access bit (empty list will get trimmed). 852 UpdateExtensionPref( 853 *ext_id, kPrefOldGrantedFullAccess, new ListValue()); 854 855 // Add the plugin permission if the full access bit was set. 856 if (full_access) { 857 const ListValue* apis = NULL; 858 ListValue* new_apis = NULL; 859 860 std::string granted_apis = 861 JoinPrefs(kPrefGrantedPermissions, kPrefAPIs); 862 if (ext->GetList(kPrefOldGrantedAPIs, &apis)) 863 new_apis = apis->DeepCopy(); 864 else 865 new_apis = new ListValue(); 866 867 std::string plugin_name = info->GetByID( 868 APIPermission::kPlugin)->name(); 869 new_apis->Append(Value::CreateStringValue(plugin_name)); 870 UpdateExtensionPref(*ext_id, granted_apis, new_apis); 871 } 872 873 // The granted permissions originally only held the effective hosts, 874 // which are a combination of host and user script host permissions. 875 // We now maintain these lists separately. For migration purposes, it 876 // does not matter how we treat the old effective hosts as long as the 877 // new effective hosts will be the same, so we move them to explicit 878 // host permissions. 879 const ListValue* hosts = NULL; 880 std::string explicit_hosts = 881 JoinPrefs(kPrefGrantedPermissions, kPrefExplicitHosts); 882 if (ext->GetList(kPrefOldGrantedHosts, &hosts)) { 883 UpdateExtensionPref( 884 *ext_id, explicit_hosts, hosts->DeepCopy()); 885 886 // We can get rid of the old one by setting it to an empty list. 887 UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new ListValue()); 888 } 889 } 890 } 891 892 void ExtensionPrefs::MigrateDisableReasons( 893 const ExtensionIdList& extension_ids) { 894 for (ExtensionIdList::const_iterator ext_id = 895 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) { 896 int value = -1; 897 if (ReadPrefAsInteger(*ext_id, kDeprecatedPrefDisableReason, &value)) { 898 int new_value = Extension::DISABLE_NONE; 899 switch (value) { 900 case Extension::DEPRECATED_DISABLE_USER_ACTION: 901 new_value = Extension::DISABLE_USER_ACTION; 902 break; 903 case Extension::DEPRECATED_DISABLE_PERMISSIONS_INCREASE: 904 new_value = Extension::DISABLE_PERMISSIONS_INCREASE; 905 break; 906 case Extension::DEPRECATED_DISABLE_RELOAD: 907 new_value = Extension::DISABLE_RELOAD; 908 break; 909 } 910 911 UpdateExtensionPref(*ext_id, kPrefDisableReasons, 912 Value::CreateIntegerValue(new_value)); 913 // Remove the old disable reason. 914 UpdateExtensionPref(*ext_id, kDeprecatedPrefDisableReason, NULL); 915 } 916 } 917 } 918 919 PermissionSet* ExtensionPrefs::GetGrantedPermissions( 920 const std::string& extension_id) { 921 CHECK(Extension::IdIsValid(extension_id)); 922 return ReadPrefAsPermissionSet(extension_id, kPrefGrantedPermissions); 923 } 924 925 void ExtensionPrefs::AddGrantedPermissions( 926 const std::string& extension_id, 927 const PermissionSet* permissions) { 928 CHECK(Extension::IdIsValid(extension_id)); 929 930 scoped_refptr<PermissionSet> granted_permissions( 931 GetGrantedPermissions(extension_id)); 932 933 // The new granted permissions are the union of the already granted 934 // permissions and the newly granted permissions. 935 scoped_refptr<PermissionSet> new_perms( 936 PermissionSet::CreateUnion( 937 permissions, granted_permissions.get())); 938 939 SetExtensionPrefPermissionSet( 940 extension_id, kPrefGrantedPermissions, new_perms.get()); 941 } 942 943 void ExtensionPrefs::RemoveGrantedPermissions( 944 const std::string& extension_id, 945 const PermissionSet* permissions) { 946 CHECK(Extension::IdIsValid(extension_id)); 947 948 scoped_refptr<PermissionSet> granted_permissions( 949 GetGrantedPermissions(extension_id)); 950 951 // The new granted permissions are the difference of the already granted 952 // permissions and the newly ungranted permissions. 953 scoped_refptr<PermissionSet> new_perms( 954 PermissionSet::CreateDifference( 955 granted_permissions.get(), permissions)); 956 957 SetExtensionPrefPermissionSet( 958 extension_id, kPrefGrantedPermissions, new_perms.get()); 959 } 960 961 PermissionSet* ExtensionPrefs::GetActivePermissions( 962 const std::string& extension_id) { 963 CHECK(Extension::IdIsValid(extension_id)); 964 return ReadPrefAsPermissionSet(extension_id, kPrefActivePermissions); 965 } 966 967 void ExtensionPrefs::SetActivePermissions( 968 const std::string& extension_id, 969 const PermissionSet* permissions) { 970 SetExtensionPrefPermissionSet( 971 extension_id, kPrefActivePermissions, permissions); 972 } 973 974 void ExtensionPrefs::SetExtensionRunning(const std::string& extension_id, 975 bool is_running) { 976 Value* value = Value::CreateBooleanValue(is_running); 977 UpdateExtensionPref(extension_id, kPrefRunning, value); 978 } 979 980 bool ExtensionPrefs::IsExtensionRunning(const std::string& extension_id) { 981 const DictionaryValue* extension = GetExtensionPref(extension_id); 982 if (!extension) 983 return false; 984 bool running = false; 985 extension->GetBoolean(kPrefRunning, &running); 986 return running; 987 } 988 989 void ExtensionPrefs::SetIsActive(const std::string& extension_id, 990 bool is_active) { 991 Value* value = Value::CreateBooleanValue(is_active); 992 UpdateExtensionPref(extension_id, kIsActive, value); 993 } 994 995 bool ExtensionPrefs::IsActive(const std::string& extension_id) { 996 const DictionaryValue* extension = GetExtensionPref(extension_id); 997 if (!extension) 998 return false; 999 bool is_active = false; 1000 extension->GetBoolean(kIsActive, &is_active); 1001 return is_active; 1002 } 1003 1004 bool ExtensionPrefs::IsIncognitoEnabled(const std::string& extension_id) { 1005 return ReadPrefAsBooleanAndReturn(extension_id, kPrefIncognitoEnabled); 1006 } 1007 1008 void ExtensionPrefs::SetIsIncognitoEnabled(const std::string& extension_id, 1009 bool enabled) { 1010 UpdateExtensionPref(extension_id, kPrefIncognitoEnabled, 1011 Value::CreateBooleanValue(enabled)); 1012 } 1013 1014 bool ExtensionPrefs::AllowFileAccess(const std::string& extension_id) { 1015 return ReadPrefAsBooleanAndReturn(extension_id, kPrefAllowFileAccess); 1016 } 1017 1018 void ExtensionPrefs::SetAllowFileAccess(const std::string& extension_id, 1019 bool allow) { 1020 UpdateExtensionPref(extension_id, kPrefAllowFileAccess, 1021 Value::CreateBooleanValue(allow)); 1022 } 1023 1024 bool ExtensionPrefs::HasAllowFileAccessSetting( 1025 const std::string& extension_id) const { 1026 const DictionaryValue* ext = GetExtensionPref(extension_id); 1027 return ext && ext->HasKey(kPrefAllowFileAccess); 1028 } 1029 1030 ExtensionPrefs::LaunchType ExtensionPrefs::GetLaunchType( 1031 const Extension* extension, 1032 ExtensionPrefs::LaunchType default_pref_value) { 1033 int value = -1; 1034 LaunchType result = LAUNCH_REGULAR; 1035 1036 if (ReadPrefAsInteger(extension->id(), kPrefLaunchType, &value) && 1037 (value == LAUNCH_PINNED || 1038 value == LAUNCH_REGULAR || 1039 value == LAUNCH_FULLSCREEN || 1040 value == LAUNCH_WINDOW)) { 1041 result = static_cast<LaunchType>(value); 1042 } else { 1043 result = default_pref_value; 1044 } 1045 #if (USE_ASH) 1046 if (ash::Shell::IsForcedMaximizeMode() && 1047 (result == LAUNCH_FULLSCREEN || result == LAUNCH_WINDOW)) 1048 result = LAUNCH_REGULAR; 1049 #endif 1050 #if defined(OS_MACOSX) 1051 // App windows are not yet supported on mac. Pref sync could make 1052 // the launch type LAUNCH_WINDOW, even if there is no UI to set it 1053 // on mac. 1054 if (!extension->is_platform_app() && result == LAUNCH_WINDOW) 1055 result = LAUNCH_REGULAR; 1056 #endif 1057 1058 #if defined(OS_WIN) 1059 // We don't support app windows in Windows 8 single window Metro mode. 1060 if (win8::IsSingleWindowMetroMode() && result == LAUNCH_WINDOW) 1061 result = LAUNCH_REGULAR; 1062 #endif // OS_WIN 1063 1064 return result; 1065 } 1066 1067 extension_misc::LaunchContainer ExtensionPrefs::GetLaunchContainer( 1068 const Extension* extension, 1069 ExtensionPrefs::LaunchType default_pref_value) { 1070 extension_misc::LaunchContainer manifest_launch_container = 1071 AppLaunchInfo::GetLaunchContainer(extension); 1072 1073 const extension_misc::LaunchContainer kInvalidLaunchContainer = 1074 static_cast<extension_misc::LaunchContainer>(-1); 1075 1076 extension_misc::LaunchContainer result = kInvalidLaunchContainer; 1077 1078 if (manifest_launch_container == extension_misc::LAUNCH_PANEL) { 1079 // Apps with app.launch.container = 'panel' should always respect the 1080 // manifest setting. 1081 result = manifest_launch_container; 1082 } else if (manifest_launch_container == extension_misc::LAUNCH_TAB) { 1083 // Look for prefs that indicate the user's choice of launch 1084 // container. The app's menu on the NTP provides a UI to set 1085 // this preference. If no preference is set, |default_pref_value| 1086 // is used. 1087 ExtensionPrefs::LaunchType prefs_launch_type = 1088 GetLaunchType(extension, default_pref_value); 1089 1090 if (prefs_launch_type == ExtensionPrefs::LAUNCH_WINDOW) { 1091 // If the pref is set to launch a window (or no pref is set, and 1092 // window opening is the default), make the container a window. 1093 result = extension_misc::LAUNCH_WINDOW; 1094 #if defined(USE_ASH) 1095 } else if (prefs_launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN && 1096 chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) { 1097 // LAUNCH_FULLSCREEN launches in a maximized app window in ash. 1098 // For desktop chrome AURA on all platforms we should open the 1099 // application in full screen mode in the current tab, on the same 1100 // lines as non AURA chrome. 1101 result = extension_misc::LAUNCH_WINDOW; 1102 #endif 1103 } else { 1104 // All other launch types (tab, pinned, fullscreen) are 1105 // implemented as tabs in a window. 1106 result = extension_misc::LAUNCH_TAB; 1107 } 1108 } else { 1109 // If a new value for app.launch.container is added, logic 1110 // for it should be added here. extension_misc::LAUNCH_WINDOW 1111 // is not present because there is no way to set it in a manifest. 1112 NOTREACHED() << manifest_launch_container; 1113 } 1114 1115 // All paths should set |result|. 1116 if (result == kInvalidLaunchContainer) { 1117 DLOG(FATAL) << "Failed to set a launch container."; 1118 result = extension_misc::LAUNCH_TAB; 1119 } 1120 1121 return result; 1122 } 1123 1124 void ExtensionPrefs::SetLaunchType(const std::string& extension_id, 1125 LaunchType launch_type) { 1126 UpdateExtensionPref(extension_id, kPrefLaunchType, 1127 Value::CreateIntegerValue(static_cast<int>(launch_type))); 1128 } 1129 1130 bool ExtensionPrefs::DoesExtensionHaveState( 1131 const std::string& id, Extension::State check_state) const { 1132 const DictionaryValue* extension = GetExtensionPref(id); 1133 int state = -1; 1134 if (!extension || !extension->GetInteger(kPrefState, &state)) 1135 return false; 1136 1137 if (state < 0 || state >= Extension::NUM_STATES) { 1138 LOG(ERROR) << "Bad pref 'state' for extension '" << id << "'"; 1139 return false; 1140 } 1141 1142 return state == check_state; 1143 } 1144 1145 bool ExtensionPrefs::IsExternalExtensionUninstalled( 1146 const std::string& id) const { 1147 return DoesExtensionHaveState(id, Extension::EXTERNAL_EXTENSION_UNINSTALLED); 1148 } 1149 1150 bool ExtensionPrefs::IsExtensionDisabled( 1151 const std::string& id) const { 1152 return DoesExtensionHaveState(id, Extension::DISABLED); 1153 } 1154 1155 ExtensionIdList ExtensionPrefs::GetToolbarOrder() { 1156 return GetExtensionPrefAsVector(prefs::kExtensionToolbar); 1157 } 1158 1159 void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList& extension_ids) { 1160 SetExtensionPrefFromVector(prefs::kExtensionToolbar, extension_ids); 1161 } 1162 1163 void ExtensionPrefs::OnExtensionInstalled( 1164 const Extension* extension, 1165 Extension::State initial_state, 1166 Blacklist::BlacklistState blacklist_state, 1167 const syncer::StringOrdinal& page_ordinal) { 1168 ScopedExtensionPrefUpdate update(prefs_, extension->id()); 1169 DictionaryValue* extension_dict = update.Get(); 1170 const base::Time install_time = time_provider_->GetCurrentTime(); 1171 PopulateExtensionInfoPrefs(extension, install_time, initial_state, 1172 blacklist_state, extension_dict); 1173 FinishExtensionInfoPrefs(extension->id(), install_time, 1174 extension->RequiresSortOrdinal(), 1175 page_ordinal, extension_dict); 1176 } 1177 1178 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, 1179 const Manifest::Location& location, 1180 bool external_uninstall) { 1181 extension_sorting_->ClearOrdinals(extension_id); 1182 1183 // For external extensions, we save a preference reminding ourself not to try 1184 // and install the extension anymore (except when |external_uninstall| is 1185 // true, which signifies that the registry key was deleted or the pref file 1186 // no longer lists the extension). 1187 if (!external_uninstall && Manifest::IsExternalLocation(location)) { 1188 UpdateExtensionPref(extension_id, kPrefState, 1189 Value::CreateIntegerValue( 1190 Extension::EXTERNAL_EXTENSION_UNINSTALLED)); 1191 extension_pref_value_map_->SetExtensionState(extension_id, false); 1192 content_settings_store_->SetExtensionState(extension_id, false); 1193 } else { 1194 DeleteExtensionPrefs(extension_id); 1195 } 1196 } 1197 1198 void ExtensionPrefs::SetExtensionState(const std::string& extension_id, 1199 Extension::State state) { 1200 UpdateExtensionPref(extension_id, kPrefState, 1201 Value::CreateIntegerValue(state)); 1202 bool enabled = (state == Extension::ENABLED); 1203 extension_pref_value_map_->SetExtensionState(extension_id, enabled); 1204 content_settings_store_->SetExtensionState(extension_id, enabled); 1205 } 1206 1207 std::string ExtensionPrefs::GetVersionString(const std::string& extension_id) { 1208 const DictionaryValue* extension = GetExtensionPref(extension_id); 1209 if (!extension) 1210 return std::string(); 1211 1212 std::string version; 1213 extension->GetString(kPrefVersion, &version); 1214 1215 return version; 1216 } 1217 1218 void ExtensionPrefs::UpdateManifest(const Extension* extension) { 1219 if (!Manifest::IsUnpackedLocation(extension->location())) { 1220 const DictionaryValue* extension_dict = 1221 GetExtensionPref(extension->id()); 1222 if (!extension_dict) 1223 return; 1224 const DictionaryValue* old_manifest = NULL; 1225 bool update_required = 1226 !extension_dict->GetDictionary(kPrefManifest, &old_manifest) || 1227 !extension->manifest()->value()->Equals(old_manifest); 1228 if (update_required) { 1229 UpdateExtensionPref(extension->id(), kPrefManifest, 1230 extension->manifest()->value()->DeepCopy()); 1231 } 1232 } 1233 } 1234 1235 base::FilePath ExtensionPrefs::GetExtensionPath( 1236 const std::string& extension_id) { 1237 const DictionaryValue* dict = GetExtensionPref(extension_id); 1238 if (!dict) 1239 return base::FilePath(); 1240 1241 std::string path; 1242 if (!dict->GetString(kPrefPath, &path)) 1243 return base::FilePath(); 1244 1245 return install_directory_.Append( 1246 base::FilePath::FromWStringHack(UTF8ToWide(path))); 1247 } 1248 1249 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledInfoHelper( 1250 const std::string& extension_id, 1251 const DictionaryValue* extension) const { 1252 int location_value; 1253 if (!extension->GetInteger(kPrefLocation, &location_value)) 1254 return scoped_ptr<ExtensionInfo>(); 1255 1256 base::FilePath::StringType path; 1257 if (!extension->GetString(kPrefPath, &path)) 1258 return scoped_ptr<ExtensionInfo>(); 1259 1260 // Make path absolute. Unpacked extensions will already have absolute paths, 1261 // otherwise make it so. 1262 Manifest::Location location = static_cast<Manifest::Location>(location_value); 1263 if (!Manifest::IsUnpackedLocation(location)) { 1264 DCHECK(location == Manifest::COMPONENT || 1265 !base::FilePath(path).IsAbsolute()); 1266 path = install_directory_.Append(path).value(); 1267 } 1268 1269 // Only the following extension types have data saved in the preferences. 1270 if (location != Manifest::INTERNAL && 1271 !Manifest::IsUnpackedLocation(location) && 1272 !Manifest::IsExternalLocation(location)) { 1273 NOTREACHED(); 1274 return scoped_ptr<ExtensionInfo>(); 1275 } 1276 1277 const DictionaryValue* manifest = NULL; 1278 if (!Manifest::IsUnpackedLocation(location) && 1279 !extension->GetDictionary(kPrefManifest, &manifest)) { 1280 LOG(WARNING) << "Missing manifest for extension " << extension_id; 1281 // Just a warning for now. 1282 } 1283 1284 return scoped_ptr<ExtensionInfo>(new ExtensionInfo( 1285 manifest, extension_id, base::FilePath(path), location)); 1286 } 1287 1288 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledExtensionInfo( 1289 const std::string& extension_id) const { 1290 const DictionaryValue* ext = NULL; 1291 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); 1292 if (!extensions || 1293 !extensions->GetDictionaryWithoutPathExpansion(extension_id, &ext)) 1294 return scoped_ptr<ExtensionInfo>(); 1295 int state_value; 1296 if (!ext->GetInteger(kPrefState, &state_value) || 1297 state_value == Extension::ENABLED_COMPONENT) { 1298 // Old preferences files may not have kPrefState for component extensions. 1299 return scoped_ptr<ExtensionInfo>(); 1300 } 1301 1302 if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) { 1303 LOG(WARNING) << "External extension with id " << extension_id 1304 << " has been uninstalled by the user"; 1305 return scoped_ptr<ExtensionInfo>(); 1306 } 1307 1308 return GetInstalledInfoHelper(extension_id, ext); 1309 } 1310 1311 scoped_ptr<ExtensionPrefs::ExtensionsInfo> 1312 ExtensionPrefs::GetInstalledExtensionsInfo() const { 1313 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); 1314 1315 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); 1316 for (DictionaryValue::Iterator extension_id(*extensions); 1317 !extension_id.IsAtEnd(); extension_id.Advance()) { 1318 if (!Extension::IdIsValid(extension_id.key())) 1319 continue; 1320 1321 scoped_ptr<ExtensionInfo> info = 1322 GetInstalledExtensionInfo(extension_id.key()); 1323 if (info) 1324 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); 1325 } 1326 1327 return extensions_info.Pass(); 1328 } 1329 1330 void ExtensionPrefs::SetDelayedInstallInfo( 1331 const Extension* extension, 1332 Extension::State initial_state, 1333 Blacklist::BlacklistState blacklist_state, 1334 DelayReason delay_reason, 1335 const syncer::StringOrdinal& page_ordinal) { 1336 DictionaryValue* extension_dict = new DictionaryValue(); 1337 PopulateExtensionInfoPrefs(extension, time_provider_->GetCurrentTime(), 1338 initial_state, blacklist_state, extension_dict); 1339 1340 // Add transient data that is needed by FinishDelayedInstallInfo(), but 1341 // should not be in the final extension prefs. All entries here should have 1342 // a corresponding Remove() call in FinishDelayedInstallInfo(). 1343 if (extension->RequiresSortOrdinal()) { 1344 extension_dict->SetString( 1345 kPrefSuggestedPageOrdinal, 1346 page_ordinal.IsValid() ? page_ordinal.ToInternalValue() 1347 : std::string()); 1348 } 1349 extension_dict->SetInteger(kDelayedInstallReason, 1350 static_cast<int>(delay_reason)); 1351 1352 UpdateExtensionPref(extension->id(), kDelayedInstallInfo, extension_dict); 1353 } 1354 1355 bool ExtensionPrefs::RemoveDelayedInstallInfo( 1356 const std::string& extension_id) { 1357 if (!GetExtensionPref(extension_id)) 1358 return false; 1359 ScopedExtensionPrefUpdate update(prefs_, extension_id); 1360 bool result = update->Remove(kDelayedInstallInfo, NULL); 1361 return result; 1362 } 1363 1364 bool ExtensionPrefs::FinishDelayedInstallInfo( 1365 const std::string& extension_id) { 1366 CHECK(Extension::IdIsValid(extension_id)); 1367 ScopedExtensionPrefUpdate update(prefs_, extension_id); 1368 DictionaryValue* extension_dict = update.Get(); 1369 DictionaryValue* pending_install_dict = NULL; 1370 if (!extension_dict->GetDictionary(kDelayedInstallInfo, 1371 &pending_install_dict)) { 1372 return false; 1373 } 1374 1375 // Retrieve and clear transient values populated by SetDelayedInstallInfo(). 1376 // Also do any other data cleanup that makes sense. 1377 std::string serialized_ordinal; 1378 syncer::StringOrdinal suggested_page_ordinal; 1379 bool needs_sort_ordinal = false; 1380 if (pending_install_dict->GetString(kPrefSuggestedPageOrdinal, 1381 &serialized_ordinal)) { 1382 suggested_page_ordinal = syncer::StringOrdinal(serialized_ordinal); 1383 needs_sort_ordinal = true; 1384 pending_install_dict->Remove(kPrefSuggestedPageOrdinal, NULL); 1385 } 1386 pending_install_dict->Remove(kDelayedInstallReason, NULL); 1387 1388 const base::Time install_time = time_provider_->GetCurrentTime(); 1389 pending_install_dict->Set( 1390 kPrefInstallTime, 1391 Value::CreateStringValue( 1392 base::Int64ToString(install_time.ToInternalValue()))); 1393 1394 // Commit the delayed install data. 1395 for (DictionaryValue::Iterator it(*pending_install_dict); !it.IsAtEnd(); 1396 it.Advance()) { 1397 extension_dict->Set(it.key(), it.value().DeepCopy()); 1398 } 1399 FinishExtensionInfoPrefs(extension_id, install_time, needs_sort_ordinal, 1400 suggested_page_ordinal, extension_dict); 1401 return true; 1402 } 1403 1404 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetDelayedInstallInfo( 1405 const std::string& extension_id) const { 1406 const DictionaryValue* extension_prefs = 1407 GetExtensionPref(extension_id); 1408 if (!extension_prefs) 1409 return scoped_ptr<ExtensionInfo>(); 1410 1411 const DictionaryValue* ext = NULL; 1412 if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext)) 1413 return scoped_ptr<ExtensionInfo>(); 1414 1415 return GetInstalledInfoHelper(extension_id, ext); 1416 } 1417 1418 ExtensionPrefs::DelayReason ExtensionPrefs::GetDelayedInstallReason( 1419 const std::string& extension_id) const { 1420 const DictionaryValue* extension_prefs = 1421 GetExtensionPref(extension_id); 1422 if (!extension_prefs) 1423 return DELAY_REASON_NONE; 1424 1425 const DictionaryValue* ext = NULL; 1426 if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext)) 1427 return DELAY_REASON_NONE; 1428 1429 int delay_reason; 1430 if (!ext->GetInteger(kDelayedInstallReason, &delay_reason)) 1431 return DELAY_REASON_NONE; 1432 1433 return static_cast<DelayReason>(delay_reason); 1434 } 1435 1436 scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs:: 1437 GetAllDelayedInstallInfo() const { 1438 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); 1439 1440 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); 1441 for (DictionaryValue::Iterator extension_id(*extensions); 1442 !extension_id.IsAtEnd(); extension_id.Advance()) { 1443 if (!Extension::IdIsValid(extension_id.key())) 1444 continue; 1445 1446 scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key()); 1447 if (info) 1448 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); 1449 } 1450 1451 return extensions_info.Pass(); 1452 } 1453 1454 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) { 1455 return ReadPrefAsBooleanAndReturn(extension_id, kPrefUserDraggedApp); 1456 } 1457 1458 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) { 1459 UpdateExtensionPref(extension_id, kPrefUserDraggedApp, 1460 Value::CreateBooleanValue(true)); 1461 } 1462 1463 bool ExtensionPrefs::IsFromWebStore( 1464 const std::string& extension_id) const { 1465 const DictionaryValue* dictionary = GetExtensionPref(extension_id); 1466 bool result = false; 1467 if (dictionary && dictionary->GetBoolean(kPrefFromWebStore, &result)) 1468 return result; 1469 return false; 1470 } 1471 1472 bool ExtensionPrefs::IsFromBookmark( 1473 const std::string& extension_id) const { 1474 const DictionaryValue* dictionary = GetExtensionPref(extension_id); 1475 bool result = false; 1476 if (dictionary && dictionary->GetBoolean(kPrefFromBookmark, &result)) 1477 return result; 1478 return false; 1479 } 1480 1481 int ExtensionPrefs::GetCreationFlags(const std::string& extension_id) const { 1482 int creation_flags = Extension::NO_FLAGS; 1483 if (!ReadPrefAsInteger(extension_id, kPrefCreationFlags, &creation_flags)) { 1484 // Since kPrefCreationFlags was added later, it will be missing for 1485 // previously installed extensions. 1486 if (IsFromBookmark(extension_id)) 1487 creation_flags |= Extension::FROM_BOOKMARK; 1488 if (IsFromWebStore(extension_id)) 1489 creation_flags |= Extension::FROM_WEBSTORE; 1490 if (WasInstalledByDefault(extension_id)) 1491 creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT; 1492 } 1493 return creation_flags; 1494 } 1495 1496 int ExtensionPrefs::GetDelayedInstallCreationFlags( 1497 const std::string& extension_id) const { 1498 int creation_flags = Extension::NO_FLAGS; 1499 const DictionaryValue* delayed_info = NULL; 1500 if (ReadPrefAsDictionary(extension_id, kDelayedInstallInfo, &delayed_info)) { 1501 delayed_info->GetInteger(kPrefCreationFlags, &creation_flags); 1502 } 1503 return creation_flags; 1504 } 1505 1506 bool ExtensionPrefs::WasInstalledByDefault( 1507 const std::string& extension_id) const { 1508 const DictionaryValue* dictionary = GetExtensionPref(extension_id); 1509 bool result = false; 1510 if (dictionary && 1511 dictionary->GetBoolean(kPrefWasInstalledByDefault, &result)) 1512 return result; 1513 return false; 1514 } 1515 1516 base::Time ExtensionPrefs::GetInstallTime( 1517 const std::string& extension_id) const { 1518 const DictionaryValue* extension = GetExtensionPref(extension_id); 1519 if (!extension) { 1520 NOTREACHED(); 1521 return base::Time(); 1522 } 1523 std::string install_time_str; 1524 if (!extension->GetString(kPrefInstallTime, &install_time_str)) 1525 return base::Time(); 1526 int64 install_time_i64 = 0; 1527 if (!base::StringToInt64(install_time_str, &install_time_i64)) 1528 return base::Time(); 1529 return base::Time::FromInternalValue(install_time_i64); 1530 } 1531 1532 void ExtensionPrefs::GetExtensions(ExtensionIdList* out) { 1533 CHECK(out); 1534 1535 scoped_ptr<ExtensionsInfo> extensions_info(GetInstalledExtensionsInfo()); 1536 1537 for (size_t i = 0; i < extensions_info->size(); ++i) { 1538 ExtensionInfo* info = extensions_info->at(i).get(); 1539 out->push_back(info->extension_id); 1540 } 1541 } 1542 1543 // static 1544 ExtensionIdList ExtensionPrefs::GetExtensionsFrom( 1545 const PrefService* pref_service) { 1546 ExtensionIdList result; 1547 1548 const DictionaryValue* extension_prefs = NULL; 1549 const Value* extension_prefs_value = 1550 pref_service->GetUserPrefValue(kExtensionsPref); 1551 if (!extension_prefs_value || 1552 !extension_prefs_value->GetAsDictionary(&extension_prefs)) { 1553 return result; // Empty set 1554 } 1555 1556 for (DictionaryValue::Iterator it(*extension_prefs); !it.IsAtEnd(); 1557 it.Advance()) { 1558 const DictionaryValue* ext = NULL; 1559 if (!it.value().GetAsDictionary(&ext)) { 1560 NOTREACHED() << "Invalid pref for extension " << it.key(); 1561 continue; 1562 } 1563 if (!IsBlacklistBitSet(ext)) 1564 result.push_back(it.key()); 1565 } 1566 return result; 1567 } 1568 1569 void ExtensionPrefs::FixMissingPrefs(const ExtensionIdList& extension_ids) { 1570 // Fix old entries that did not get an installation time entry when they 1571 // were installed or don't have a preferences field. 1572 for (ExtensionIdList::const_iterator ext_id = extension_ids.begin(); 1573 ext_id != extension_ids.end(); ++ext_id) { 1574 if (GetInstallTime(*ext_id) == base::Time()) { 1575 LOG(INFO) << "Could not parse installation time of extension " 1576 << *ext_id << ". It was probably installed before setting " 1577 << kPrefInstallTime << " was introduced. Updating " 1578 << kPrefInstallTime << " to the current time."; 1579 const base::Time install_time = time_provider_->GetCurrentTime(); 1580 UpdateExtensionPref(*ext_id, 1581 kPrefInstallTime, 1582 Value::CreateStringValue(base::Int64ToString( 1583 install_time.ToInternalValue()))); 1584 } 1585 } 1586 } 1587 1588 void ExtensionPrefs::InitPrefStore() { 1589 if (extensions_disabled_) { 1590 extension_pref_value_map_->NotifyInitializationCompleted(); 1591 return; 1592 } 1593 1594 // When this is called, the PrefService is initialized and provides access 1595 // to the user preferences stored in a JSON file. 1596 ExtensionIdList extension_ids; 1597 GetExtensions(&extension_ids); 1598 // Create empty preferences dictionary for each extension (these dictionaries 1599 // are pruned when persisting the preferences to disk). 1600 for (ExtensionIdList::iterator ext_id = extension_ids.begin(); 1601 ext_id != extension_ids.end(); ++ext_id) { 1602 ScopedExtensionPrefUpdate update(prefs_, *ext_id); 1603 // This creates an empty dictionary if none is stored. 1604 update.Get(); 1605 } 1606 1607 FixMissingPrefs(extension_ids); 1608 MigratePermissions(extension_ids); 1609 MigrateDisableReasons(extension_ids); 1610 extension_sorting_->Initialize(extension_ids); 1611 1612 PreferenceAPI::InitExtensionControlledPrefs(this, extension_pref_value_map_); 1613 1614 extension_pref_value_map_->NotifyInitializationCompleted(); 1615 } 1616 1617 bool ExtensionPrefs::HasIncognitoPrefValue(const std::string& pref_key) { 1618 bool has_incognito_pref_value = false; 1619 extension_pref_value_map_->GetEffectivePrefValue(pref_key, 1620 true, 1621 &has_incognito_pref_value); 1622 return has_incognito_pref_value; 1623 } 1624 1625 URLPatternSet ExtensionPrefs::GetAllowedInstallSites() { 1626 URLPatternSet result; 1627 const ListValue* list = prefs_->GetList(prefs::kExtensionAllowedInstallSites); 1628 CHECK(list); 1629 1630 for (size_t i = 0; i < list->GetSize(); ++i) { 1631 std::string entry_string; 1632 URLPattern entry(URLPattern::SCHEME_ALL); 1633 if (!list->GetString(i, &entry_string) || 1634 entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) { 1635 LOG(ERROR) << "Invalid value for preference: " 1636 << prefs::kExtensionAllowedInstallSites 1637 << "." << i; 1638 continue; 1639 } 1640 result.AddPattern(entry); 1641 } 1642 1643 return result; 1644 } 1645 1646 const DictionaryValue* ExtensionPrefs::GetGeometryCache( 1647 const std::string& extension_id) const { 1648 const DictionaryValue* extension_prefs = GetExtensionPref(extension_id); 1649 if (!extension_prefs) 1650 return NULL; 1651 1652 const DictionaryValue* ext = NULL; 1653 if (!extension_prefs->GetDictionary(kPrefGeometryCache, &ext)) 1654 return NULL; 1655 1656 return ext; 1657 } 1658 1659 void ExtensionPrefs::SetGeometryCache( 1660 const std::string& extension_id, 1661 scoped_ptr<DictionaryValue> cache) { 1662 UpdateExtensionPref(extension_id, kPrefGeometryCache, cache.release()); 1663 } 1664 1665 ExtensionPrefs::ExtensionPrefs( 1666 PrefService* prefs, 1667 const base::FilePath& root_dir, 1668 ExtensionPrefValueMap* extension_pref_value_map, 1669 scoped_ptr<TimeProvider> time_provider, 1670 bool extensions_disabled) 1671 : prefs_(prefs), 1672 install_directory_(root_dir), 1673 extension_pref_value_map_(extension_pref_value_map), 1674 extension_sorting_(new ExtensionSorting(this)), 1675 content_settings_store_(new ContentSettingsStore()), 1676 time_provider_(time_provider.Pass()), 1677 extensions_disabled_(extensions_disabled) { 1678 MakePathsRelative(); 1679 InitPrefStore(); 1680 } 1681 1682 void ExtensionPrefs::SetNeedsStorageGarbageCollection(bool value) { 1683 prefs_->SetBoolean(prefs::kExtensionStorageGarbageCollect, value); 1684 } 1685 1686 bool ExtensionPrefs::NeedsStorageGarbageCollection() { 1687 return prefs_->GetBoolean(prefs::kExtensionStorageGarbageCollect); 1688 } 1689 1690 // static 1691 void ExtensionPrefs::RegisterProfilePrefs( 1692 user_prefs::PrefRegistrySyncable* registry) { 1693 registry->RegisterDictionaryPref( 1694 kExtensionsPref, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1695 registry->RegisterListPref(prefs::kExtensionToolbar, 1696 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 1697 registry->RegisterIntegerPref( 1698 prefs::kExtensionToolbarSize, 1699 -1, // default value 1700 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1701 registry->RegisterDictionaryPref( 1702 kExtensionsBlacklistUpdate, 1703 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1704 registry->RegisterListPref(prefs::kExtensionInstallAllowList, 1705 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1706 registry->RegisterListPref(prefs::kExtensionInstallDenyList, 1707 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1708 registry->RegisterDictionaryPref( 1709 prefs::kExtensionInstallForceList, 1710 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1711 registry->RegisterListPref(prefs::kExtensionAllowedTypes, 1712 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1713 registry->RegisterStringPref( 1714 prefs::kExtensionBlacklistUpdateVersion, 1715 "0", // default value 1716 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1717 registry->RegisterBooleanPref( 1718 prefs::kExtensionStorageGarbageCollect, 1719 false, // default value 1720 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1721 registry->RegisterInt64Pref( 1722 prefs::kLastExtensionsUpdateCheck, 1723 0, // default value 1724 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1725 registry->RegisterInt64Pref( 1726 prefs::kNextExtensionsUpdateCheck, 1727 0, // default value 1728 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1729 registry->RegisterListPref(prefs::kExtensionAllowedInstallSites, 1730 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1731 registry->RegisterStringPref( 1732 kExtensionsLastChromeVersion, 1733 std::string(), // default value 1734 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1735 1736 #if defined(TOOLKIT_VIEWS) 1737 registry->RegisterIntegerPref( 1738 prefs::kBrowserActionContainerWidth, 1739 0, 1740 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1741 #endif 1742 } 1743 1744 ExtensionIdList ExtensionPrefs::GetExtensionPrefAsVector( 1745 const char* pref) { 1746 ExtensionIdList extension_ids; 1747 const ListValue* list_of_values = prefs_->GetList(pref); 1748 if (!list_of_values) 1749 return extension_ids; 1750 1751 std::string extension_id; 1752 for (size_t i = 0; i < list_of_values->GetSize(); ++i) { 1753 if (list_of_values->GetString(i, &extension_id)) 1754 extension_ids.push_back(extension_id); 1755 } 1756 return extension_ids; 1757 } 1758 1759 void ExtensionPrefs::SetExtensionPrefFromVector( 1760 const char* pref, 1761 const ExtensionIdList& strings) { 1762 ListPrefUpdate update(prefs_, pref); 1763 ListValue* list_of_values = update.Get(); 1764 list_of_values->Clear(); 1765 for (ExtensionIdList::const_iterator iter = strings.begin(); 1766 iter != strings.end(); ++iter) 1767 list_of_values->Append(new StringValue(*iter)); 1768 } 1769 1770 void ExtensionPrefs::PopulateExtensionInfoPrefs( 1771 const Extension* extension, 1772 const base::Time install_time, 1773 Extension::State initial_state, 1774 Blacklist::BlacklistState blacklist_state, 1775 DictionaryValue* extension_dict) { 1776 // Leave the state blank for component extensions so that old chrome versions 1777 // loading new profiles do not fail in GetInstalledExtensionInfo. Older 1778 // Chrome versions would only check for an omitted state. 1779 if (initial_state != Extension::ENABLED_COMPONENT) 1780 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); 1781 1782 extension_dict->Set(kPrefLocation, 1783 Value::CreateIntegerValue(extension->location())); 1784 extension_dict->Set(kPrefCreationFlags, 1785 Value::CreateIntegerValue(extension->creation_flags())); 1786 extension_dict->Set(kPrefFromWebStore, 1787 Value::CreateBooleanValue(extension->from_webstore())); 1788 extension_dict->Set(kPrefFromBookmark, 1789 Value::CreateBooleanValue(extension->from_bookmark())); 1790 extension_dict->Set( 1791 kPrefWasInstalledByDefault, 1792 Value::CreateBooleanValue(extension->was_installed_by_default())); 1793 extension_dict->Set(kPrefInstallTime, 1794 Value::CreateStringValue( 1795 base::Int64ToString(install_time.ToInternalValue()))); 1796 if (blacklist_state == Blacklist::BLACKLISTED) 1797 extension_dict->Set(kPrefBlacklist, Value::CreateBooleanValue(true)); 1798 1799 base::FilePath::StringType path = MakePathRelative(install_directory_, 1800 extension->path()); 1801 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); 1802 // We store prefs about LOAD extensions, but don't cache their manifest 1803 // since it may change on disk. 1804 if (!Manifest::IsUnpackedLocation(extension->location())) { 1805 extension_dict->Set(kPrefManifest, 1806 extension->manifest()->value()->DeepCopy()); 1807 } 1808 } 1809 1810 void ExtensionPrefs::FinishExtensionInfoPrefs( 1811 const std::string& extension_id, 1812 const base::Time install_time, 1813 bool needs_sort_ordinal, 1814 const syncer::StringOrdinal& suggested_page_ordinal, 1815 DictionaryValue* extension_dict) { 1816 // Reinitializes various preferences with empty dictionaries. 1817 extension_dict->Set(pref_names::kPrefPreferences, new DictionaryValue); 1818 extension_dict->Set(pref_names::kPrefIncognitoPreferences, 1819 new DictionaryValue); 1820 extension_dict->Set(pref_names::kPrefRegularOnlyPreferences, 1821 new DictionaryValue); 1822 extension_dict->Set(pref_names::kPrefContentSettings, new ListValue); 1823 extension_dict->Set(pref_names::kPrefIncognitoContentSettings, new ListValue); 1824 1825 // If this point has been reached, any pending installs should be considered 1826 // out of date. 1827 extension_dict->Remove(kDelayedInstallInfo, NULL); 1828 1829 // Clear state that may be registered from a previous install. 1830 extension_dict->Remove(EventRouter::kRegisteredEvents, NULL); 1831 1832 // FYI, all code below here races on sudden shutdown because 1833 // |extension_dict|, |extension_sorting_|, |extension_pref_value_map_|, 1834 // and |content_settings_store_| are updated non-transactionally. This is 1835 // probably not fixable without nested transactional updates to pref 1836 // dictionaries. 1837 if (needs_sort_ordinal) { 1838 extension_sorting_->EnsureValidOrdinals(extension_id, 1839 suggested_page_ordinal); 1840 } 1841 1842 bool is_enabled = false; 1843 int initial_state; 1844 if (extension_dict->GetInteger(kPrefState, &initial_state)) { 1845 is_enabled = initial_state == Extension::ENABLED; 1846 } 1847 1848 extension_pref_value_map_->RegisterExtension(extension_id, install_time, 1849 is_enabled); 1850 content_settings_store_->RegisterExtension(extension_id, install_time, 1851 is_enabled); 1852 } 1853 1854 } // namespace extensions 1855