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

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: Lint issues and factored out renaming of InMemoryPrefStore 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";
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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 504
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 ExtensionPrefs::PrefKeySet ExtensionPrefs::GetToolbarOrder() {
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 Did you also fix callers of this function?
battre (please use the other) 2010/11/19 18:00:39 Reverted.
504 std::vector<std::string> extension_ids; 515 ExtensionPrefs::PrefKeySet extension_ids;
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 no need for the ExtensionPrefs qualifier in this l
battre (please use the other) 2010/11/19 18:00:39 Reverted.
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 PrefKeySet& extension_ids) {
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 Now fits the previous line!
battre (please use the other) 2010/11/19 18:00:39 Reverted.
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 (PrefKeySet::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());
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);
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 if (preferences == NULL) { // May be pruned when writing to disk.
729 preferences = new DictionaryValue;
730 extension->Set(kPrefPreferences, preferences);
731 }
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 I don't see why you add the empty dictionary here.
battre (please use the other) 2010/11/19 18:00:39 Done. (added a missing NULLity test for the change
732 return preferences;
733 }
734
692 // Helper function for GetInstalledExtensionsInfo. 735 // Helper function for GetInstalledExtensionsInfo.
693 static ExtensionInfo* GetInstalledExtensionInfoImpl( 736 static ExtensionInfo* GetInstalledExtensionInfoImpl(
694 DictionaryValue* extension_data, 737 DictionaryValue* extension_data,
695 DictionaryValue::key_iterator extension_id) { 738 DictionaryValue::key_iterator extension_id) {
696 DictionaryValue* ext; 739 DictionaryValue* ext;
697 if (!extension_data->GetDictionaryWithoutPathExpansion(*extension_id, &ext)) { 740 if (!extension_data->GetDictionaryWithoutPathExpansion(*extension_id, &ext)) {
698 LOG(WARNING) << "Invalid pref for extension " << *extension_id; 741 LOG(WARNING) << "Invalid pref for extension " << *extension_id;
699 NOTREACHED(); 742 NOTREACHED();
700 return NULL; 743 return NULL;
701 } 744 }
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 std::string ExtensionPrefs::GetUpdateUrlData(const std::string& extension_id) { 984 std::string ExtensionPrefs::GetUpdateUrlData(const std::string& extension_id) {
942 DictionaryValue* dictionary = GetExtensionPref(extension_id); 985 DictionaryValue* dictionary = GetExtensionPref(extension_id);
943 if (!dictionary) 986 if (!dictionary)
944 return std::string(); 987 return std::string();
945 988
946 std::string data; 989 std::string data;
947 dictionary->GetString(kUpdateUrlData, &data); 990 dictionary->GetString(kUpdateUrlData, &data);
948 return data; 991 return data;
949 } 992 }
950 993
994 base::Time ExtensionPrefs::GetCurrentTime() const {
995 return base::Time::Now();
996 }
997
998 base::Time ExtensionPrefs::GetInstallTime(const std::string& extension_id)
999 const {
1000 const DictionaryValue* extension = GetExtensionPref(extension_id);
1001 if (!extension)
1002 return base::Time::FromInternalValue(0);
1003 std::string install_time_str("0");
1004 extension->GetString(kPrefInstallTime, &install_time_str);
1005 int64 install_time_i64 = 0;
1006 base::StringToInt64(install_time_str, &install_time_i64);
1007 LOG_IF(ERROR, install_time_i64 == 0)
1008 << "Error parsing installation time of an extension.";
1009 return base::Time::FromInternalValue(install_time_i64);
1010 }
1011
1012 void ExtensionPrefs::GetEnabledExtensions(ExtensionIdSet* out) const {
1013 DCHECK(out);
1014 const DictionaryValue* extensions =
1015 pref_service()->GetDictionary(kExtensionsPref);
1016
1017 for (DictionaryValue::key_iterator ext_id = extensions->begin_keys();
1018 ext_id != extensions->end_keys(); ++ext_id) {
1019 if (GetExtensionState(*ext_id) != Extension::ENABLED)
1020 continue;
1021 out->push_back(*ext_id);
1022 }
1023 }
1024
1025 // Comparator that sorts extensions by their increasing installation time
1026 // or uses the extension id as a fall back for equal installation times.
1027 struct InstallTimeComparator {
1028 explicit InstallTimeComparator(ExtensionPrefs* ext_prefs)
1029 : ext_prefs_(ext_prefs) {}
1030
1031 bool operator()(std::string extid_a, std::string extid_b) {
1032 base::Time install_time_a = ext_prefs_->GetInstallTime(extid_a);
1033 base::Time install_time_b = ext_prefs_->GetInstallTime(extid_b);
1034 if (install_time_a == install_time_b)
1035 return extid_a < extid_b;
1036 return install_time_a < install_time_b;
1037 }
1038
1039 ExtensionPrefs* ext_prefs_; // Weak pointer.
1040 };
1041
1042 void ExtensionPrefs::FixMissingPrefs(const ExtensionIdSet& extension_ids) {
1043 // Fix old entries that did not get an installation time entry when they
1044 // were installed or don't have a preferences field.
1045 bool persistRequired = false;
1046 for (ExtensionIdSet::const_iterator ext_id = extension_ids.begin();
1047 ext_id != extension_ids.end(); ++ext_id) {
1048 DictionaryValue* extension = GetExtensionPref(*ext_id);
1049 CHECK(extension != NULL);
1050
1051 if (GetInstallTime(*ext_id) == base::Time::FromInternalValue(0)) {
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 base::Time::FromInternalValue(0) == base::Time()
battre (please use the other) 2010/11/19 18:00:39 Done.
1052 const base::Time installTime = GetCurrentTime();
1053 extension->Set(kPrefInstallTime,
1054 Value::CreateStringValue(
1055 base::Int64ToString(installTime.ToInternalValue())));
1056 }
1057 }
1058 if (persistRequired) {
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 AFAICS, persistRequired is always false. Does that
battre (please use the other) 2010/11/19 18:00:39 Done.
1059 SavePrefsAndNotify();
1060 }
1061 }
1062
1063 void ExtensionPrefs::InstallPersistedExtensionControlledPrefs() {
1064 // When this is called, the PrefService is initialized and provides access
1065 // to the user preferences stored in a JSON file. We take the persisted
1066 // preferences of all extensions, calculate the effective preferences
1067 // (considering that one extension overrides preferences of other extensions)
1068 // and store the effective preferences in the PrefService.
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 Maybe say "extension pref store" instead of PrefSe
battre (please use the other) 2010/11/19 18:00:39 Done.
1069 ExtensionIdSet extension_ids;
1070 GetEnabledExtensions(&extension_ids);
1071 FixMissingPrefs(extension_ids);
1072
1073 // Sort such that latest installed extension appears last.
1074 std::sort(extension_ids.begin(), extension_ids.end(),
1075 InstallTimeComparator(this));
1076
1077 // Collect all effective preferences (later ones override newer ones).
1078 DictionaryValue merged_non_expanded;
1079 for (ExtensionIdSet::iterator ext_id = extension_ids.begin();
1080 ext_id != extension_ids.end(); ++ext_id) {
1081 if (DictionaryValue* preferences = GetExtensionControlledPrefs(*ext_id))
1082 merged_non_expanded.MergeDictionary(preferences);
1083 }
1084
1085 // Expand all keys.
1086 PrefStore* extension_prefs =
1087 pref_service()->pref_value_store()->GetExtensionPrefStore();
1088 for (DictionaryValue::key_iterator prefkey =
1089 merged_non_expanded.begin_keys();
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 Doesn't this fit the previous line?
battre (please use the other) 2010/11/19 18:00:39 80 characters on the spot. :-) Done.
1090 prefkey != merged_non_expanded.end_keys();
1091 ++prefkey) {
1092 Value* value;
1093 CHECK(merged_non_expanded.GetWithoutPathExpansion(*prefkey, &value));
1094 extension_prefs->prefs()->Set(*prefkey, value->DeepCopy());
1095 }
1096 }
1097
1098 static bool equalValues(const Value* a, const Value* b) {
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 Any reason, why you didn't move this to base/value
battre (please use the other) 2010/11/19 18:00:39 Respect for modifying the holy base classes. ;-)
1099 return a == NULL ? b == NULL : a->Equals(b);
1100 }
1101
1102 const Value* ExtensionPrefs::WinningExtensionControlledPrefValue(
1103 const std::string& key) const {
1104 Value *winner = NULL;
1105 base::Time winners_install_time = base::Time::FromInternalValue(0);
1106
1107 ExtensionIdSet extension_ids;
1108 GetEnabledExtensions(&extension_ids);
1109 for (ExtensionIdSet::iterator ext_id = extension_ids.begin();
1110 ext_id != extension_ids.end(); ++ext_id) {
1111 base::Time extension_install_time = GetInstallTime(*ext_id);
1112
1113 // We do not need to consider extensions that were installed before the
1114 // most recent extension found that provides the requested preference.
1115 if (extension_install_time < winners_install_time)
1116 continue;
1117
1118 DictionaryValue* preferences = GetExtensionControlledPrefs(*ext_id);
1119 Value *value = NULL;
1120 if (preferences && preferences->GetWithoutPathExpansion(key, &value)) {
1121 // This extension is more recent than the last one providing this pref.
1122 winner = value;
1123 winners_install_time = extension_install_time;
1124 }
1125 }
1126
1127 return winner;
1128 }
1129
1130 void ExtensionPrefs::UpdateWinningPref(const std::string& pref_key) {
1131 PrefStore* extensionPrefStore =
1132 pref_service()->pref_value_store()->GetExtensionPrefStore();
1133 const Value* winningPrefValue = WinningExtensionControlledPrefValue(pref_key);
1134 // TODO(battre): the following lines should go into a function of the
1135 // PrefStores, which requires that they have a pointer to the pref_notifier.
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 s/PrefStores/InMemoryPrefStore/. I'm not too sure
battre (please use the other) 2010/11/19 18:00:39 Removed the comment. It would be a major refactori
1136 Value* oldValue = NULL;
1137 extensionPrefStore->prefs()->Get(pref_key, &oldValue);
1138 bool changed = !equalValues(winningPrefValue, oldValue);
1139
1140 if (winningPrefValue) {
1141 extensionPrefStore->prefs()->Set(pref_key, winningPrefValue->DeepCopy());
1142 } else {
1143 extensionPrefStore->prefs()->Remove(pref_key, NULL);
1144 }
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 Non need for curlies, but keep them if you like th
battre (please use the other) 2010/11/19 18:00:39 Done.
1145
1146 if (changed)
1147 pref_service()->pref_notifier()->OnPreferenceSet(
1148 pref_key.c_str(), PrefNotifier::EXTENSION_STORE);
1149 }
1150
1151 void ExtensionPrefs::SetExtensionControlledPref(const std::string& extension_id,
1152 const std::string& pref_key,
1153 Value* value) {
1154 DictionaryValue* extensionPreferences =
1155 GetExtensionControlledPrefs(extension_id);
1156
1157 Value* oldValue = NULL;
1158 extensionPreferences->GetWithoutPathExpansion(pref_key, &oldValue);
1159 bool modified = !equalValues(oldValue, value);
1160 if (!modified)
1161 return;
1162
1163 if (value == NULL)
1164 extensionPreferences->RemoveWithoutPathExpansion(pref_key, NULL);
1165 else
1166 extensionPreferences->SetWithoutPathExpansion(pref_key, value);
Mattias Nissler (ping if slow) 2010/11/19 16:52:20 Well, if there are no curlies here, you shouldn't
battre (please use the other) 2010/11/19 18:00:39 Done.
1167 pref_service()->ScheduleSavePersistentPrefs();
1168
1169 UpdateWinningPref(pref_key);
1170 }
1171
1172 void ExtensionPrefs::GetExtensionControlledPrefKeys(
1173 const std::string& extension_id, PrefKeySet *out) const {
1174 DCHECK(out != NULL);
1175 DictionaryValue* extPrefs = GetExtensionControlledPrefs(extension_id);
1176 if (extPrefs) {
1177 for (DictionaryValue::key_iterator i = extPrefs->begin_keys();
1178 i != extPrefs->end_keys(); ++i) {
1179 out->push_back(*i);
1180 }
1181 }
1182 }
1183
951 // static 1184 // static
952 void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) { 1185 void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) {
953 prefs->RegisterDictionaryPref(kExtensionsPref); 1186 prefs->RegisterDictionaryPref(kExtensionsPref);
954 prefs->RegisterListPref(kExtensionToolbar); 1187 prefs->RegisterListPref(kExtensionToolbar);
955 prefs->RegisterIntegerPref(prefs::kExtensionToolbarSize, -1); 1188 prefs->RegisterIntegerPref(prefs::kExtensionToolbarSize, -1);
956 prefs->RegisterDictionaryPref(kExtensionsBlacklistUpdate); 1189 prefs->RegisterDictionaryPref(kExtensionsBlacklistUpdate);
957 prefs->RegisterListPref(prefs::kExtensionInstallAllowList); 1190 prefs->RegisterListPref(prefs::kExtensionInstallAllowList);
958 prefs->RegisterListPref(prefs::kExtensionInstallDenyList); 1191 prefs->RegisterListPref(prefs::kExtensionInstallDenyList);
959 prefs->RegisterListPref(prefs::kExtensionInstallForceList); 1192 prefs->RegisterListPref(prefs::kExtensionInstallForceList);
960 prefs->RegisterStringPref(kWebStoreLogin, std::string() /* default_value */); 1193 prefs->RegisterStringPref(kWebStoreLogin, std::string() /* default_value */);
961 } 1194 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698