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