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