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