Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(877)

Side by Side Diff: chrome/browser/extensions/extension_prefs.cc

Issue 5213002: Fix for Bug 50726 "Save extension list and "winning" prefs from extensions" (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Temporary hack to fix regression in unit tests Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "base/string_util.h" 7 #include "base/string_util.h"
8 #include "base/string_number_conversions.h" 8 #include "base/string_number_conversions.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/prefs/in_memory_pref_store.h"
10 #include "chrome/common/extensions/extension.h" 11 #include "chrome/common/extensions/extension.h"
11 #include "chrome/common/notification_service.h" 12 #include "chrome/common/notification_service.h"
12 #include "chrome/common/pref_names.h" 13 #include "chrome/common/pref_names.h"
13 14
14 using base::Time; 15 using base::Time;
15 16
16 namespace { 17 namespace {
17 18
18 // Additional preferences keys 19 // Additional preferences keys
19 20
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 76
76 // A preference determining the order of which the apps appear on the NTP. 77 // A preference determining the order of which the apps appear on the NTP.
77 const char kPrefAppLaunchIndex[] = "app_launcher_index"; 78 const char kPrefAppLaunchIndex[] = "app_launcher_index";
78 79
79 // A preference for storing extra data sent in update checks for an extension. 80 // A preference for storing extra data sent in update checks for an extension.
80 const char kUpdateUrlData[] = "update_url_data"; 81 const char kUpdateUrlData[] = "update_url_data";
81 82
82 // Whether the browser action is visible in the toolbar. 83 // Whether the browser action is visible in the toolbar.
83 const char kBrowserActionVisible[] = "browser_action_visible"; 84 const char kBrowserActionVisible[] = "browser_action_visible";
84 85
86 // A preference that indicates when an extension was installed.
87 const char kPrefInstallTime[] = "install_time";
88
89 // A preference that indicates the last effective preference values of an
90 // extension. The value is a dictionary mapping (non-expanded) preference keys
91 // to the values configured by the extension.
92 const char kPrefPreferences[] = "preferences";
Aaron Boodman 2010/11/23 20:35:13 I'm split on having this subtree and the correspon
Mattias Nissler (ping if slow) 2010/11/23 22:02:44 My vote is for the namespace separation. This also
battre (please use the other) 2010/11/30 17:46:53 We have discussed this with several people in MUC
93
85 } // namespace 94 } // namespace
86 95
87 //////////////////////////////////////////////////////////////////////////////// 96 ////////////////////////////////////////////////////////////////////////////////
88 97
89 namespace { 98 namespace {
90 99
91 // TODO(asargent) - This is cleanup code for a key that was introduced into 100 // TODO(asargent) - This is cleanup code for a key that was introduced into
92 // the extensions.settings sub-dictionary which wasn't a valid extension 101 // the extensions.settings sub-dictionary which wasn't a valid extension
93 // id. We can remove this in a couple of months. (See http://crbug.com/40017 102 // id. We can remove this in a couple of months. (See http://crbug.com/40017
94 // and http://crbug.com/39745 for more details). 103 // and http://crbug.com/39745 for more details).
(...skipping 21 matching lines...) Expand all
116 } // namespace 125 } // namespace
117 126
118 ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir) 127 ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir)
119 : prefs_(prefs), 128 : prefs_(prefs),
120 install_directory_(root_dir) { 129 install_directory_(root_dir) {
121 // TODO(asargent) - Remove this in a couple of months. (See comment above 130 // TODO(asargent) - Remove this in a couple of months. (See comment above
122 // CleanupBadExtensionKeys). 131 // CleanupBadExtensionKeys).
123 CleanupBadExtensionKeys(prefs); 132 CleanupBadExtensionKeys(prefs);
124 133
125 MakePathsRelative(); 134 MakePathsRelative();
135
136 InstallPersistedExtensionControlledPrefs();
126 } 137 }
127 138
128 ExtensionPrefs::~ExtensionPrefs() {} 139 ExtensionPrefs::~ExtensionPrefs() {}
129 140
130 // static 141 // static
131 const char ExtensionPrefs::kExtensionsPref[] = "extensions.settings"; 142 const char ExtensionPrefs::kExtensionsPref[] = "extensions.settings";
132 143
133 static FilePath::StringType MakePathRelative(const FilePath& parent, 144 static FilePath::StringType MakePathRelative(const FilePath& parent,
134 const FilePath& child, 145 const FilePath& child,
135 bool *dirty) { 146 bool *dirty) {
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 // Check to see if the extension has been killed. 505 // Check to see if the extension has been killed.
495 int state; 506 int state;
496 if (extension->GetInteger(kPrefState, &state) && 507 if (extension->GetInteger(kPrefState, &state) &&
497 state == static_cast<int>(Extension::KILLBIT)) { 508 state == static_cast<int>(Extension::KILLBIT)) {
498 killed_ids->insert(StringToLowerASCII(key_name)); 509 killed_ids->insert(StringToLowerASCII(key_name));
499 } 510 }
500 } 511 }
501 } 512 }
502 513
503 std::vector<std::string> ExtensionPrefs::GetToolbarOrder() { 514 std::vector<std::string> ExtensionPrefs::GetToolbarOrder() {
504 std::vector<std::string> extension_ids; 515 ExtensionPrefs::ExtensionIdSet extension_ids;
505 const ListValue* toolbar_order = prefs_->GetList(kExtensionToolbar); 516 const ListValue* toolbar_order = prefs_->GetList(kExtensionToolbar);
506 if (toolbar_order) { 517 if (toolbar_order) {
507 for (size_t i = 0; i < toolbar_order->GetSize(); ++i) { 518 for (size_t i = 0; i < toolbar_order->GetSize(); ++i) {
508 std::string extension_id; 519 std::string extension_id;
509 if (toolbar_order->GetString(i, &extension_id)) 520 if (toolbar_order->GetString(i, &extension_id))
510 extension_ids.push_back(extension_id); 521 extension_ids.push_back(extension_id);
511 } 522 }
512 } 523 }
513 return extension_ids; 524 return extension_ids;
514 } 525 }
515 526
516 void ExtensionPrefs::SetToolbarOrder( 527 void ExtensionPrefs::SetToolbarOrder(
517 const std::vector<std::string>& extension_ids) { 528 const std::vector<std::string>& extension_ids) {
518 ListValue* toolbar_order = prefs_->GetMutableList(kExtensionToolbar); 529 ListValue* toolbar_order = prefs_->GetMutableList(kExtensionToolbar);
519 toolbar_order->Clear(); 530 toolbar_order->Clear();
520 for (std::vector<std::string>::const_iterator iter = extension_ids.begin(); 531 for (std::vector<std::string>::const_iterator iter = extension_ids.begin();
521 iter != extension_ids.end(); ++iter) { 532 iter != extension_ids.end(); ++iter) {
522 toolbar_order->Append(new StringValue(*iter)); 533 toolbar_order->Append(new StringValue(*iter));
523 } 534 }
524 SavePrefsAndNotify(); 535 SavePrefsAndNotify();
525 } 536 }
526 537
527 void ExtensionPrefs::OnExtensionInstalled( 538 void ExtensionPrefs::OnExtensionInstalled(
528 const Extension* extension, Extension::State initial_state, 539 const Extension* extension, Extension::State initial_state,
529 bool initial_incognito_enabled) { 540 bool initial_incognito_enabled) {
530 const std::string& id = extension->id(); 541 const std::string& id = extension->id();
542 const base::Time installTime = GetCurrentTime();
531 UpdateExtensionPref(id, kPrefState, 543 UpdateExtensionPref(id, kPrefState,
532 Value::CreateIntegerValue(initial_state)); 544 Value::CreateIntegerValue(initial_state));
533 UpdateExtensionPref(id, kPrefIncognitoEnabled, 545 UpdateExtensionPref(id, kPrefIncognitoEnabled,
534 Value::CreateBooleanValue(initial_incognito_enabled)); 546 Value::CreateBooleanValue(initial_incognito_enabled));
535 UpdateExtensionPref(id, kPrefLocation, 547 UpdateExtensionPref(id, kPrefLocation,
536 Value::CreateIntegerValue(extension->location())); 548 Value::CreateIntegerValue(extension->location()));
549 UpdateExtensionPref(id, kPrefInstallTime,
550 Value::CreateStringValue(
551 base::Int64ToString(installTime.ToInternalValue())));
552 UpdateExtensionPref(id, kPrefPreferences, new DictionaryValue());
Aaron Boodman 2010/11/23 20:35:13 Nit: since you know that this will be removed if e
battre (please use the other) 2010/11/30 17:46:53 That is true, but on the other hand, I like having
553
537 FilePath::StringType path = MakePathRelative(install_directory_, 554 FilePath::StringType path = MakePathRelative(install_directory_,
538 extension->path(), NULL); 555 extension->path(), NULL);
539 UpdateExtensionPref(id, kPrefPath, Value::CreateStringValue(path)); 556 UpdateExtensionPref(id, kPrefPath, Value::CreateStringValue(path));
540 // We store prefs about LOAD extensions, but don't cache their manifest 557 // We store prefs about LOAD extensions, but don't cache their manifest
541 // since it may change on disk. 558 // since it may change on disk.
542 if (extension->location() != Extension::LOAD) { 559 if (extension->location() != Extension::LOAD) {
543 UpdateExtensionPref(id, kPrefManifest, 560 UpdateExtensionPref(id, kPrefManifest,
544 extension->manifest_value()->DeepCopy()); 561 extension->manifest_value()->DeepCopy());
545 } 562 }
546 UpdateExtensionPref(id, kPrefAppLaunchIndex, 563 UpdateExtensionPref(id, kPrefAppLaunchIndex,
547 Value::CreateIntegerValue(GetNextAppLaunchIndex())); 564 Value::CreateIntegerValue(GetNextAppLaunchIndex()));
548 SavePrefsAndNotify(); 565 SavePrefsAndNotify();
549 } 566 }
550 567
551 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, 568 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
552 const Extension::Location& location, 569 const Extension::Location& location,
553 bool external_uninstall) { 570 bool external_uninstall) {
571 PrefKeySet prefKeys;
572 GetExtensionControlledPrefKeys(extension_id, &prefKeys);
573
554 // For external extensions, we save a preference reminding ourself not to try 574 // For external extensions, we save a preference reminding ourself not to try
555 // and install the extension anymore (except when |external_uninstall| is 575 // and install the extension anymore (except when |external_uninstall| is
556 // true, which signifies that the registry key was deleted or the pref file 576 // true, which signifies that the registry key was deleted or the pref file
557 // no longer lists the extension). 577 // no longer lists the extension).
558 if (!external_uninstall && Extension::IsExternalLocation(location)) { 578 if (!external_uninstall && Extension::IsExternalLocation(location)) {
559 UpdateExtensionPref(extension_id, kPrefState, 579 UpdateExtensionPref(extension_id, kPrefState,
560 Value::CreateIntegerValue(Extension::KILLBIT)); 580 Value::CreateIntegerValue(Extension::KILLBIT));
561 SavePrefsAndNotify(); 581 SavePrefsAndNotify();
562 } else { 582 } else {
563 DeleteExtensionPrefs(extension_id); 583 DeleteExtensionPrefs(extension_id);
564 } 584 }
585
586 for (PrefKeySet::iterator i = prefKeys.begin(); i != prefKeys.end(); ++i)
587 UpdateWinningPref(*i);
565 } 588 }
566 589
567 Extension::State ExtensionPrefs::GetExtensionState( 590 Extension::State ExtensionPrefs::GetExtensionState(
568 const std::string& extension_id) { 591 const std::string& extension_id) const {
569 DictionaryValue* extension = GetExtensionPref(extension_id); 592 DictionaryValue* extension = GetExtensionPref(extension_id);
570 593
571 // If the extension doesn't have a pref, it's a --load-extension. 594 // If the extension doesn't have a pref, it's a --load-extension.
572 if (!extension) 595 if (!extension)
573 return Extension::ENABLED; 596 return Extension::ENABLED;
574 597
575 int state = -1; 598 int state = -1;
576 if (!extension->GetInteger(kPrefState, &state) || 599 if (!extension->GetInteger(kPrefState, &state) ||
577 state < 0 || state >= Extension::NUM_STATES) { 600 state < 0 || state >= Extension::NUM_STATES) {
578 LOG(ERROR) << "Bad or missing pref 'state' for extension '" 601 LOG(ERROR) << "Bad or missing pref 'state' for extension '"
579 << extension_id << "'"; 602 << extension_id << "'";
580 return Extension::ENABLED; 603 return Extension::ENABLED;
581 } 604 }
582 return static_cast<Extension::State>(state); 605 return static_cast<Extension::State>(state);
583 } 606 }
584 607
585 void ExtensionPrefs::SetExtensionState(const Extension* extension, 608 void ExtensionPrefs::SetExtensionState(const Extension* extension,
586 Extension::State state) { 609 Extension::State state) {
587 UpdateExtensionPref(extension->id(), kPrefState, 610 UpdateExtensionPref(extension->id(), kPrefState,
588 Value::CreateIntegerValue(state)); 611 Value::CreateIntegerValue(state));
612
613 PrefKeySet prefKeys;
614 GetExtensionControlledPrefKeys(extension->id(), &prefKeys);
615 for (PrefKeySet::iterator i = prefKeys.begin(); i != prefKeys.end(); ++i)
616 UpdateWinningPref(*i);
Aaron Boodman 2010/11/23 20:35:13 This pattern is repeated a few times. Factor out a
battre (please use the other) 2010/11/30 17:46:53 I think the pattern is repeated only twice (Update
617
589 SavePrefsAndNotify(); 618 SavePrefsAndNotify();
590 } 619 }
591 620
592 bool ExtensionPrefs::GetBrowserActionVisibility(const Extension* extension) { 621 bool ExtensionPrefs::GetBrowserActionVisibility(const Extension* extension) {
593 DictionaryValue* extension_prefs = GetExtensionPref(extension->id()); 622 DictionaryValue* extension_prefs = GetExtensionPref(extension->id());
594 bool visible = false; 623 bool visible = false;
595 if (!extension_prefs->GetBoolean(kBrowserActionVisible, &visible) || visible) 624 if (!extension_prefs->GetBoolean(kBrowserActionVisible, &visible) || visible)
596 return true; 625 return true;
597 626
598 return false; 627 return false;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 DictionaryValue* ExtensionPrefs::GetExtensionPref( 711 DictionaryValue* ExtensionPrefs::GetExtensionPref(
683 const std::string& extension_id) const { 712 const std::string& extension_id) const {
684 const DictionaryValue* dict = prefs_->GetDictionary(kExtensionsPref); 713 const DictionaryValue* dict = prefs_->GetDictionary(kExtensionsPref);
685 if (!dict) 714 if (!dict)
686 return NULL; 715 return NULL;
687 DictionaryValue* extension = NULL; 716 DictionaryValue* extension = NULL;
688 dict->GetDictionary(extension_id, &extension); 717 dict->GetDictionary(extension_id, &extension);
689 return extension; 718 return extension;
690 } 719 }
691 720
721 DictionaryValue* ExtensionPrefs::GetExtensionControlledPrefs(
722 const std::string& extension_id) const {
723 DictionaryValue* extension = GetExtensionPref(extension_id);
724 if (!extension)
725 return NULL;
726 DictionaryValue* preferences = NULL;
727 extension->GetDictionary(kPrefPreferences, &preferences);
728 return preferences;
729 }
730
692 // Helper function for GetInstalledExtensionsInfo. 731 // Helper function for GetInstalledExtensionsInfo.
693 static ExtensionInfo* GetInstalledExtensionInfoImpl( 732 static ExtensionInfo* GetInstalledExtensionInfoImpl(
694 DictionaryValue* extension_data, 733 DictionaryValue* extension_data,
695 DictionaryValue::key_iterator extension_id) { 734 DictionaryValue::key_iterator extension_id) {
696 DictionaryValue* ext; 735 DictionaryValue* ext;
697 if (!extension_data->GetDictionaryWithoutPathExpansion(*extension_id, &ext)) { 736 if (!extension_data->GetDictionaryWithoutPathExpansion(*extension_id, &ext)) {
698 LOG(WARNING) << "Invalid pref for extension " << *extension_id; 737 LOG(WARNING) << "Invalid pref for extension " << *extension_id;
699 NOTREACHED(); 738 NOTREACHED();
700 return NULL; 739 return NULL;
701 } 740 }
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 std::string ExtensionPrefs::GetUpdateUrlData(const std::string& extension_id) { 980 std::string ExtensionPrefs::GetUpdateUrlData(const std::string& extension_id) {
942 DictionaryValue* dictionary = GetExtensionPref(extension_id); 981 DictionaryValue* dictionary = GetExtensionPref(extension_id);
943 if (!dictionary) 982 if (!dictionary)
944 return std::string(); 983 return std::string();
945 984
946 std::string data; 985 std::string data;
947 dictionary->GetString(kUpdateUrlData, &data); 986 dictionary->GetString(kUpdateUrlData, &data);
948 return data; 987 return data;
949 } 988 }
950 989
990 base::Time ExtensionPrefs::GetCurrentTime() const {
991 return base::Time::Now();
992 }
993
994 base::Time ExtensionPrefs::GetInstallTime(const std::string& extension_id)
995 const {
Aaron Boodman 2010/11/23 20:35:13 Is the const indented on its own correct style? It
battre (please use the other) 2010/11/30 17:46:53 Done.
996 const DictionaryValue* extension = GetExtensionPref(extension_id);
997 if (!extension)
Aaron Boodman 2010/11/23 20:35:13 Do we intend for this to happen? If not, we should
battre (please use the other) 2010/11/30 17:46:53 Done. Added comment: // If the extension doesn't h
998 return base::Time::Time();
999 std::string install_time_str("0");
1000 extension->GetString(kPrefInstallTime, &install_time_str);
1001 int64 install_time_i64 = 0;
1002 base::StringToInt64(install_time_str, &install_time_i64);
1003 LOG_IF(ERROR, install_time_i64 == 0)
1004 << "Error parsing installation time of an extension.";
1005 return base::Time::FromInternalValue(install_time_i64);
1006 }
1007
1008 void ExtensionPrefs::GetEnabledExtensions(ExtensionIdSet* out) const {
1009 DCHECK(out);
1010 const DictionaryValue* extensions =
1011 pref_service()->GetDictionary(kExtensionsPref);
1012
1013 for (DictionaryValue::key_iterator ext_id = extensions->begin_keys();
1014 ext_id != extensions->end_keys(); ++ext_id) {
1015 if (GetExtensionState(*ext_id) != Extension::ENABLED)
1016 continue;
1017 out->push_back(*ext_id);
1018 }
1019 }
1020
1021 // Comparator that sorts extensions by their increasing installation time
1022 // or uses the extension id as a fall back for equal installation times.
1023 struct InstallTimeComparator {
1024 explicit InstallTimeComparator(ExtensionPrefs* ext_prefs)
1025 : ext_prefs_(ext_prefs) {}
1026
1027 bool operator()(std::string extid_a, std::string extid_b) {
1028 base::Time install_time_a = ext_prefs_->GetInstallTime(extid_a);
1029 base::Time install_time_b = ext_prefs_->GetInstallTime(extid_b);
1030 if (install_time_a == install_time_b)
1031 return extid_a < extid_b;
1032 return install_time_a < install_time_b;
1033 }
1034
1035 ExtensionPrefs* ext_prefs_; // Weak pointer.
1036 };
1037
1038 void ExtensionPrefs::FixMissingPrefs(const ExtensionIdSet& extension_ids) {
1039 // Fix old entries that did not get an installation time entry when they
1040 // were installed or don't have a preferences field.
1041 bool persistRequired = false;
1042 for (ExtensionIdSet::const_iterator ext_id = extension_ids.begin();
1043 ext_id != extension_ids.end(); ++ext_id) {
1044 DictionaryValue* extension = GetExtensionPref(*ext_id);
1045 CHECK(extension != NULL);
1046
1047 if (GetInstallTime(*ext_id) == base::Time::Time()) {
1048 const base::Time installTime = GetCurrentTime();
1049 extension->Set(kPrefInstallTime,
1050 Value::CreateStringValue(
1051 base::Int64ToString(installTime.ToInternalValue())));
1052 persistRequired = true;
1053 }
1054 }
1055 if (persistRequired) {
1056 SavePrefsAndNotify();
1057 }
1058 }
1059
1060 void ExtensionPrefs::InstallPersistedExtensionControlledPrefs() {
1061 // When this is called, the PrefService is initialized and provides access
1062 // to the user preferences stored in a JSON file. We take the persisted
1063 // preferences of all extensions, calculate the effective preferences
1064 // (considering that one extension overrides preferences of other extensions)
1065 // and store the effective preferences in the extension pref store.
1066 ExtensionIdSet extension_ids;
1067 GetEnabledExtensions(&extension_ids);
1068 FixMissingPrefs(extension_ids);
1069
1070 // Sort such that latest installed extension appears last.
1071 std::sort(extension_ids.begin(), extension_ids.end(),
1072 InstallTimeComparator(this));
1073
1074 // Collect all effective preferences (later ones override newer ones).
1075 DictionaryValue merged_non_expanded;
1076 for (ExtensionIdSet::iterator ext_id = extension_ids.begin();
1077 ext_id != extension_ids.end(); ++ext_id) {
1078 if (DictionaryValue* preferences = GetExtensionControlledPrefs(*ext_id))
1079 merged_non_expanded.MergeDictionary(preferences);
1080 }
1081
1082 // Expand all keys.
1083 PrefStore* extension_prefs =
1084 pref_service()->pref_value_store()->GetExtensionPrefStore();
1085 for (DictionaryValue::key_iterator prefkey = merged_non_expanded.begin_keys();
1086 prefkey != merged_non_expanded.end_keys();
1087 ++prefkey) {
1088 Value* value;
1089 CHECK(merged_non_expanded.GetWithoutPathExpansion(*prefkey, &value));
1090 extension_prefs->prefs()->Set(*prefkey, value->DeepCopy());
1091 }
1092 }
1093
1094 const Value* ExtensionPrefs::WinningExtensionControlledPrefValue(
1095 const std::string& key) const {
1096 Value *winner = NULL;
1097 base::Time winners_install_time = base::Time::Time();
1098
1099 ExtensionIdSet extension_ids;
1100 GetEnabledExtensions(&extension_ids);
1101 for (ExtensionIdSet::iterator ext_id = extension_ids.begin();
1102 ext_id != extension_ids.end(); ++ext_id) {
1103 base::Time extension_install_time = GetInstallTime(*ext_id);
1104
1105 // We do not need to consider extensions that were installed before the
1106 // most recent extension found that provides the requested preference.
1107 if (extension_install_time < winners_install_time)
1108 continue;
1109
1110 DictionaryValue* preferences = GetExtensionControlledPrefs(*ext_id);
1111 Value *value = NULL;
1112 if (preferences && preferences->GetWithoutPathExpansion(key, &value)) {
1113 // This extension is more recent than the last one providing this pref.
1114 winner = value;
1115 winners_install_time = extension_install_time;
1116 }
1117 }
1118
1119 return winner;
1120 }
1121
1122 void ExtensionPrefs::UpdateWinningPref(const std::string& pref_key) {
Aaron Boodman 2010/11/23 20:35:13 Trying to update the individual preference that ha
battre (please use the other) 2010/11/30 17:46:53 We could do this and DictionaryValue::GetDiffering
1123 PrefStore* extensionPrefStore =
Aaron Boodman 2010/11/23 20:35:13 Here, and many places in this file: Chromium uses
battre (please use the other) 2010/11/30 17:46:53 Done.
1124 pref_service()->pref_value_store()->GetExtensionPrefStore();
1125 const Value* winningPrefValue = WinningExtensionControlledPrefValue(pref_key);
1126 Value* oldValue = NULL;
1127 extensionPrefStore->prefs()->Get(pref_key, &oldValue);
1128 bool changed = !Value::Equals(winningPrefValue, oldValue);
1129
1130 if (winningPrefValue)
1131 extensionPrefStore->prefs()->Set(pref_key, winningPrefValue->DeepCopy());
1132 else
1133 extensionPrefStore->prefs()->Remove(pref_key, NULL);
1134
1135 if (changed)
1136 pref_service()->pref_notifier()->OnPreferenceSet(
1137 pref_key.c_str(), PrefNotifier::EXTENSION_STORE);
1138 }
1139
1140 void ExtensionPrefs::SetExtensionControlledPref(const std::string& extension_id,
1141 const std::string& pref_key,
1142 Value* value) {
1143 DictionaryValue* extensionPreferences =
1144 GetExtensionControlledPrefs(extension_id);
1145
1146 if (extensionPreferences == NULL) { // May be pruned when writing to disk.
1147 DictionaryValue* extension = GetExtensionPref(extension_id);
1148 extensionPreferences = new DictionaryValue;
1149 extension->Set(kPrefPreferences, extensionPreferences);
1150 }
1151
1152 Value* oldValue = NULL;
1153 extensionPreferences->GetWithoutPathExpansion(pref_key, &oldValue);
1154 bool modified = !Value::Equals(oldValue, value);
1155 if (!modified)
1156 return;
1157
1158 if (value == NULL)
1159 extensionPreferences->RemoveWithoutPathExpansion(pref_key, NULL);
1160 else
1161 extensionPreferences->SetWithoutPathExpansion(pref_key, value);
1162 pref_service()->ScheduleSavePersistentPrefs();
1163
1164 UpdateWinningPref(pref_key);
1165 }
1166
1167 void ExtensionPrefs::GetExtensionControlledPrefKeys(
1168 const std::string& extension_id, PrefKeySet *out) const {
1169 DCHECK(out != NULL);
1170 DictionaryValue* extPrefs = GetExtensionControlledPrefs(extension_id);
1171 if (extPrefs) {
1172 for (DictionaryValue::key_iterator i = extPrefs->begin_keys();
1173 i != extPrefs->end_keys(); ++i) {
1174 out->push_back(*i);
1175 }
1176 }
1177 }
1178
951 // static 1179 // static
952 void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) { 1180 void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) {
953 prefs->RegisterDictionaryPref(kExtensionsPref); 1181 prefs->RegisterDictionaryPref(kExtensionsPref);
954 prefs->RegisterListPref(kExtensionToolbar); 1182 prefs->RegisterListPref(kExtensionToolbar);
955 prefs->RegisterIntegerPref(prefs::kExtensionToolbarSize, -1); 1183 prefs->RegisterIntegerPref(prefs::kExtensionToolbarSize, -1);
956 prefs->RegisterDictionaryPref(kExtensionsBlacklistUpdate); 1184 prefs->RegisterDictionaryPref(kExtensionsBlacklistUpdate);
957 prefs->RegisterListPref(prefs::kExtensionInstallAllowList); 1185 prefs->RegisterListPref(prefs::kExtensionInstallAllowList);
958 prefs->RegisterListPref(prefs::kExtensionInstallDenyList); 1186 prefs->RegisterListPref(prefs::kExtensionInstallDenyList);
959 prefs->RegisterListPref(prefs::kExtensionInstallForceList); 1187 prefs->RegisterListPref(prefs::kExtensionInstallForceList);
960 prefs->RegisterStringPref(kWebStoreLogin, std::string() /* default_value */); 1188 prefs->RegisterStringPref(kWebStoreLogin, std::string() /* default_value */);
961 } 1189 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698