| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_prefs.h" | 5 #include "chrome/browser/extensions/extension_prefs.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/prefs/pref_notifier.h" | 10 #include "base/prefs/pref_notifier.h" |
| 11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/value_conversions.h" | 14 #include "base/value_conversions.h" |
| 15 #include "chrome/browser/extensions/api/content_settings/content_settings_store.
h" | 15 #include "chrome/browser/extensions/api/content_settings/content_settings_store.
h" |
| 16 #include "chrome/browser/extensions/api/preference/preference_api.h" | 16 #include "chrome/browser/extensions/api/preference/preference_api.h" |
| 17 #include "chrome/browser/extensions/extension_pref_store.h" | 17 #include "chrome/browser/extensions/extension_pref_store.h" |
| 18 #include "chrome/browser/extensions/extension_prefs_factory.h" | 18 #include "chrome/browser/extensions/extension_prefs_factory.h" |
| 19 #include "chrome/common/pref_names.h" | |
| 20 #include "components/user_prefs/pref_registry_syncable.h" | 19 #include "components/user_prefs/pref_registry_syncable.h" |
| 21 #include "extensions/browser/admin_policy.h" | 20 #include "extensions/browser/admin_policy.h" |
| 22 #include "extensions/browser/app_sorting.h" | 21 #include "extensions/browser/app_sorting.h" |
| 23 #include "extensions/browser/event_router.h" | 22 #include "extensions/browser/event_router.h" |
| 24 #include "extensions/browser/pref_names.h" | 23 #include "extensions/browser/pref_names.h" |
| 25 #include "extensions/common/feature_switch.h" | 24 #include "extensions/common/feature_switch.h" |
| 26 #include "extensions/common/manifest.h" | 25 #include "extensions/common/manifest.h" |
| 27 #include "extensions/common/permissions/permission_set.h" | 26 #include "extensions/common/permissions/permission_set.h" |
| 28 #include "extensions/common/permissions/permissions_info.h" | 27 #include "extensions/common/permissions/permissions_info.h" |
| 29 #include "extensions/common/url_pattern.h" | 28 #include "extensions/common/url_pattern.h" |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 const char kPrefLastLaunchTime[] = "last_launch_time"; | 174 const char kPrefLastLaunchTime[] = "last_launch_time"; |
| 176 | 175 |
| 177 // A list of installed ids and a signature. | 176 // A list of installed ids and a signature. |
| 178 const char kInstallSignature[] = "extensions.install_signature"; | 177 const char kInstallSignature[] = "extensions.install_signature"; |
| 179 | 178 |
| 180 // Provider of write access to a dictionary storing extension prefs. | 179 // Provider of write access to a dictionary storing extension prefs. |
| 181 class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate { | 180 class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate { |
| 182 public: | 181 public: |
| 183 ScopedExtensionPrefUpdate(PrefService* service, | 182 ScopedExtensionPrefUpdate(PrefService* service, |
| 184 const std::string& extension_id) : | 183 const std::string& extension_id) : |
| 185 DictionaryPrefUpdate(service, prefs::kExtensionsPref), | 184 DictionaryPrefUpdate(service, pref_names::kExtensions), |
| 186 extension_id_(extension_id) {} | 185 extension_id_(extension_id) {} |
| 187 | 186 |
| 188 virtual ~ScopedExtensionPrefUpdate() { | 187 virtual ~ScopedExtensionPrefUpdate() { |
| 189 } | 188 } |
| 190 | 189 |
| 191 // DictionaryPrefUpdate overrides: | 190 // DictionaryPrefUpdate overrides: |
| 192 virtual base::DictionaryValue* Get() OVERRIDE { | 191 virtual base::DictionaryValue* Get() OVERRIDE { |
| 193 base::DictionaryValue* dict = DictionaryPrefUpdate::Get(); | 192 base::DictionaryValue* dict = DictionaryPrefUpdate::Get(); |
| 194 base::DictionaryValue* extension = NULL; | 193 base::DictionaryValue* extension = NULL; |
| 195 if (!dict->GetDictionary(extension_id_, &extension)) { | 194 if (!dict->GetDictionary(extension_id_, &extension)) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 } | 234 } |
| 236 | 235 |
| 237 // | 236 // |
| 238 // ScopedUpdate | 237 // ScopedUpdate |
| 239 // | 238 // |
| 240 template <typename T, base::Value::Type type_enum_value> | 239 template <typename T, base::Value::Type type_enum_value> |
| 241 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::ScopedUpdate( | 240 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::ScopedUpdate( |
| 242 ExtensionPrefs* prefs, | 241 ExtensionPrefs* prefs, |
| 243 const std::string& extension_id, | 242 const std::string& extension_id, |
| 244 const std::string& key) | 243 const std::string& key) |
| 245 : update_(prefs->pref_service(), prefs::kExtensionsPref), | 244 : update_(prefs->pref_service(), pref_names::kExtensions), |
| 246 extension_id_(extension_id), | 245 extension_id_(extension_id), |
| 247 key_(key) { | 246 key_(key) { |
| 248 DCHECK(Extension::IdIsValid(extension_id_)); | 247 DCHECK(Extension::IdIsValid(extension_id_)); |
| 249 } | 248 } |
| 250 | 249 |
| 251 template <typename T, base::Value::Type type_enum_value> | 250 template <typename T, base::Value::Type type_enum_value> |
| 252 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::~ScopedUpdate() { | 251 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::~ScopedUpdate() { |
| 253 } | 252 } |
| 254 | 253 |
| 255 template <typename T, base::Value::Type type_enum_value> | 254 template <typename T, base::Value::Type type_enum_value> |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 base::FilePath::StringType retval = child.value().substr( | 342 base::FilePath::StringType retval = child.value().substr( |
| 344 parent.value().length()); | 343 parent.value().length()); |
| 345 if (base::FilePath::IsSeparator(retval[0])) | 344 if (base::FilePath::IsSeparator(retval[0])) |
| 346 return retval.substr(1); | 345 return retval.substr(1); |
| 347 else | 346 else |
| 348 return retval; | 347 return retval; |
| 349 } | 348 } |
| 350 | 349 |
| 351 void ExtensionPrefs::MakePathsRelative() { | 350 void ExtensionPrefs::MakePathsRelative() { |
| 352 const base::DictionaryValue* dict = | 351 const base::DictionaryValue* dict = |
| 353 prefs_->GetDictionary(prefs::kExtensionsPref); | 352 prefs_->GetDictionary(pref_names::kExtensions); |
| 354 if (!dict || dict->empty()) | 353 if (!dict || dict->empty()) |
| 355 return; | 354 return; |
| 356 | 355 |
| 357 // Collect all extensions ids with absolute paths in |absolute_keys|. | 356 // Collect all extensions ids with absolute paths in |absolute_keys|. |
| 358 std::set<std::string> absolute_keys; | 357 std::set<std::string> absolute_keys; |
| 359 for (base::DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) { | 358 for (base::DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) { |
| 360 const base::DictionaryValue* extension_dict = NULL; | 359 const base::DictionaryValue* extension_dict = NULL; |
| 361 if (!i.value().GetAsDictionary(&extension_dict)) | 360 if (!i.value().GetAsDictionary(&extension_dict)) |
| 362 continue; | 361 continue; |
| 363 int location_value; | 362 int location_value; |
| 364 if (extension_dict->GetInteger(kPrefLocation, &location_value) && | 363 if (extension_dict->GetInteger(kPrefLocation, &location_value) && |
| 365 Manifest::IsUnpackedLocation( | 364 Manifest::IsUnpackedLocation( |
| 366 static_cast<Manifest::Location>(location_value))) { | 365 static_cast<Manifest::Location>(location_value))) { |
| 367 // Unpacked extensions can have absolute paths. | 366 // Unpacked extensions can have absolute paths. |
| 368 continue; | 367 continue; |
| 369 } | 368 } |
| 370 base::FilePath::StringType path_string; | 369 base::FilePath::StringType path_string; |
| 371 if (!extension_dict->GetString(kPrefPath, &path_string)) | 370 if (!extension_dict->GetString(kPrefPath, &path_string)) |
| 372 continue; | 371 continue; |
| 373 base::FilePath path(path_string); | 372 base::FilePath path(path_string); |
| 374 if (path.IsAbsolute()) | 373 if (path.IsAbsolute()) |
| 375 absolute_keys.insert(i.key()); | 374 absolute_keys.insert(i.key()); |
| 376 } | 375 } |
| 377 if (absolute_keys.empty()) | 376 if (absolute_keys.empty()) |
| 378 return; | 377 return; |
| 379 | 378 |
| 380 // Fix these paths. | 379 // Fix these paths. |
| 381 DictionaryPrefUpdate update(prefs_, prefs::kExtensionsPref); | 380 DictionaryPrefUpdate update(prefs_, pref_names::kExtensions); |
| 382 base::DictionaryValue* update_dict = update.Get(); | 381 base::DictionaryValue* update_dict = update.Get(); |
| 383 for (std::set<std::string>::iterator i = absolute_keys.begin(); | 382 for (std::set<std::string>::iterator i = absolute_keys.begin(); |
| 384 i != absolute_keys.end(); ++i) { | 383 i != absolute_keys.end(); ++i) { |
| 385 base::DictionaryValue* extension_dict = NULL; | 384 base::DictionaryValue* extension_dict = NULL; |
| 386 if (!update_dict->GetDictionaryWithoutPathExpansion(*i, &extension_dict)) { | 385 if (!update_dict->GetDictionaryWithoutPathExpansion(*i, &extension_dict)) { |
| 387 NOTREACHED() << "Control should never reach here for extension " << *i; | 386 NOTREACHED() << "Control should never reach here for extension " << *i; |
| 388 continue; | 387 continue; |
| 389 } | 388 } |
| 390 base::FilePath::StringType path_string; | 389 base::FilePath::StringType path_string; |
| 391 extension_dict->GetString(kPrefPath, &path_string); | 390 extension_dict->GetString(kPrefPath, &path_string); |
| 392 base::FilePath path(path_string); | 391 base::FilePath path(path_string); |
| 393 extension_dict->SetString(kPrefPath, | 392 extension_dict->SetString(kPrefPath, |
| 394 MakePathRelative(install_directory_, path)); | 393 MakePathRelative(install_directory_, path)); |
| 395 } | 394 } |
| 396 } | 395 } |
| 397 | 396 |
| 398 const base::DictionaryValue* ExtensionPrefs::GetExtensionPref( | 397 const base::DictionaryValue* ExtensionPrefs::GetExtensionPref( |
| 399 const std::string& extension_id) const { | 398 const std::string& extension_id) const { |
| 400 const base::DictionaryValue* extensions = | 399 const base::DictionaryValue* extensions = |
| 401 prefs_->GetDictionary(prefs::kExtensionsPref); | 400 prefs_->GetDictionary(pref_names::kExtensions); |
| 402 const base::DictionaryValue* extension_dict = NULL; | 401 const base::DictionaryValue* extension_dict = NULL; |
| 403 if (!extensions || | 402 if (!extensions || |
| 404 !extensions->GetDictionary(extension_id, &extension_dict)) { | 403 !extensions->GetDictionary(extension_id, &extension_dict)) { |
| 405 return NULL; | 404 return NULL; |
| 406 } | 405 } |
| 407 return extension_dict; | 406 return extension_dict; |
| 408 } | 407 } |
| 409 | 408 |
| 410 void ExtensionPrefs::UpdateExtensionPref(const std::string& extension_id, | 409 void ExtensionPrefs::UpdateExtensionPref(const std::string& extension_id, |
| 411 const std::string& key, | 410 const std::string& key, |
| 412 base::Value* data_value) { | 411 base::Value* data_value) { |
| 413 if (!Extension::IdIsValid(extension_id)) { | 412 if (!Extension::IdIsValid(extension_id)) { |
| 414 NOTREACHED() << "Invalid extension_id " << extension_id; | 413 NOTREACHED() << "Invalid extension_id " << extension_id; |
| 415 return; | 414 return; |
| 416 } | 415 } |
| 417 ScopedExtensionPrefUpdate update(prefs_, extension_id); | 416 ScopedExtensionPrefUpdate update(prefs_, extension_id); |
| 418 if (data_value) | 417 if (data_value) |
| 419 update->Set(key, data_value); | 418 update->Set(key, data_value); |
| 420 else | 419 else |
| 421 update->Remove(key, NULL); | 420 update->Remove(key, NULL); |
| 422 } | 421 } |
| 423 | 422 |
| 424 void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) { | 423 void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) { |
| 425 extension_pref_value_map_->UnregisterExtension(extension_id); | 424 extension_pref_value_map_->UnregisterExtension(extension_id); |
| 426 content_settings_store_->UnregisterExtension(extension_id); | 425 content_settings_store_->UnregisterExtension(extension_id); |
| 427 DictionaryPrefUpdate update(prefs_, prefs::kExtensionsPref); | 426 DictionaryPrefUpdate update(prefs_, pref_names::kExtensions); |
| 428 base::DictionaryValue* dict = update.Get(); | 427 base::DictionaryValue* dict = update.Get(); |
| 429 dict->Remove(extension_id, NULL); | 428 dict->Remove(extension_id, NULL); |
| 430 } | 429 } |
| 431 | 430 |
| 432 bool ExtensionPrefs::ReadPrefAsBoolean(const std::string& extension_id, | 431 bool ExtensionPrefs::ReadPrefAsBoolean(const std::string& extension_id, |
| 433 const std::string& pref_key, | 432 const std::string& pref_key, |
| 434 bool* out_value) const { | 433 bool* out_value) const { |
| 435 const base::DictionaryValue* ext = GetExtensionPref(extension_id); | 434 const base::DictionaryValue* ext = GetExtensionPref(extension_id); |
| 436 if (!ext || !ext->GetBoolean(pref_key, out_value)) | 435 if (!ext || !ext->GetBoolean(pref_key, out_value)) |
| 437 return false; | 436 return false; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 } | 671 } |
| 673 | 672 |
| 674 void ExtensionPrefs::SetWipeoutAcknowledged( | 673 void ExtensionPrefs::SetWipeoutAcknowledged( |
| 675 const std::string& extension_id, | 674 const std::string& extension_id, |
| 676 bool value) { | 675 bool value) { |
| 677 UpdateExtensionPref(extension_id, kPrefWipeoutAcknowledged, | 676 UpdateExtensionPref(extension_id, kPrefWipeoutAcknowledged, |
| 678 value ? base::Value::CreateBooleanValue(value) : NULL); | 677 value ? base::Value::CreateBooleanValue(value) : NULL); |
| 679 } | 678 } |
| 680 | 679 |
| 681 bool ExtensionPrefs::SetAlertSystemFirstRun() { | 680 bool ExtensionPrefs::SetAlertSystemFirstRun() { |
| 682 if (prefs_->GetBoolean(prefs::kExtensionAlertsInitializedPref)) { | 681 if (prefs_->GetBoolean(pref_names::kAlertsInitialized)) { |
| 683 return true; | 682 return true; |
| 684 } | 683 } |
| 685 prefs_->SetBoolean(prefs::kExtensionAlertsInitializedPref, true); | 684 prefs_->SetBoolean(pref_names::kAlertsInitialized, true); |
| 686 return false; | 685 return false; |
| 687 } | 686 } |
| 688 | 687 |
| 689 bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const { | 688 bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const { |
| 690 return admin_policy::BlacklistedByDefault( | 689 return admin_policy::BlacklistedByDefault( |
| 691 prefs_->GetList(prefs::kExtensionInstallDenyList)); | 690 prefs_->GetList(pref_names::kInstallDenyList)); |
| 692 } | 691 } |
| 693 | 692 |
| 694 bool ExtensionPrefs::DidExtensionEscalatePermissions( | 693 bool ExtensionPrefs::DidExtensionEscalatePermissions( |
| 695 const std::string& extension_id) { | 694 const std::string& extension_id) { |
| 696 return ReadPrefAsBooleanAndReturn(extension_id, | 695 return ReadPrefAsBooleanAndReturn(extension_id, |
| 697 kExtensionDidEscalatePermissions); | 696 kExtensionDidEscalatePermissions); |
| 698 } | 697 } |
| 699 | 698 |
| 700 void ExtensionPrefs::SetDidExtensionEscalatePermissions( | 699 void ExtensionPrefs::SetDidExtensionEscalatePermissions( |
| 701 const Extension* extension, bool did_escalate) { | 700 const Extension* extension, bool did_escalate) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 } | 733 } |
| 735 | 734 |
| 736 void ExtensionPrefs::ClearDisableReasons(const std::string& extension_id) { | 735 void ExtensionPrefs::ClearDisableReasons(const std::string& extension_id) { |
| 737 UpdateExtensionPref(extension_id, kPrefDisableReasons, NULL); | 736 UpdateExtensionPref(extension_id, kPrefDisableReasons, NULL); |
| 738 } | 737 } |
| 739 | 738 |
| 740 std::set<std::string> ExtensionPrefs::GetBlacklistedExtensions() { | 739 std::set<std::string> ExtensionPrefs::GetBlacklistedExtensions() { |
| 741 std::set<std::string> ids; | 740 std::set<std::string> ids; |
| 742 | 741 |
| 743 const base::DictionaryValue* extensions = | 742 const base::DictionaryValue* extensions = |
| 744 prefs_->GetDictionary(prefs::kExtensionsPref); | 743 prefs_->GetDictionary(pref_names::kExtensions); |
| 745 if (!extensions) | 744 if (!extensions) |
| 746 return ids; | 745 return ids; |
| 747 | 746 |
| 748 for (base::DictionaryValue::Iterator it(*extensions); | 747 for (base::DictionaryValue::Iterator it(*extensions); |
| 749 !it.IsAtEnd(); it.Advance()) { | 748 !it.IsAtEnd(); it.Advance()) { |
| 750 if (!it.value().IsType(base::Value::TYPE_DICTIONARY)) { | 749 if (!it.value().IsType(base::Value::TYPE_DICTIONARY)) { |
| 751 NOTREACHED() << "Invalid pref for extension " << it.key(); | 750 NOTREACHED() << "Invalid pref for extension " << it.key(); |
| 752 continue; | 751 continue; |
| 753 } | 752 } |
| 754 if (IsBlacklistBitSet( | 753 if (IsBlacklistBitSet( |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 return DoesExtensionHaveState(id, Extension::EXTERNAL_EXTENSION_UNINSTALLED); | 1079 return DoesExtensionHaveState(id, Extension::EXTERNAL_EXTENSION_UNINSTALLED); |
| 1081 } | 1080 } |
| 1082 | 1081 |
| 1083 bool ExtensionPrefs::IsExtensionDisabled( | 1082 bool ExtensionPrefs::IsExtensionDisabled( |
| 1084 const std::string& id) const { | 1083 const std::string& id) const { |
| 1085 return DoesExtensionHaveState(id, Extension::DISABLED); | 1084 return DoesExtensionHaveState(id, Extension::DISABLED); |
| 1086 } | 1085 } |
| 1087 | 1086 |
| 1088 ExtensionIdList ExtensionPrefs::GetToolbarOrder() { | 1087 ExtensionIdList ExtensionPrefs::GetToolbarOrder() { |
| 1089 ExtensionIdList id_list_out; | 1088 ExtensionIdList id_list_out; |
| 1090 GetUserExtensionPrefIntoContainer(prefs::kExtensionToolbar, &id_list_out); | 1089 GetUserExtensionPrefIntoContainer(pref_names::kToolbar, &id_list_out); |
| 1091 return id_list_out; | 1090 return id_list_out; |
| 1092 } | 1091 } |
| 1093 | 1092 |
| 1094 void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList& extension_ids) { | 1093 void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList& extension_ids) { |
| 1095 SetExtensionPrefFromContainer(prefs::kExtensionToolbar, extension_ids); | 1094 SetExtensionPrefFromContainer(pref_names::kToolbar, extension_ids); |
| 1096 } | 1095 } |
| 1097 | 1096 |
| 1098 bool ExtensionPrefs::GetKnownDisabled(ExtensionIdSet* id_set_out) { | 1097 bool ExtensionPrefs::GetKnownDisabled(ExtensionIdSet* id_set_out) { |
| 1099 return GetUserExtensionPrefIntoContainer(prefs::kExtensionKnownDisabled, | 1098 return GetUserExtensionPrefIntoContainer(pref_names::kKnownDisabled, |
| 1100 id_set_out); | 1099 id_set_out); |
| 1101 } | 1100 } |
| 1102 | 1101 |
| 1103 void ExtensionPrefs::SetKnownDisabled(const ExtensionIdSet& extension_ids) { | 1102 void ExtensionPrefs::SetKnownDisabled(const ExtensionIdSet& extension_ids) { |
| 1104 SetExtensionPrefFromContainer(prefs::kExtensionKnownDisabled, extension_ids); | 1103 SetExtensionPrefFromContainer(pref_names::kKnownDisabled, extension_ids); |
| 1105 } | 1104 } |
| 1106 | 1105 |
| 1107 void ExtensionPrefs::OnExtensionInstalled( | 1106 void ExtensionPrefs::OnExtensionInstalled( |
| 1108 const Extension* extension, | 1107 const Extension* extension, |
| 1109 Extension::State initial_state, | 1108 Extension::State initial_state, |
| 1110 bool blacklisted_for_malware, | 1109 bool blacklisted_for_malware, |
| 1111 const syncer::StringOrdinal& page_ordinal) { | 1110 const syncer::StringOrdinal& page_ordinal) { |
| 1112 ScopedExtensionPrefUpdate update(prefs_, extension->id()); | 1111 ScopedExtensionPrefUpdate update(prefs_, extension->id()); |
| 1113 base::DictionaryValue* extension_dict = update.Get(); | 1112 base::DictionaryValue* extension_dict = update.Get(); |
| 1114 const base::Time install_time = time_provider_->GetCurrentTime(); | 1113 const base::Time install_time = time_provider_->GetCurrentTime(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 } | 1224 } |
| 1226 | 1225 |
| 1227 return scoped_ptr<ExtensionInfo>(new ExtensionInfo( | 1226 return scoped_ptr<ExtensionInfo>(new ExtensionInfo( |
| 1228 manifest, extension_id, base::FilePath(path), location)); | 1227 manifest, extension_id, base::FilePath(path), location)); |
| 1229 } | 1228 } |
| 1230 | 1229 |
| 1231 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledExtensionInfo( | 1230 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledExtensionInfo( |
| 1232 const std::string& extension_id) const { | 1231 const std::string& extension_id) const { |
| 1233 const base::DictionaryValue* ext = NULL; | 1232 const base::DictionaryValue* ext = NULL; |
| 1234 const base::DictionaryValue* extensions = | 1233 const base::DictionaryValue* extensions = |
| 1235 prefs_->GetDictionary(prefs::kExtensionsPref); | 1234 prefs_->GetDictionary(pref_names::kExtensions); |
| 1236 if (!extensions || | 1235 if (!extensions || |
| 1237 !extensions->GetDictionaryWithoutPathExpansion(extension_id, &ext)) | 1236 !extensions->GetDictionaryWithoutPathExpansion(extension_id, &ext)) |
| 1238 return scoped_ptr<ExtensionInfo>(); | 1237 return scoped_ptr<ExtensionInfo>(); |
| 1239 int state_value; | 1238 int state_value; |
| 1240 if (!ext->GetInteger(kPrefState, &state_value) || | 1239 if (!ext->GetInteger(kPrefState, &state_value) || |
| 1241 state_value == Extension::ENABLED_COMPONENT) { | 1240 state_value == Extension::ENABLED_COMPONENT) { |
| 1242 // Old preferences files may not have kPrefState for component extensions. | 1241 // Old preferences files may not have kPrefState for component extensions. |
| 1243 return scoped_ptr<ExtensionInfo>(); | 1242 return scoped_ptr<ExtensionInfo>(); |
| 1244 } | 1243 } |
| 1245 | 1244 |
| 1246 if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) { | 1245 if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) { |
| 1247 LOG(WARNING) << "External extension with id " << extension_id | 1246 LOG(WARNING) << "External extension with id " << extension_id |
| 1248 << " has been uninstalled by the user"; | 1247 << " has been uninstalled by the user"; |
| 1249 return scoped_ptr<ExtensionInfo>(); | 1248 return scoped_ptr<ExtensionInfo>(); |
| 1250 } | 1249 } |
| 1251 | 1250 |
| 1252 return GetInstalledInfoHelper(extension_id, ext); | 1251 return GetInstalledInfoHelper(extension_id, ext); |
| 1253 } | 1252 } |
| 1254 | 1253 |
| 1255 scoped_ptr<ExtensionPrefs::ExtensionsInfo> | 1254 scoped_ptr<ExtensionPrefs::ExtensionsInfo> |
| 1256 ExtensionPrefs::GetInstalledExtensionsInfo() const { | 1255 ExtensionPrefs::GetInstalledExtensionsInfo() const { |
| 1257 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); | 1256 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); |
| 1258 | 1257 |
| 1259 const base::DictionaryValue* extensions = | 1258 const base::DictionaryValue* extensions = |
| 1260 prefs_->GetDictionary(prefs::kExtensionsPref); | 1259 prefs_->GetDictionary(pref_names::kExtensions); |
| 1261 for (base::DictionaryValue::Iterator extension_id(*extensions); | 1260 for (base::DictionaryValue::Iterator extension_id(*extensions); |
| 1262 !extension_id.IsAtEnd(); extension_id.Advance()) { | 1261 !extension_id.IsAtEnd(); extension_id.Advance()) { |
| 1263 if (!Extension::IdIsValid(extension_id.key())) | 1262 if (!Extension::IdIsValid(extension_id.key())) |
| 1264 continue; | 1263 continue; |
| 1265 | 1264 |
| 1266 scoped_ptr<ExtensionInfo> info = | 1265 scoped_ptr<ExtensionInfo> info = |
| 1267 GetInstalledExtensionInfo(extension_id.key()); | 1266 GetInstalledExtensionInfo(extension_id.key()); |
| 1268 if (info) | 1267 if (info) |
| 1269 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); | 1268 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); |
| 1270 } | 1269 } |
| 1271 | 1270 |
| 1272 return extensions_info.Pass(); | 1271 return extensions_info.Pass(); |
| 1273 } | 1272 } |
| 1274 | 1273 |
| 1275 scoped_ptr<ExtensionPrefs::ExtensionsInfo> | 1274 scoped_ptr<ExtensionPrefs::ExtensionsInfo> |
| 1276 ExtensionPrefs::GetUninstalledExtensionsInfo() const { | 1275 ExtensionPrefs::GetUninstalledExtensionsInfo() const { |
| 1277 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); | 1276 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); |
| 1278 | 1277 |
| 1279 const base::DictionaryValue* extensions = | 1278 const base::DictionaryValue* extensions = |
| 1280 prefs_->GetDictionary(prefs::kExtensionsPref); | 1279 prefs_->GetDictionary(pref_names::kExtensions); |
| 1281 for (base::DictionaryValue::Iterator extension_id(*extensions); | 1280 for (base::DictionaryValue::Iterator extension_id(*extensions); |
| 1282 !extension_id.IsAtEnd(); extension_id.Advance()) { | 1281 !extension_id.IsAtEnd(); extension_id.Advance()) { |
| 1283 const base::DictionaryValue* ext = NULL; | 1282 const base::DictionaryValue* ext = NULL; |
| 1284 if (!Extension::IdIsValid(extension_id.key()) || | 1283 if (!Extension::IdIsValid(extension_id.key()) || |
| 1285 !IsExternalExtensionUninstalled(extension_id.key()) || | 1284 !IsExternalExtensionUninstalled(extension_id.key()) || |
| 1286 !extension_id.value().GetAsDictionary(&ext)) | 1285 !extension_id.value().GetAsDictionary(&ext)) |
| 1287 continue; | 1286 continue; |
| 1288 | 1287 |
| 1289 scoped_ptr<ExtensionInfo> info = | 1288 scoped_ptr<ExtensionInfo> info = |
| 1290 GetInstalledInfoHelper(extension_id.key(), ext); | 1289 GetInstalledInfoHelper(extension_id.key(), ext); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 return DELAY_REASON_NONE; | 1399 return DELAY_REASON_NONE; |
| 1401 | 1400 |
| 1402 return static_cast<DelayReason>(delay_reason); | 1401 return static_cast<DelayReason>(delay_reason); |
| 1403 } | 1402 } |
| 1404 | 1403 |
| 1405 scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs:: | 1404 scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs:: |
| 1406 GetAllDelayedInstallInfo() const { | 1405 GetAllDelayedInstallInfo() const { |
| 1407 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); | 1406 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); |
| 1408 | 1407 |
| 1409 const base::DictionaryValue* extensions = | 1408 const base::DictionaryValue* extensions = |
| 1410 prefs_->GetDictionary(prefs::kExtensionsPref); | 1409 prefs_->GetDictionary(pref_names::kExtensions); |
| 1411 for (base::DictionaryValue::Iterator extension_id(*extensions); | 1410 for (base::DictionaryValue::Iterator extension_id(*extensions); |
| 1412 !extension_id.IsAtEnd(); extension_id.Advance()) { | 1411 !extension_id.IsAtEnd(); extension_id.Advance()) { |
| 1413 if (!Extension::IdIsValid(extension_id.key())) | 1412 if (!Extension::IdIsValid(extension_id.key())) |
| 1414 continue; | 1413 continue; |
| 1415 | 1414 |
| 1416 scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key()); | 1415 scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key()); |
| 1417 if (info) | 1416 if (info) |
| 1418 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); | 1417 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); |
| 1419 } | 1418 } |
| 1420 | 1419 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1532 } | 1531 } |
| 1533 } | 1532 } |
| 1534 | 1533 |
| 1535 // static | 1534 // static |
| 1536 ExtensionIdList ExtensionPrefs::GetExtensionsFrom( | 1535 ExtensionIdList ExtensionPrefs::GetExtensionsFrom( |
| 1537 const PrefService* pref_service) { | 1536 const PrefService* pref_service) { |
| 1538 ExtensionIdList result; | 1537 ExtensionIdList result; |
| 1539 | 1538 |
| 1540 const base::DictionaryValue* extension_prefs = NULL; | 1539 const base::DictionaryValue* extension_prefs = NULL; |
| 1541 const base::Value* extension_prefs_value = | 1540 const base::Value* extension_prefs_value = |
| 1542 pref_service->GetUserPrefValue(prefs::kExtensionsPref); | 1541 pref_service->GetUserPrefValue(pref_names::kExtensions); |
| 1543 if (!extension_prefs_value || | 1542 if (!extension_prefs_value || |
| 1544 !extension_prefs_value->GetAsDictionary(&extension_prefs)) { | 1543 !extension_prefs_value->GetAsDictionary(&extension_prefs)) { |
| 1545 return result; // Empty set | 1544 return result; // Empty set |
| 1546 } | 1545 } |
| 1547 | 1546 |
| 1548 for (base::DictionaryValue::Iterator it(*extension_prefs); !it.IsAtEnd(); | 1547 for (base::DictionaryValue::Iterator it(*extension_prefs); !it.IsAtEnd(); |
| 1549 it.Advance()) { | 1548 it.Advance()) { |
| 1550 const base::DictionaryValue* ext = NULL; | 1549 const base::DictionaryValue* ext = NULL; |
| 1551 if (!it.value().GetAsDictionary(&ext)) { | 1550 if (!it.value().GetAsDictionary(&ext)) { |
| 1552 NOTREACHED() << "Invalid pref for extension " << it.key(); | 1551 NOTREACHED() << "Invalid pref for extension " << it.key(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 bool has_incognito_pref_value = false; | 1609 bool has_incognito_pref_value = false; |
| 1611 extension_pref_value_map_->GetEffectivePrefValue(pref_key, | 1610 extension_pref_value_map_->GetEffectivePrefValue(pref_key, |
| 1612 true, | 1611 true, |
| 1613 &has_incognito_pref_value); | 1612 &has_incognito_pref_value); |
| 1614 return has_incognito_pref_value; | 1613 return has_incognito_pref_value; |
| 1615 } | 1614 } |
| 1616 | 1615 |
| 1617 URLPatternSet ExtensionPrefs::GetAllowedInstallSites() { | 1616 URLPatternSet ExtensionPrefs::GetAllowedInstallSites() { |
| 1618 URLPatternSet result; | 1617 URLPatternSet result; |
| 1619 const base::ListValue* list = | 1618 const base::ListValue* list = |
| 1620 prefs_->GetList(prefs::kExtensionAllowedInstallSites); | 1619 prefs_->GetList(pref_names::kAllowedInstallSites); |
| 1621 CHECK(list); | 1620 CHECK(list); |
| 1622 | 1621 |
| 1623 for (size_t i = 0; i < list->GetSize(); ++i) { | 1622 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 1624 std::string entry_string; | 1623 std::string entry_string; |
| 1625 URLPattern entry(URLPattern::SCHEME_ALL); | 1624 URLPattern entry(URLPattern::SCHEME_ALL); |
| 1626 if (!list->GetString(i, &entry_string) || | 1625 if (!list->GetString(i, &entry_string) || |
| 1627 entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) { | 1626 entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) { |
| 1628 LOG(ERROR) << "Invalid value for preference: " | 1627 LOG(ERROR) << "Invalid value for preference: " |
| 1629 << prefs::kExtensionAllowedInstallSites | 1628 << pref_names::kAllowedInstallSites << "." << i; |
| 1630 << "." << i; | |
| 1631 continue; | 1629 continue; |
| 1632 } | 1630 } |
| 1633 result.AddPattern(entry); | 1631 result.AddPattern(entry); |
| 1634 } | 1632 } |
| 1635 | 1633 |
| 1636 return result; | 1634 return result; |
| 1637 } | 1635 } |
| 1638 | 1636 |
| 1639 const base::DictionaryValue* ExtensionPrefs::GetGeometryCache( | 1637 const base::DictionaryValue* ExtensionPrefs::GetGeometryCache( |
| 1640 const std::string& extension_id) const { | 1638 const std::string& extension_id) const { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 app_sorting_(app_sorting.Pass()), | 1682 app_sorting_(app_sorting.Pass()), |
| 1685 content_settings_store_(new ContentSettingsStore()), | 1683 content_settings_store_(new ContentSettingsStore()), |
| 1686 time_provider_(time_provider.Pass()), | 1684 time_provider_(time_provider.Pass()), |
| 1687 extensions_disabled_(extensions_disabled) { | 1685 extensions_disabled_(extensions_disabled) { |
| 1688 app_sorting_->SetExtensionScopedPrefs(this), | 1686 app_sorting_->SetExtensionScopedPrefs(this), |
| 1689 MakePathsRelative(); | 1687 MakePathsRelative(); |
| 1690 InitPrefStore(); | 1688 InitPrefStore(); |
| 1691 } | 1689 } |
| 1692 | 1690 |
| 1693 void ExtensionPrefs::SetNeedsStorageGarbageCollection(bool value) { | 1691 void ExtensionPrefs::SetNeedsStorageGarbageCollection(bool value) { |
| 1694 prefs_->SetBoolean(prefs::kExtensionStorageGarbageCollect, value); | 1692 prefs_->SetBoolean(pref_names::kStorageGarbageCollect, value); |
| 1695 } | 1693 } |
| 1696 | 1694 |
| 1697 bool ExtensionPrefs::NeedsStorageGarbageCollection() { | 1695 bool ExtensionPrefs::NeedsStorageGarbageCollection() { |
| 1698 return prefs_->GetBoolean(prefs::kExtensionStorageGarbageCollect); | 1696 return prefs_->GetBoolean(pref_names::kStorageGarbageCollect); |
| 1699 } | 1697 } |
| 1700 | 1698 |
| 1701 // static | 1699 // static |
| 1702 void ExtensionPrefs::RegisterProfilePrefs( | 1700 void ExtensionPrefs::RegisterProfilePrefs( |
| 1703 user_prefs::PrefRegistrySyncable* registry) { | 1701 user_prefs::PrefRegistrySyncable* registry) { |
| 1704 registry->RegisterDictionaryPref( | 1702 registry->RegisterDictionaryPref( |
| 1705 prefs::kExtensionsPref, | 1703 pref_names::kExtensions, |
| 1706 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1704 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1707 registry->RegisterListPref(prefs::kExtensionToolbar, | 1705 registry->RegisterListPref(pref_names::kToolbar, |
| 1708 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 1706 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| 1709 registry->RegisterIntegerPref( | 1707 registry->RegisterIntegerPref( |
| 1710 prefs::kExtensionToolbarSize, | 1708 pref_names::kToolbarSize, |
| 1711 -1, // default value | 1709 -1, // default value |
| 1712 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1710 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1713 registry->RegisterDictionaryPref( | 1711 registry->RegisterDictionaryPref( |
| 1714 kExtensionsBlacklistUpdate, | 1712 kExtensionsBlacklistUpdate, |
| 1715 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1713 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1716 registry->RegisterListPref(prefs::kExtensionInstallAllowList, | 1714 registry->RegisterListPref(pref_names::kInstallAllowList, |
| 1717 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1715 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1718 registry->RegisterListPref(prefs::kExtensionInstallDenyList, | 1716 registry->RegisterListPref(pref_names::kInstallDenyList, |
| 1719 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1717 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1720 registry->RegisterDictionaryPref( | 1718 registry->RegisterDictionaryPref( |
| 1721 prefs::kExtensionInstallForceList, | 1719 pref_names::kInstallForceList, |
| 1722 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1720 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1723 registry->RegisterListPref(prefs::kExtensionAllowedTypes, | 1721 registry->RegisterListPref(pref_names::kAllowedTypes, |
| 1724 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1722 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1725 registry->RegisterStringPref( | |
| 1726 prefs::kExtensionBlacklistUpdateVersion, | |
| 1727 "0", // default value | |
| 1728 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
| 1729 registry->RegisterBooleanPref( | 1723 registry->RegisterBooleanPref( |
| 1730 prefs::kExtensionStorageGarbageCollect, | 1724 pref_names::kStorageGarbageCollect, |
| 1731 false, // default value | 1725 false, // default value |
| 1732 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1726 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1733 registry->RegisterInt64Pref( | 1727 registry->RegisterInt64Pref( |
| 1734 prefs::kLastExtensionsUpdateCheck, | 1728 pref_names::kLastUpdateCheck, |
| 1735 0, // default value | 1729 0, // default value |
| 1736 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1730 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1737 registry->RegisterInt64Pref( | 1731 registry->RegisterInt64Pref( |
| 1738 prefs::kNextExtensionsUpdateCheck, | 1732 pref_names::kNextUpdateCheck, |
| 1739 0, // default value | 1733 0, // default value |
| 1740 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1734 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1741 registry->RegisterListPref(prefs::kExtensionAllowedInstallSites, | 1735 registry->RegisterListPref(pref_names::kAllowedInstallSites, |
| 1742 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1736 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1743 registry->RegisterStringPref( | 1737 registry->RegisterStringPref( |
| 1744 prefs::kExtensionsLastChromeVersion, | 1738 pref_names::kLastChromeVersion, |
| 1745 std::string(), // default value | 1739 std::string(), // default value |
| 1746 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1740 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1747 registry->RegisterListPref(prefs::kExtensionKnownDisabled, | 1741 registry->RegisterListPref(pref_names::kKnownDisabled, |
| 1748 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1742 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1749 #if defined(TOOLKIT_VIEWS) | 1743 #if defined(TOOLKIT_VIEWS) |
| 1750 registry->RegisterIntegerPref( | 1744 registry->RegisterIntegerPref( |
| 1751 prefs::kBrowserActionContainerWidth, | 1745 pref_names::kBrowserActionContainerWidth, |
| 1752 0, | 1746 0, |
| 1753 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1747 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1754 #endif | 1748 #endif |
| 1755 registry->RegisterDictionaryPref( | 1749 registry->RegisterDictionaryPref( |
| 1756 kInstallSignature, | 1750 kInstallSignature, |
| 1757 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1751 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1758 | 1752 |
| 1759 registry->RegisterListPref(prefs::kNativeMessagingBlacklist, | 1753 registry->RegisterListPref(pref_names::kNativeMessagingBlacklist, |
| 1760 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1754 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1761 registry->RegisterListPref(prefs::kNativeMessagingWhitelist, | 1755 registry->RegisterListPref(pref_names::kNativeMessagingWhitelist, |
| 1762 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 1756 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 1763 } | 1757 } |
| 1764 | 1758 |
| 1765 template <class ExtensionIdContainer> | 1759 template <class ExtensionIdContainer> |
| 1766 bool ExtensionPrefs::GetUserExtensionPrefIntoContainer( | 1760 bool ExtensionPrefs::GetUserExtensionPrefIntoContainer( |
| 1767 const char* pref, | 1761 const char* pref, |
| 1768 ExtensionIdContainer* id_container_out) { | 1762 ExtensionIdContainer* id_container_out) { |
| 1769 DCHECK(id_container_out->empty()); | 1763 DCHECK(id_container_out->empty()); |
| 1770 | 1764 |
| 1771 const base::Value* user_pref_value = prefs_->GetUserPrefValue(pref); | 1765 const base::Value* user_pref_value = prefs_->GetUserPrefValue(pref); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1890 is_enabled = initial_state == Extension::ENABLED; | 1884 is_enabled = initial_state == Extension::ENABLED; |
| 1891 } | 1885 } |
| 1892 | 1886 |
| 1893 extension_pref_value_map_->RegisterExtension(extension_id, install_time, | 1887 extension_pref_value_map_->RegisterExtension(extension_id, install_time, |
| 1894 is_enabled); | 1888 is_enabled); |
| 1895 content_settings_store_->RegisterExtension(extension_id, install_time, | 1889 content_settings_store_->RegisterExtension(extension_id, install_time, |
| 1896 is_enabled); | 1890 is_enabled); |
| 1897 } | 1891 } |
| 1898 | 1892 |
| 1899 } // namespace extensions | 1893 } // namespace extensions |
| OLD | NEW |