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