OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/browser/extensions/extension_pref_store.h" | 10 #include "chrome/browser/extensions/extension_pref_store.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 103 |
104 // A preference set by the web store to indicate login information for | 104 // A preference set by the web store to indicate login information for |
105 // purchased apps. | 105 // purchased apps. |
106 const char kWebStoreLogin[] = "extensions.webstore_login"; | 106 const char kWebStoreLogin[] = "extensions.webstore_login"; |
107 | 107 |
108 // A preference set by the the NTP to persist the desired launch container type | 108 // A preference set by the the NTP to persist the desired launch container type |
109 // used for apps. | 109 // used for apps. |
110 const char kPrefLaunchType[] = "launchType"; | 110 const char kPrefLaunchType[] = "launchType"; |
111 | 111 |
112 // A preference determining the order of which the apps appear on the NTP. | 112 // A preference determining the order of which the apps appear on the NTP. |
113 const char kPrefAppLaunchIndex[] = "app_launcher_index"; | 113 const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index"; |
| 114 const char kPrefAppLaunchOrdinal[] = "app_launcher_ordinal"; |
114 | 115 |
115 // A preference determining the page on which an app appears in the NTP. | 116 // A preference determining the page on which an app appears in the NTP. |
116 const char kPrefPageIndex[] = "page_index"; | 117 const char kPrefPageIndexDeprecated[] = "page_index"; |
| 118 const char kPrefPageOrdinal[] = "page_ordinal"; |
117 | 119 |
118 // A preference specifying if the user dragged the app on the NTP. | 120 // A preference specifying if the user dragged the app on the NTP. |
119 const char kPrefUserDraggedApp[] = "user_dragged_app_ntp"; | 121 const char kPrefUserDraggedApp[] = "user_dragged_app_ntp"; |
120 | 122 |
121 // A preference for storing extra data sent in update checks for an extension. | 123 // A preference for storing extra data sent in update checks for an extension. |
122 const char kUpdateUrlData[] = "update_url_data"; | 124 const char kUpdateUrlData[] = "update_url_data"; |
123 | 125 |
124 // Whether the browser action is visible in the toolbar. | 126 // Whether the browser action is visible in the toolbar. |
125 const char kBrowserActionVisible[] = "browser_action_visible"; | 127 const char kBrowserActionVisible[] = "browser_action_visible"; |
126 | 128 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 const std::string extension_id_; | 234 const std::string extension_id_; |
233 const std::string incognito_or_regular_path_; | 235 const std::string incognito_or_regular_path_; |
234 | 236 |
235 DISALLOW_COPY_AND_ASSIGN(ScopedExtensionControlledPrefUpdate); | 237 DISALLOW_COPY_AND_ASSIGN(ScopedExtensionControlledPrefUpdate); |
236 }; | 238 }; |
237 | 239 |
238 std::string JoinPrefs(std::string parent, const char* child) { | 240 std::string JoinPrefs(std::string parent, const char* child) { |
239 return parent + "." + child; | 241 return parent + "." + child; |
240 } | 242 } |
241 | 243 |
| 244 // A simple structure used when sorting applications based on their app launch |
| 245 // index. This is used by the code that migrates the data from integers to |
| 246 // StringOrdinals. |
| 247 struct ApplicationNTPOldAppLaunch { |
| 248 const std::string* application_id; |
| 249 const int app_launch_index; |
| 250 |
| 251 ApplicationNTPOldAppLaunch() : application_id(0), |
| 252 app_launch_index(0) {} |
| 253 |
| 254 ApplicationNTPOldAppLaunch(const std::string& app_id, int app_launch) |
| 255 : application_id(&app_id), |
| 256 app_launch_index(app_launch) {} |
| 257 }; |
| 258 |
| 259 struct SortByNTPOldAppLaunch { |
| 260 bool operator() (const ApplicationNTPOldAppLaunch& lhs, |
| 261 const ApplicationNTPOldAppLaunch& rhs) const { |
| 262 return lhs.app_launch_index < rhs.app_launch_index; |
| 263 } |
| 264 }; |
| 265 |
242 } // namespace | 266 } // namespace |
243 | 267 |
244 ExtensionPrefs::ExtensionPrefs( | 268 ExtensionPrefs::ExtensionPrefs( |
245 PrefService* prefs, | 269 PrefService* prefs, |
246 const FilePath& root_dir, | 270 const FilePath& root_dir, |
247 ExtensionPrefValueMap* extension_pref_value_map) | 271 ExtensionPrefValueMap* extension_pref_value_map) |
248 : prefs_(prefs), | 272 : prefs_(prefs), |
249 install_directory_(root_dir), | 273 install_directory_(root_dir), |
250 extension_pref_value_map_(extension_pref_value_map), | 274 extension_pref_value_map_(extension_pref_value_map), |
251 content_settings_store_(new ExtensionContentSettingsStore()) { | 275 content_settings_store_(new ExtensionContentSettingsStore()) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 const DictionaryValue* ext = GetExtensionPref(extension_id); | 432 const DictionaryValue* ext = GetExtensionPref(extension_id); |
409 ListValue* out = NULL; | 433 ListValue* out = NULL; |
410 if (!ext || !ext->GetList(pref_key, &out)) | 434 if (!ext || !ext->GetList(pref_key, &out)) |
411 return false; | 435 return false; |
412 if (out_value) | 436 if (out_value) |
413 *out_value = out; | 437 *out_value = out; |
414 | 438 |
415 return true; | 439 return true; |
416 } | 440 } |
417 | 441 |
| 442 bool ExtensionPrefs::ReadExtensionPrefString( |
| 443 const std::string& extension_id, const std::string& pref_key, |
| 444 std::string* out_value) const { |
| 445 const DictionaryValue* ext = GetExtensionPref(extension_id); |
| 446 |
| 447 if (!ext || !ext->GetString(pref_key, out_value)) |
| 448 return false; |
| 449 |
| 450 return true; |
| 451 } |
| 452 |
418 bool ExtensionPrefs::ReadExtensionPrefURLPatternSet( | 453 bool ExtensionPrefs::ReadExtensionPrefURLPatternSet( |
419 const std::string& extension_id, | 454 const std::string& extension_id, |
420 const std::string& pref_key, | 455 const std::string& pref_key, |
421 URLPatternSet* result, | 456 URLPatternSet* result, |
422 int valid_schemes) { | 457 int valid_schemes) { |
423 const ListValue* value = NULL; | 458 const ListValue* value = NULL; |
424 if (!ReadExtensionPrefList(extension_id, pref_key, &value)) | 459 if (!ReadExtensionPrefList(extension_id, pref_key, &value)) |
425 return false; | 460 return false; |
426 | 461 |
427 result->ClearPatterns(); | 462 result->ClearPatterns(); |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 if (ext->GetList(kPrefOldGrantedHosts, &hosts)) { | 886 if (ext->GetList(kPrefOldGrantedHosts, &hosts)) { |
852 UpdateExtensionPref( | 887 UpdateExtensionPref( |
853 *ext_id, explicit_hosts, hosts->DeepCopy()); | 888 *ext_id, explicit_hosts, hosts->DeepCopy()); |
854 | 889 |
855 // We can get rid of the old one by setting it to an empty list. | 890 // We can get rid of the old one by setting it to an empty list. |
856 UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new ListValue()); | 891 UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new ListValue()); |
857 } | 892 } |
858 } | 893 } |
859 } | 894 } |
860 | 895 |
| 896 void ExtensionPrefs::MigrateAppIndex(const ExtensionIdSet& extension_ids) { |
| 897 if (extension_ids.empty()) |
| 898 return; |
| 899 |
| 900 // Convert all the page index values to page ordinals. If there are any |
| 901 // app launch values that need to be migrated, inserted them into a sorted |
| 902 // set to be dealt with later. |
| 903 std::multiset<ApplicationNTPOldAppLaunch, SortByNTPOldAppLaunch> |
| 904 app_launches_to_convert; |
| 905 for (ExtensionIdSet::const_iterator ext_id = extension_ids.begin(); |
| 906 ext_id != extension_ids.end(); ++ext_id) { |
| 907 int old_page_index = 0; |
| 908 if (ReadExtensionPrefInteger(*ext_id, |
| 909 kPrefPageIndexDeprecated, |
| 910 &old_page_index)) { |
| 911 SetPageOrdinal(*ext_id, PageIntegerAsStringOrdinal(old_page_index)); |
| 912 UpdateExtensionPref(*ext_id, kPrefPageIndexDeprecated, NULL); |
| 913 } |
| 914 |
| 915 int old_app_launch_index = 0; |
| 916 if (ReadExtensionPrefInteger(*ext_id, |
| 917 kPrefAppLaunchIndexDeprecated, |
| 918 &old_app_launch_index)) { |
| 919 // We can't update the app launch index value yet, because we use |
| 920 // GetNextAppLaunchOrdinal to get the new ordinal value and it requires |
| 921 // all the ordinals with lower values to have already been migrated. |
| 922 app_launches_to_convert.insert(ApplicationNTPOldAppLaunch( |
| 923 *ext_id, |
| 924 old_app_launch_index)); |
| 925 UpdateExtensionPref(*ext_id, kPrefAppLaunchIndexDeprecated, NULL); |
| 926 } |
| 927 } |
| 928 |
| 929 if (app_launches_to_convert.empty()) |
| 930 return; |
| 931 |
| 932 // Create the new app launch ordinals and remove the old preferences. Since |
| 933 // the set is sorted, each time we migrate an apps index, we know that all of |
| 934 // the remaining apps will appear further down the NTP than it or on a |
| 935 // different page. |
| 936 for (std::multiset<ApplicationNTPOldAppLaunch, SortByNTPOldAppLaunch> |
| 937 ::const_iterator ext = app_launches_to_convert.begin(); |
| 938 ext != app_launches_to_convert.end(); ++ext) { |
| 939 StringOrdinal page = GetPageOrdinal(*(ext->application_id)); |
| 940 if (!page.IsValid()) { |
| 941 page = GetNaturalAppPageOrdinal(); |
| 942 SetPageOrdinal(*(ext->application_id), page); |
| 943 } |
| 944 |
| 945 SetAppLaunchOrdinal(*(ext->application_id), |
| 946 GetNextAppLaunchOrdinal(page)); |
| 947 } |
| 948 } |
| 949 |
861 ExtensionPermissionSet* ExtensionPrefs::GetGrantedPermissions( | 950 ExtensionPermissionSet* ExtensionPrefs::GetGrantedPermissions( |
862 const std::string& extension_id) { | 951 const std::string& extension_id) { |
863 CHECK(Extension::IdIsValid(extension_id)); | 952 CHECK(Extension::IdIsValid(extension_id)); |
864 return ReadExtensionPrefPermissionSet(extension_id, kPrefGrantedPermissions); | 953 return ReadExtensionPrefPermissionSet(extension_id, kPrefGrantedPermissions); |
865 } | 954 } |
866 | 955 |
867 void ExtensionPrefs::AddGrantedPermissions( | 956 void ExtensionPrefs::AddGrantedPermissions( |
868 const std::string& extension_id, | 957 const std::string& extension_id, |
869 const ExtensionPermissionSet* permissions) { | 958 const ExtensionPermissionSet* permissions) { |
870 CHECK(Extension::IdIsValid(extension_id)); | 959 CHECK(Extension::IdIsValid(extension_id)); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 ListPrefUpdate update(prefs_, kExtensionToolbar); | 1150 ListPrefUpdate update(prefs_, kExtensionToolbar); |
1062 ListValue* toolbar_order = update.Get(); | 1151 ListValue* toolbar_order = update.Get(); |
1063 toolbar_order->Clear(); | 1152 toolbar_order->Clear(); |
1064 for (std::vector<std::string>::const_iterator iter = extension_ids.begin(); | 1153 for (std::vector<std::string>::const_iterator iter = extension_ids.begin(); |
1065 iter != extension_ids.end(); ++iter) { | 1154 iter != extension_ids.end(); ++iter) { |
1066 toolbar_order->Append(new StringValue(*iter)); | 1155 toolbar_order->Append(new StringValue(*iter)); |
1067 } | 1156 } |
1068 SavePrefs(); | 1157 SavePrefs(); |
1069 } | 1158 } |
1070 | 1159 |
| 1160 void ExtensionPrefs::SetAppOrdinalValues(DictionaryValue* extension_dict, |
| 1161 const StringOrdinal& page_ordinal) { |
| 1162 extension_dict->Set(kPrefPageOrdinal, |
| 1163 Value::CreateStringValue(page_ordinal.ToString())); |
| 1164 UpdatePageOrdinalMap(StringOrdinal(), page_ordinal); |
| 1165 |
| 1166 extension_dict->Set(kPrefAppLaunchOrdinal, |
| 1167 Value::CreateStringValue( |
| 1168 GetNextAppLaunchOrdinal(page_ordinal).ToString())); |
| 1169 } |
| 1170 |
1071 void ExtensionPrefs::OnExtensionInstalled( | 1171 void ExtensionPrefs::OnExtensionInstalled( |
1072 const Extension* extension, | 1172 const Extension* extension, |
1073 Extension::State initial_state, | 1173 Extension::State initial_state, |
1074 bool from_webstore, | 1174 bool from_webstore, |
1075 int page_index) { | 1175 const StringOrdinal& page_ordinal) { |
1076 const std::string& id = extension->id(); | 1176 const std::string& id = extension->id(); |
1077 CHECK(Extension::IdIsValid(id)); | 1177 CHECK(Extension::IdIsValid(id)); |
1078 ScopedExtensionPrefUpdate update(prefs_, id); | 1178 ScopedExtensionPrefUpdate update(prefs_, id); |
1079 DictionaryValue* extension_dict = update.Get(); | 1179 DictionaryValue* extension_dict = update.Get(); |
1080 const base::Time install_time = GetCurrentTime(); | 1180 const base::Time install_time = GetCurrentTime(); |
1081 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); | 1181 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); |
1082 extension_dict->Set(kPrefLocation, | 1182 extension_dict->Set(kPrefLocation, |
1083 Value::CreateIntegerValue(extension->location())); | 1183 Value::CreateIntegerValue(extension->location())); |
1084 extension_dict->Set(kPrefFromWebStore, | 1184 extension_dict->Set(kPrefFromWebStore, |
1085 Value::CreateBooleanValue(from_webstore)); | 1185 Value::CreateBooleanValue(from_webstore)); |
(...skipping 11 matching lines...) Expand all Loading... |
1097 extension->path()); | 1197 extension->path()); |
1098 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); | 1198 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); |
1099 // We store prefs about LOAD extensions, but don't cache their manifest | 1199 // We store prefs about LOAD extensions, but don't cache their manifest |
1100 // since it may change on disk. | 1200 // since it may change on disk. |
1101 if (extension->location() != Extension::LOAD) { | 1201 if (extension->location() != Extension::LOAD) { |
1102 extension_dict->Set(kPrefManifest, | 1202 extension_dict->Set(kPrefManifest, |
1103 extension->manifest_value()->DeepCopy()); | 1203 extension->manifest_value()->DeepCopy()); |
1104 } | 1204 } |
1105 | 1205 |
1106 if (extension->is_app()) { | 1206 if (extension->is_app()) { |
1107 if (page_index == -1) | 1207 if (page_ordinal.IsValid()) |
1108 page_index = GetNaturalAppPageIndex(); | 1208 SetAppOrdinalValues(extension_dict, page_ordinal); |
1109 extension_dict->Set(kPrefPageIndex, | 1209 else |
1110 Value::CreateIntegerValue(page_index)); | 1210 SetAppOrdinalValues(extension_dict, GetNaturalAppPageOrdinal()); |
1111 extension_dict->Set(kPrefAppLaunchIndex, | |
1112 Value::CreateIntegerValue(GetNextAppLaunchIndex(page_index))); | |
1113 } | 1211 } |
| 1212 |
1114 extension_pref_value_map_->RegisterExtension( | 1213 extension_pref_value_map_->RegisterExtension( |
1115 id, install_time, initial_state == Extension::ENABLED); | 1214 id, install_time, initial_state == Extension::ENABLED); |
1116 content_settings_store_->RegisterExtension( | 1215 content_settings_store_->RegisterExtension( |
1117 id, install_time, initial_state == Extension::ENABLED); | 1216 id, install_time, initial_state == Extension::ENABLED); |
1118 } | 1217 } |
1119 | 1218 |
1120 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, | 1219 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, |
1121 const Extension::Location& location, | 1220 const Extension::Location& location, |
1122 bool external_uninstall) { | 1221 bool external_uninstall) { |
1123 // For external extensions, we save a preference reminding ourself not to try | 1222 // For external extensions, we save a preference reminding ourself not to try |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 return true; | 1534 return true; |
1436 } | 1535 } |
1437 return false; | 1536 return false; |
1438 } | 1537 } |
1439 | 1538 |
1440 void ExtensionPrefs::SetWebStoreLogin(const std::string& login) { | 1539 void ExtensionPrefs::SetWebStoreLogin(const std::string& login) { |
1441 prefs_->SetString(kWebStoreLogin, login); | 1540 prefs_->SetString(kWebStoreLogin, login); |
1442 SavePrefs(); | 1541 SavePrefs(); |
1443 } | 1542 } |
1444 | 1543 |
1445 int ExtensionPrefs::GetAppLaunchIndex(const std::string& extension_id) { | 1544 bool ExtensionPrefs::GetMaxAndMinAppLaunchOrdinalsOnPage( |
1446 int value; | 1545 const StringOrdinal& target_page_ordinal, |
1447 if (ReadExtensionPrefInteger(extension_id, kPrefAppLaunchIndex, &value)) | 1546 StringOrdinal* min_app_launch_value, |
1448 return value; | 1547 StringOrdinal* max_app_launch_value) const { |
| 1548 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
| 1549 CHECK(extensions); |
| 1550 CHECK(target_page_ordinal.IsValid()); |
| 1551 CHECK(min_app_launch_value); |
| 1552 CHECK(max_app_launch_value); |
1449 | 1553 |
1450 return -1; | 1554 StringOrdinal* min_value = NULL; |
| 1555 StringOrdinal* max_value = NULL; |
| 1556 for (DictionaryValue::key_iterator ext_it = extensions->begin_keys(); |
| 1557 ext_it != extensions->end_keys(); ++ext_it) { |
| 1558 StringOrdinal page_ordinal = GetPageOrdinal(*ext_it); |
| 1559 if (page_ordinal.IsValid() && page_ordinal.Equal(target_page_ordinal)) { |
| 1560 StringOrdinal app_launch_ordinal = GetAppLaunchOrdinal(*ext_it); |
| 1561 if (app_launch_ordinal.IsValid()) { |
| 1562 if (min_value == NULL || !min_value->IsValid() || |
| 1563 app_launch_ordinal.LessThan(*min_value)) |
| 1564 min_value = &app_launch_ordinal; |
| 1565 |
| 1566 if (max_value == NULL || !max_value->IsValid() || |
| 1567 max_value->LessThan(app_launch_ordinal)) |
| 1568 max_value = &app_launch_ordinal; |
| 1569 } |
| 1570 } |
| 1571 } |
| 1572 |
| 1573 if (min_value != NULL) |
| 1574 *min_app_launch_value = *min_value; |
| 1575 if (max_value != NULL) |
| 1576 *max_app_launch_value = *max_value; |
| 1577 |
| 1578 // If |min_app_launch_value| is valid then we had at least 1 app on the page, |
| 1579 // so both positions are valid. |
| 1580 return min_app_launch_value->IsValid(); |
1451 } | 1581 } |
1452 | 1582 |
1453 void ExtensionPrefs::SetAppLaunchIndex(const std::string& extension_id, | 1583 StringOrdinal ExtensionPrefs::GetFirstAppPage() const { |
1454 int index) { | 1584 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
1455 UpdateExtensionPref(extension_id, kPrefAppLaunchIndex, | 1585 CHECK(extensions); |
1456 Value::CreateIntegerValue(index)); | 1586 |
| 1587 if (page_ordinal_map_.empty()) |
| 1588 return StringOrdinal::CreateInitialOrdinal(); |
| 1589 |
| 1590 return page_ordinal_map_.begin()->first; |
1457 } | 1591 } |
1458 | 1592 |
1459 int ExtensionPrefs::GetNextAppLaunchIndex(int on_page) { | 1593 StringOrdinal ExtensionPrefs::CreateFirstAppLaunchOrdinal( |
1460 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); | 1594 const StringOrdinal& page_ordinal) const { |
1461 if (!extensions) | 1595 StringOrdinal max_ordinal; |
1462 return 0; | 1596 StringOrdinal min_ordinal; |
| 1597 GetMaxAndMinAppLaunchOrdinalsOnPage(page_ordinal, &min_ordinal, &max_ordinal); |
1463 | 1598 |
1464 int max_value = -1; | 1599 if (min_ordinal.IsValid()) |
1465 for (DictionaryValue::key_iterator extension_id = extensions->begin_keys(); | 1600 return min_ordinal.CreateBefore(); |
1466 extension_id != extensions->end_keys(); ++extension_id) { | 1601 else |
1467 int value = GetAppLaunchIndex(*extension_id); | 1602 return StringOrdinal::CreateInitialOrdinal(); |
1468 int page = GetPageIndex(*extension_id); | |
1469 if (page == on_page && value > max_value) | |
1470 max_value = value; | |
1471 } | |
1472 return max_value + 1; | |
1473 } | 1603 } |
1474 | 1604 |
1475 int ExtensionPrefs::GetNaturalAppPageIndex() { | 1605 StringOrdinal ExtensionPrefs::GetAppLaunchOrdinal( |
1476 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); | 1606 const std::string& extension_id) const { |
1477 if (!extensions) | 1607 std::string raw_value; |
1478 return 0; | 1608 // If the preference read fails then raw_value will still be unset and we |
1479 | 1609 // will return an invalid StringOrdinal to signal that no app launch ordinal |
1480 std::map<int, int> page_counts; | 1610 // was found. |
1481 for (DictionaryValue::key_iterator extension_id = extensions->begin_keys(); | 1611 ReadExtensionPrefString(extension_id, kPrefAppLaunchOrdinal, &raw_value); |
1482 extension_id != extensions->end_keys(); ++extension_id) { | 1612 return StringOrdinal(raw_value); |
1483 int page_index = GetPageIndex(*extension_id); | |
1484 if (page_index >= 0) | |
1485 page_counts[page_index] = page_counts[page_index] + 1; | |
1486 } | |
1487 for (int i = 0; ; i++) { | |
1488 std::map<int, int>::const_iterator it = page_counts.find(i); | |
1489 if (it == page_counts.end() || it->second < kNaturalAppPageSize) | |
1490 return i; | |
1491 } | |
1492 } | 1613 } |
1493 | 1614 |
1494 void ExtensionPrefs::SetAppLauncherOrder( | 1615 void ExtensionPrefs::SetAppLaunchOrdinal(const std::string& extension_id, |
1495 const std::vector<std::string>& extension_ids) { | 1616 const StringOrdinal& ordinal) { |
1496 for (size_t i = 0; i < extension_ids.size(); ++i) | 1617 UpdateExtensionPref(extension_id, kPrefAppLaunchOrdinal, |
1497 SetAppLaunchIndex(extension_ids.at(i), i); | 1618 Value::CreateStringValue(ordinal.ToString())); |
| 1619 } |
| 1620 |
| 1621 StringOrdinal ExtensionPrefs::GetNextAppLaunchOrdinal( |
| 1622 const StringOrdinal& page_ordinal) const { |
| 1623 StringOrdinal max_ordinal; |
| 1624 StringOrdinal min_ordinal; |
| 1625 GetMaxAndMinAppLaunchOrdinalsOnPage(page_ordinal, &min_ordinal, &max_ordinal); |
| 1626 |
| 1627 if (max_ordinal.IsValid()) |
| 1628 return max_ordinal.CreateAfter(); |
| 1629 else |
| 1630 return StringOrdinal::CreateInitialOrdinal(); |
| 1631 } |
| 1632 |
| 1633 StringOrdinal ExtensionPrefs::GetNaturalAppPageOrdinal() const { |
| 1634 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
| 1635 CHECK(extensions); |
| 1636 |
| 1637 if (page_ordinal_map_.empty()) |
| 1638 return StringOrdinal::CreateInitialOrdinal(); |
| 1639 |
| 1640 std::map<StringOrdinal, int>::const_iterator it = page_ordinal_map_.begin(); |
| 1641 for (; it != page_ordinal_map_.end(); ++it) { |
| 1642 if (it->second < kNaturalAppPageSize) |
| 1643 return it->first; |
| 1644 } |
| 1645 |
| 1646 // Add a new page as all existing pages are full. |
| 1647 StringOrdinal last_element = page_ordinal_map_.rbegin()->first; |
| 1648 return last_element.CreateAfter(); |
| 1649 } |
| 1650 |
| 1651 void ExtensionPrefs::OnExtensionMoved( |
| 1652 const std::string& moved_extension_id, |
| 1653 const std::string& predecessor_extension_id, |
| 1654 const std::string& successor_extension_id) { |
| 1655 // We only need to update the ordinal if the app has at least 1 neighbor. |
| 1656 if (!predecessor_extension_id.empty() || !successor_extension_id.empty()) { |
| 1657 if (predecessor_extension_id.empty()) { |
| 1658 SetAppLaunchOrdinal( |
| 1659 moved_extension_id, |
| 1660 GetAppLaunchOrdinal(successor_extension_id).CreateBefore()); |
| 1661 } else if (successor_extension_id.empty()) { |
| 1662 SetAppLaunchOrdinal( |
| 1663 moved_extension_id, |
| 1664 GetAppLaunchOrdinal(predecessor_extension_id).CreateAfter()); |
| 1665 } else { |
| 1666 StringOrdinal predecessor_ordinal = |
| 1667 GetAppLaunchOrdinal(predecessor_extension_id); |
| 1668 StringOrdinal sucessor_ordinal = |
| 1669 GetAppLaunchOrdinal(successor_extension_id); |
| 1670 SetAppLaunchOrdinal(moved_extension_id, |
| 1671 predecessor_ordinal.CreateBetween(sucessor_ordinal)); |
| 1672 } |
| 1673 } |
1498 | 1674 |
1499 content::NotificationService::current()->Notify( | 1675 content::NotificationService::current()->Notify( |
1500 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, | 1676 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, |
1501 content::Source<ExtensionPrefs>(this), | 1677 content::Source<ExtensionPrefs>(this), |
1502 content::NotificationService::NoDetails()); | 1678 content::NotificationService::NoDetails()); |
1503 } | 1679 } |
1504 | 1680 |
1505 int ExtensionPrefs::GetPageIndex(const std::string& extension_id) { | 1681 StringOrdinal ExtensionPrefs::GetPageOrdinal(const std::string& extension_id) |
1506 int value = -1; | 1682 const { |
1507 ReadExtensionPrefInteger(extension_id, kPrefPageIndex, &value); | 1683 std::string raw_data; |
1508 return value; | 1684 // If the preference read fails then raw_data will still be unset and we will |
| 1685 // return an invalid StringOrdinal to signal that no page ordinal was found. |
| 1686 ReadExtensionPrefString(extension_id, kPrefPageOrdinal, &raw_data); |
| 1687 return StringOrdinal(raw_data); |
1509 } | 1688 } |
1510 | 1689 |
1511 void ExtensionPrefs::SetPageIndex(const std::string& extension_id, int index) { | 1690 void ExtensionPrefs::SetPageOrdinal(const std::string& extension_id, |
1512 UpdateExtensionPref(extension_id, kPrefPageIndex, | 1691 const StringOrdinal& page_ordinal) { |
1513 Value::CreateIntegerValue(index)); | 1692 UpdatePageOrdinalMap(GetPageOrdinal(extension_id), page_ordinal); |
| 1693 UpdateExtensionPref(extension_id, kPrefPageOrdinal, |
| 1694 Value::CreateStringValue(page_ordinal.ToString())); |
1514 } | 1695 } |
1515 | 1696 |
1516 void ExtensionPrefs::ClearPageIndex(const std::string& extension_id) { | 1697 void ExtensionPrefs::ClearPageOrdinal(const std::string& extension_id) { |
1517 UpdateExtensionPref(extension_id, kPrefPageIndex, NULL); | 1698 UpdatePageOrdinalMap(GetPageOrdinal(extension_id), StringOrdinal()); |
| 1699 UpdateExtensionPref(extension_id, kPrefPageOrdinal, NULL); |
| 1700 } |
| 1701 |
| 1702 void ExtensionPrefs::InitializePageOrdinalMap( |
| 1703 const ExtensionIdSet& extension_ids) { |
| 1704 for (ExtensionIdSet::const_iterator ext_it = extension_ids.begin(); |
| 1705 ext_it != extension_ids.end(); ++ext_it) { |
| 1706 UpdatePageOrdinalMap(StringOrdinal(), GetPageOrdinal(*ext_it)); |
| 1707 } |
| 1708 } |
| 1709 |
| 1710 void ExtensionPrefs::UpdatePageOrdinalMap(const StringOrdinal& old_value, |
| 1711 const StringOrdinal& new_value) { |
| 1712 if (new_value.IsValid()) |
| 1713 ++page_ordinal_map_[new_value]; |
| 1714 |
| 1715 if (old_value.IsValid()) { |
| 1716 --page_ordinal_map_[old_value]; |
| 1717 |
| 1718 if (page_ordinal_map_[old_value] == 0) |
| 1719 page_ordinal_map_.erase(old_value); |
| 1720 } |
| 1721 } |
| 1722 |
| 1723 int ExtensionPrefs::PageStringOrdinalAsInteger( |
| 1724 const StringOrdinal& page_ordinal) |
| 1725 const { |
| 1726 if (!page_ordinal.IsValid()) |
| 1727 return -1; |
| 1728 |
| 1729 std::map<StringOrdinal, int>::const_iterator it = |
| 1730 page_ordinal_map_.find(page_ordinal); |
| 1731 if (it != page_ordinal_map_.end()) { |
| 1732 return std::distance(page_ordinal_map_.begin(), it); |
| 1733 } else { |
| 1734 return -1; |
| 1735 } |
| 1736 } |
| 1737 |
| 1738 StringOrdinal ExtensionPrefs::PageIntegerAsStringOrdinal(size_t page_index) { |
| 1739 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
| 1740 if (!extensions) |
| 1741 return StringOrdinal(); |
| 1742 |
| 1743 if (page_index < page_ordinal_map_.size()) { |
| 1744 std::map<StringOrdinal, int, StringOrdinalLessThan>::const_iterator it = |
| 1745 page_ordinal_map_.begin(); |
| 1746 advance(it, page_index); |
| 1747 |
| 1748 return it->first; |
| 1749 } else { |
| 1750 if (page_ordinal_map_.empty()) |
| 1751 page_ordinal_map_[StringOrdinal::CreateInitialOrdinal()] = 0; |
| 1752 |
| 1753 // Create new pages until we reach the desired index. |
| 1754 while (page_index >= page_ordinal_map_.size()) { |
| 1755 StringOrdinal new_page = page_ordinal_map_.rbegin()->first.CreateAfter(); |
| 1756 page_ordinal_map_[new_page] = 0; |
| 1757 } |
| 1758 return page_ordinal_map_.rbegin()->first; |
| 1759 } |
1518 } | 1760 } |
1519 | 1761 |
1520 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) { | 1762 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) { |
1521 return ReadExtensionPrefBoolean(extension_id, kPrefUserDraggedApp); | 1763 return ReadExtensionPrefBoolean(extension_id, kPrefUserDraggedApp); |
1522 } | 1764 } |
1523 | 1765 |
1524 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) { | 1766 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) { |
1525 UpdateExtensionPref(extension_id, kPrefUserDraggedApp, | 1767 UpdateExtensionPref(extension_id, kPrefUserDraggedApp, |
1526 Value::CreateBooleanValue(true)); | 1768 Value::CreateBooleanValue(true)); |
1527 } | 1769 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1654 // Create empty preferences dictionary for each extension (these dictionaries | 1896 // Create empty preferences dictionary for each extension (these dictionaries |
1655 // are pruned when persisting the preferences to disk). | 1897 // are pruned when persisting the preferences to disk). |
1656 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); | 1898 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); |
1657 ext_id != extension_ids.end(); ++ext_id) { | 1899 ext_id != extension_ids.end(); ++ext_id) { |
1658 ScopedExtensionPrefUpdate update(prefs_, *ext_id); | 1900 ScopedExtensionPrefUpdate update(prefs_, *ext_id); |
1659 // This creates an empty dictionary if none is stored. | 1901 // This creates an empty dictionary if none is stored. |
1660 update.Get(); | 1902 update.Get(); |
1661 } | 1903 } |
1662 | 1904 |
1663 FixMissingPrefs(extension_ids); | 1905 FixMissingPrefs(extension_ids); |
| 1906 InitializePageOrdinalMap(extension_ids); |
1664 MigratePermissions(extension_ids); | 1907 MigratePermissions(extension_ids); |
| 1908 MigrateAppIndex(extension_ids); |
1665 | 1909 |
1666 // Store extension controlled preference values in the | 1910 // Store extension controlled preference values in the |
1667 // |extension_pref_value_map_|, which then informs the subscribers | 1911 // |extension_pref_value_map_|, which then informs the subscribers |
1668 // (ExtensionPrefStores) about the winning values. | 1912 // (ExtensionPrefStores) about the winning values. |
1669 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); | 1913 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); |
1670 ext_id != extension_ids.end(); ++ext_id) { | 1914 ext_id != extension_ids.end(); ++ext_id) { |
1671 extension_pref_value_map_->RegisterExtension( | 1915 extension_pref_value_map_->RegisterExtension( |
1672 *ext_id, | 1916 *ext_id, |
1673 GetInstallTime(*ext_id), | 1917 GetInstallTime(*ext_id), |
1674 !IsExtensionDisabled(*ext_id)); | 1918 !IsExtensionDisabled(*ext_id)); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1822 prefs->RegisterListPref(prefs::kExtensionInstallAllowList, | 2066 prefs->RegisterListPref(prefs::kExtensionInstallAllowList, |
1823 PrefService::UNSYNCABLE_PREF); | 2067 PrefService::UNSYNCABLE_PREF); |
1824 prefs->RegisterListPref(prefs::kExtensionInstallDenyList, | 2068 prefs->RegisterListPref(prefs::kExtensionInstallDenyList, |
1825 PrefService::UNSYNCABLE_PREF); | 2069 PrefService::UNSYNCABLE_PREF); |
1826 prefs->RegisterListPref(prefs::kExtensionInstallForceList, | 2070 prefs->RegisterListPref(prefs::kExtensionInstallForceList, |
1827 PrefService::UNSYNCABLE_PREF); | 2071 PrefService::UNSYNCABLE_PREF); |
1828 prefs->RegisterStringPref(kWebStoreLogin, | 2072 prefs->RegisterStringPref(kWebStoreLogin, |
1829 std::string() /* default_value */, | 2073 std::string() /* default_value */, |
1830 PrefService::UNSYNCABLE_PREF); | 2074 PrefService::UNSYNCABLE_PREF); |
1831 } | 2075 } |
OLD | NEW |