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