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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 | 104 |
105 // A preference set by the web store to indicate login information for | 105 // A preference set by the web store to indicate login information for |
106 // purchased apps. | 106 // purchased apps. |
107 const char kWebStoreLogin[] = "extensions.webstore_login"; | 107 const char kWebStoreLogin[] = "extensions.webstore_login"; |
108 | 108 |
109 // A preference set by the the NTP to persist the desired launch container type | 109 // A preference set by the the NTP to persist the desired launch container type |
110 // used for apps. | 110 // used for apps. |
111 const char kPrefLaunchType[] = "launchType"; | 111 const char kPrefLaunchType[] = "launchType"; |
112 | 112 |
113 // A preference determining the order of which the apps appear on the NTP. | 113 // A preference determining the order of which the apps appear on the NTP. |
114 const char kPrefAppLaunchIndex[] = "app_launcher_index"; | 114 const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index"; |
| 115 const char kPrefAppLaunchOrdinal[] = "app_launcher_ordinal"; |
115 | 116 |
116 // A preference determining the page on which an app appears in the NTP. | 117 // A preference determining the page on which an app appears in the NTP. |
117 const char kPrefPageIndex[] = "page_index"; | 118 const char kPrefPageIndexDeprecated[] = "page_index"; |
| 119 const char kPrefPageOrdinal[] = "page_ordinal"; |
118 | 120 |
119 // A preference specifying if the user dragged the app on the NTP. | 121 // A preference specifying if the user dragged the app on the NTP. |
120 const char kPrefUserDraggedApp[] = "user_dragged_app_ntp"; | 122 const char kPrefUserDraggedApp[] = "user_dragged_app_ntp"; |
121 | 123 |
122 // A preference for storing extra data sent in update checks for an extension. | 124 // A preference for storing extra data sent in update checks for an extension. |
123 const char kUpdateUrlData[] = "update_url_data"; | 125 const char kUpdateUrlData[] = "update_url_data"; |
124 | 126 |
125 // Whether the browser action is visible in the toolbar. | 127 // Whether the browser action is visible in the toolbar. |
126 const char kBrowserActionVisible[] = "browser_action_visible"; | 128 const char kBrowserActionVisible[] = "browser_action_visible"; |
127 | 129 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 const DictionaryValue* ext = GetExtensionPref(extension_id); | 412 const DictionaryValue* ext = GetExtensionPref(extension_id); |
411 ListValue* out = NULL; | 413 ListValue* out = NULL; |
412 if (!ext || !ext->GetList(pref_key, &out)) | 414 if (!ext || !ext->GetList(pref_key, &out)) |
413 return false; | 415 return false; |
414 if (out_value) | 416 if (out_value) |
415 *out_value = out; | 417 *out_value = out; |
416 | 418 |
417 return true; | 419 return true; |
418 } | 420 } |
419 | 421 |
| 422 bool ExtensionPrefs::ReadExtensionPrefString( |
| 423 const std::string& extension_id, const std::string& pref_key, |
| 424 std::string* out_value) const { |
| 425 const DictionaryValue* ext = GetExtensionPref(extension_id); |
| 426 |
| 427 if (!ext || !ext->GetString(pref_key, out_value)) |
| 428 return false; |
| 429 |
| 430 return true; |
| 431 } |
| 432 |
420 bool ExtensionPrefs::ReadExtensionPrefURLPatternSet( | 433 bool ExtensionPrefs::ReadExtensionPrefURLPatternSet( |
421 const std::string& extension_id, | 434 const std::string& extension_id, |
422 const std::string& pref_key, | 435 const std::string& pref_key, |
423 URLPatternSet* result, | 436 URLPatternSet* result, |
424 int valid_schemes) { | 437 int valid_schemes) { |
425 const ListValue* value = NULL; | 438 const ListValue* value = NULL; |
426 if (!ReadExtensionPrefList(extension_id, pref_key, &value)) | 439 if (!ReadExtensionPrefList(extension_id, pref_key, &value)) |
427 return false; | 440 return false; |
428 | 441 |
429 result->ClearPatterns(); | 442 result->ClearPatterns(); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 if (ext->GetList(kPrefOldGrantedHosts, &hosts)) { | 870 if (ext->GetList(kPrefOldGrantedHosts, &hosts)) { |
858 UpdateExtensionPref( | 871 UpdateExtensionPref( |
859 *ext_id, explicit_hosts, hosts->DeepCopy()); | 872 *ext_id, explicit_hosts, hosts->DeepCopy()); |
860 | 873 |
861 // We can get rid of the old one by setting it to an empty list. | 874 // We can get rid of the old one by setting it to an empty list. |
862 UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new ListValue()); | 875 UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new ListValue()); |
863 } | 876 } |
864 } | 877 } |
865 } | 878 } |
866 | 879 |
| 880 void ExtensionPrefs::MigrateAppIndex(const ExtensionIdSet& extension_ids) { |
| 881 if (extension_ids.empty()) |
| 882 return; |
| 883 |
| 884 // Convert all the page index values to page ordinals. If there are any |
| 885 // app launch values that need to be migrated, inserted them into a sorted |
| 886 // set to be dealt with later. |
| 887 typedef std::map<StringOrdinal, std::map<int, const std::string*>, |
| 888 StringOrdinalLessThan> AppPositionToIdMapping; |
| 889 AppPositionToIdMapping app_launches_to_convert; |
| 890 for (ExtensionIdSet::const_iterator ext_id = extension_ids.begin(); |
| 891 ext_id != extension_ids.end(); ++ext_id) { |
| 892 int old_page_index = 0; |
| 893 StringOrdinal page = GetPageOrdinal(*ext_id); |
| 894 if (ReadExtensionPrefInteger(*ext_id, |
| 895 kPrefPageIndexDeprecated, |
| 896 &old_page_index)) { |
| 897 // Since we require all earlier StringOrdinals to already exist in order |
| 898 // to properly convert from integers and we are iterating though them in |
| 899 // no given order, we create earlier StringOrdinal values as required. |
| 900 // This should be filled in by the time we are done with this loop. |
| 901 if (page_ordinal_map_.empty()) |
| 902 page_ordinal_map_[StringOrdinal::CreateInitialOrdinal()] = 0; |
| 903 while (page_ordinal_map_.size() <= static_cast<size_t>(old_page_index)) { |
| 904 StringOrdinal earlier_page = |
| 905 page_ordinal_map_.rbegin()->first.CreateAfter(); |
| 906 page_ordinal_map_[earlier_page] = 0; |
| 907 } |
| 908 |
| 909 page = PageIntegerAsStringOrdinal(old_page_index); |
| 910 SetPageOrdinal(*ext_id, page); |
| 911 UpdateExtensionPref(*ext_id, kPrefPageIndexDeprecated, NULL); |
| 912 } |
| 913 |
| 914 int old_app_launch_index = 0; |
| 915 if (ReadExtensionPrefInteger(*ext_id, |
| 916 kPrefAppLaunchIndexDeprecated, |
| 917 &old_app_launch_index)) { |
| 918 // We can't update the app launch index value yet, because we use |
| 919 // GetNextAppLaunchOrdinal to get the new ordinal value and it requires |
| 920 // all the ordinals with lower values to have already been migrated. |
| 921 // A valid page ordinal is also required because otherwise there is |
| 922 // no page to add the app to. |
| 923 if (page.IsValid()) |
| 924 app_launches_to_convert[page][old_app_launch_index] = &*ext_id; |
| 925 |
| 926 UpdateExtensionPref(*ext_id, kPrefAppLaunchIndexDeprecated, NULL); |
| 927 } |
| 928 } |
| 929 |
| 930 // Remove any empty pages that may have been added. This shouldn't occur, |
| 931 // but double check here to prevent future problems with conversions between |
| 932 // integers and StringOrdinals. |
| 933 for (PageOrdinalMap::iterator it = page_ordinal_map_.begin(); |
| 934 it != page_ordinal_map_.end();) { |
| 935 if (it->second == 0) { |
| 936 PageOrdinalMap::iterator prev_it = it; |
| 937 ++it; |
| 938 page_ordinal_map_.erase(prev_it); |
| 939 } else { |
| 940 ++it; |
| 941 } |
| 942 } |
| 943 |
| 944 if (app_launches_to_convert.empty()) |
| 945 return; |
| 946 |
| 947 // Create the new app launch ordinals and remove the old preferences. Since |
| 948 // the set is sorted, each time we migrate an apps index, we know that all of |
| 949 // the remaining apps will appear further down the NTP than it or on a |
| 950 // different page. |
| 951 for (AppPositionToIdMapping::const_iterator page_it = |
| 952 app_launches_to_convert.begin(); |
| 953 page_it != app_launches_to_convert.end(); ++page_it) { |
| 954 StringOrdinal page = page_it->first; |
| 955 for (std::map<int, const std::string*>::const_iterator launch_it = |
| 956 page_it->second.begin(); launch_it != page_it->second.end(); |
| 957 ++launch_it) { |
| 958 SetAppLaunchOrdinal(*(launch_it->second), |
| 959 CreateNextAppLaunchOrdinal(page)); |
| 960 } |
| 961 } |
| 962 } |
| 963 |
867 ExtensionPermissionSet* ExtensionPrefs::GetGrantedPermissions( | 964 ExtensionPermissionSet* ExtensionPrefs::GetGrantedPermissions( |
868 const std::string& extension_id) { | 965 const std::string& extension_id) { |
869 CHECK(Extension::IdIsValid(extension_id)); | 966 CHECK(Extension::IdIsValid(extension_id)); |
870 return ReadExtensionPrefPermissionSet(extension_id, kPrefGrantedPermissions); | 967 return ReadExtensionPrefPermissionSet(extension_id, kPrefGrantedPermissions); |
871 } | 968 } |
872 | 969 |
873 void ExtensionPrefs::AddGrantedPermissions( | 970 void ExtensionPrefs::AddGrantedPermissions( |
874 const std::string& extension_id, | 971 const std::string& extension_id, |
875 const ExtensionPermissionSet* permissions) { | 972 const ExtensionPermissionSet* permissions) { |
876 CHECK(Extension::IdIsValid(extension_id)); | 973 CHECK(Extension::IdIsValid(extension_id)); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 iter != extension_ids.end(); ++iter) { | 1169 iter != extension_ids.end(); ++iter) { |
1073 toolbar_order->Append(new StringValue(*iter)); | 1170 toolbar_order->Append(new StringValue(*iter)); |
1074 } | 1171 } |
1075 SavePrefs(); | 1172 SavePrefs(); |
1076 } | 1173 } |
1077 | 1174 |
1078 void ExtensionPrefs::OnExtensionInstalled( | 1175 void ExtensionPrefs::OnExtensionInstalled( |
1079 const Extension* extension, | 1176 const Extension* extension, |
1080 Extension::State initial_state, | 1177 Extension::State initial_state, |
1081 bool from_webstore, | 1178 bool from_webstore, |
1082 int page_index) { | 1179 const StringOrdinal& page_ordinal) { |
1083 const std::string& id = extension->id(); | 1180 const std::string& id = extension->id(); |
1084 CHECK(Extension::IdIsValid(id)); | 1181 CHECK(Extension::IdIsValid(id)); |
1085 ScopedExtensionPrefUpdate update(prefs_, id); | 1182 ScopedExtensionPrefUpdate update(prefs_, id); |
1086 DictionaryValue* extension_dict = update.Get(); | 1183 DictionaryValue* extension_dict = update.Get(); |
1087 const base::Time install_time = GetCurrentTime(); | 1184 const base::Time install_time = GetCurrentTime(); |
1088 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); | 1185 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); |
1089 extension_dict->Set(kPrefLocation, | 1186 extension_dict->Set(kPrefLocation, |
1090 Value::CreateIntegerValue(extension->location())); | 1187 Value::CreateIntegerValue(extension->location())); |
1091 extension_dict->Set(kPrefFromWebStore, | 1188 extension_dict->Set(kPrefFromWebStore, |
1092 Value::CreateBooleanValue(from_webstore)); | 1189 Value::CreateBooleanValue(from_webstore)); |
(...skipping 11 matching lines...) Expand all Loading... |
1104 extension->path()); | 1201 extension->path()); |
1105 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); | 1202 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); |
1106 // We store prefs about LOAD extensions, but don't cache their manifest | 1203 // We store prefs about LOAD extensions, but don't cache their manifest |
1107 // since it may change on disk. | 1204 // since it may change on disk. |
1108 if (extension->location() != Extension::LOAD) { | 1205 if (extension->location() != Extension::LOAD) { |
1109 extension_dict->Set(kPrefManifest, | 1206 extension_dict->Set(kPrefManifest, |
1110 extension->manifest()->value()->DeepCopy()); | 1207 extension->manifest()->value()->DeepCopy()); |
1111 } | 1208 } |
1112 | 1209 |
1113 if (extension->is_app()) { | 1210 if (extension->is_app()) { |
1114 if (page_index == -1) | 1211 StringOrdinal new_page_ordinal = |
1115 page_index = GetNaturalAppPageIndex(); | 1212 page_ordinal.IsValid() ? page_ordinal : GetNaturalAppPageOrdinal(); |
1116 extension_dict->Set(kPrefPageIndex, | 1213 SetPageOrdinal(id, new_page_ordinal); |
1117 Value::CreateIntegerValue(page_index)); | 1214 SetAppLaunchOrdinal(id, CreateNextAppLaunchOrdinal(new_page_ordinal)); |
1118 extension_dict->Set(kPrefAppLaunchIndex, | |
1119 Value::CreateIntegerValue(GetNextAppLaunchIndex(page_index))); | |
1120 } | 1215 } |
| 1216 |
1121 extension_pref_value_map_->RegisterExtension( | 1217 extension_pref_value_map_->RegisterExtension( |
1122 id, install_time, initial_state == Extension::ENABLED); | 1218 id, install_time, initial_state == Extension::ENABLED); |
1123 content_settings_store_->RegisterExtension( | 1219 content_settings_store_->RegisterExtension( |
1124 id, install_time, initial_state == Extension::ENABLED); | 1220 id, install_time, initial_state == Extension::ENABLED); |
1125 } | 1221 } |
1126 | 1222 |
1127 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, | 1223 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, |
1128 const Extension::Location& location, | 1224 const Extension::Location& location, |
1129 bool external_uninstall) { | 1225 bool external_uninstall) { |
1130 // For external extensions, we save a preference reminding ourself not to try | 1226 // For external extensions, we save a preference reminding ourself not to try |
1131 // and install the extension anymore (except when |external_uninstall| is | 1227 // and install the extension anymore (except when |external_uninstall| is |
1132 // true, which signifies that the registry key was deleted or the pref file | 1228 // true, which signifies that the registry key was deleted or the pref file |
1133 // no longer lists the extension). | 1229 // no longer lists the extension). |
1134 if (!external_uninstall && Extension::IsExternalLocation(location)) { | 1230 if (!external_uninstall && Extension::IsExternalLocation(location)) { |
1135 UpdateExtensionPref(extension_id, kPrefState, | 1231 UpdateExtensionPref(extension_id, kPrefState, |
1136 Value::CreateIntegerValue( | 1232 Value::CreateIntegerValue( |
1137 Extension::EXTERNAL_EXTENSION_UNINSTALLED)); | 1233 Extension::EXTERNAL_EXTENSION_UNINSTALLED)); |
1138 extension_pref_value_map_->SetExtensionState(extension_id, false); | 1234 extension_pref_value_map_->SetExtensionState(extension_id, false); |
1139 content_settings_store_->SetExtensionState(extension_id, false); | 1235 content_settings_store_->SetExtensionState(extension_id, false); |
1140 } else { | 1236 } else { |
1141 DeleteExtensionPrefs(extension_id); | 1237 DeleteExtensionPrefs(extension_id); |
1142 } | 1238 } |
1143 } | 1239 } |
1144 | 1240 |
| 1241 void ExtensionPrefs::OnExtensionMoved( |
| 1242 const std::string& moved_extension_id, |
| 1243 const std::string& predecessor_extension_id, |
| 1244 const std::string& successor_extension_id) { |
| 1245 // If there are no neighbors then no changes are required, so we can return. |
| 1246 if (predecessor_extension_id.empty() && successor_extension_id.empty()) |
| 1247 return; |
| 1248 |
| 1249 if (predecessor_extension_id.empty()) { |
| 1250 SetAppLaunchOrdinal( |
| 1251 moved_extension_id, |
| 1252 GetAppLaunchOrdinal(successor_extension_id).CreateBefore()); |
| 1253 } else if (successor_extension_id.empty()) { |
| 1254 SetAppLaunchOrdinal( |
| 1255 moved_extension_id, |
| 1256 GetAppLaunchOrdinal(predecessor_extension_id).CreateAfter()); |
| 1257 } else { |
| 1258 const StringOrdinal& predecessor_ordinal = |
| 1259 GetAppLaunchOrdinal(predecessor_extension_id); |
| 1260 const StringOrdinal& successor_ordinal = |
| 1261 GetAppLaunchOrdinal(successor_extension_id); |
| 1262 SetAppLaunchOrdinal(moved_extension_id, |
| 1263 predecessor_ordinal.CreateBetween(successor_ordinal)); |
| 1264 } |
| 1265 |
| 1266 content::NotificationService::current()->Notify( |
| 1267 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, |
| 1268 content::Source<ExtensionPrefs>(this), |
| 1269 content::NotificationService::NoDetails()); |
| 1270 } |
| 1271 |
1145 void ExtensionPrefs::SetExtensionState(const std::string& extension_id, | 1272 void ExtensionPrefs::SetExtensionState(const std::string& extension_id, |
1146 Extension::State state) { | 1273 Extension::State state) { |
1147 UpdateExtensionPref(extension_id, kPrefState, | 1274 UpdateExtensionPref(extension_id, kPrefState, |
1148 Value::CreateIntegerValue(state)); | 1275 Value::CreateIntegerValue(state)); |
1149 bool enabled = (state == Extension::ENABLED); | 1276 bool enabled = (state == Extension::ENABLED); |
1150 extension_pref_value_map_->SetExtensionState(extension_id, enabled); | 1277 extension_pref_value_map_->SetExtensionState(extension_id, enabled); |
1151 content_settings_store_->SetExtensionState(extension_id, enabled); | 1278 content_settings_store_->SetExtensionState(extension_id, enabled); |
1152 } | 1279 } |
1153 | 1280 |
1154 bool ExtensionPrefs::GetBrowserActionVisibility(const Extension* extension) { | 1281 bool ExtensionPrefs::GetBrowserActionVisibility(const Extension* extension) { |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1442 return true; | 1569 return true; |
1443 } | 1570 } |
1444 return false; | 1571 return false; |
1445 } | 1572 } |
1446 | 1573 |
1447 void ExtensionPrefs::SetWebStoreLogin(const std::string& login) { | 1574 void ExtensionPrefs::SetWebStoreLogin(const std::string& login) { |
1448 prefs_->SetString(kWebStoreLogin, login); | 1575 prefs_->SetString(kWebStoreLogin, login); |
1449 SavePrefs(); | 1576 SavePrefs(); |
1450 } | 1577 } |
1451 | 1578 |
1452 int ExtensionPrefs::GetAppLaunchIndex(const std::string& extension_id) { | 1579 StringOrdinal ExtensionPrefs::GetMinOrMaxAppLaunchOrdinalsOnPage( |
1453 int value; | 1580 const StringOrdinal& target_page_ordinal, |
1454 if (ReadExtensionPrefInteger(extension_id, kPrefAppLaunchIndex, &value)) | 1581 AppLaunchOrdinalReturn return_type) const { |
1455 return value; | 1582 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
| 1583 CHECK(extensions); |
| 1584 CHECK(target_page_ordinal.IsValid()); |
1456 | 1585 |
1457 return -1; | 1586 StringOrdinal return_value; |
| 1587 for (DictionaryValue::key_iterator ext_it = extensions->begin_keys(); |
| 1588 ext_it != extensions->end_keys(); ++ext_it) { |
| 1589 const StringOrdinal& page_ordinal = GetPageOrdinal(*ext_it); |
| 1590 if (page_ordinal.IsValid() && page_ordinal.Equal(target_page_ordinal)) { |
| 1591 const StringOrdinal& app_launch_ordinal = GetAppLaunchOrdinal(*ext_it); |
| 1592 if (app_launch_ordinal.IsValid()) { |
| 1593 if (!return_value.IsValid()) |
| 1594 return_value = app_launch_ordinal; |
| 1595 else if (return_type == ExtensionPrefs::MIN_ORDINAL && |
| 1596 app_launch_ordinal.LessThan(return_value)) |
| 1597 return_value = app_launch_ordinal; |
| 1598 else if (return_type == ExtensionPrefs::MAX_ORDINAL && |
| 1599 app_launch_ordinal.GreaterThan(return_value)) |
| 1600 return_value = app_launch_ordinal; |
| 1601 } |
| 1602 } |
| 1603 } |
| 1604 |
| 1605 return return_value; |
1458 } | 1606 } |
1459 | 1607 |
1460 void ExtensionPrefs::SetAppLaunchIndex(const std::string& extension_id, | 1608 StringOrdinal ExtensionPrefs::GetAppLaunchOrdinal( |
1461 int index) { | 1609 const std::string& extension_id) const { |
1462 UpdateExtensionPref(extension_id, kPrefAppLaunchIndex, | 1610 std::string raw_value; |
1463 Value::CreateIntegerValue(index)); | 1611 // If the preference read fails then raw_value will still be unset and we |
| 1612 // will return an invalid StringOrdinal to signal that no app launch ordinal |
| 1613 // was found. |
| 1614 ReadExtensionPrefString(extension_id, kPrefAppLaunchOrdinal, &raw_value); |
| 1615 return StringOrdinal(raw_value); |
1464 } | 1616 } |
1465 | 1617 |
1466 int ExtensionPrefs::GetNextAppLaunchIndex(int on_page) { | 1618 void ExtensionPrefs::SetAppLaunchOrdinal(const std::string& extension_id, |
1467 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); | 1619 const StringOrdinal& ordinal) { |
1468 if (!extensions) | 1620 UpdateExtensionPref(extension_id, kPrefAppLaunchOrdinal, |
1469 return 0; | 1621 Value::CreateStringValue(ordinal.ToString())); |
1470 | |
1471 int max_value = -1; | |
1472 for (DictionaryValue::key_iterator extension_id = extensions->begin_keys(); | |
1473 extension_id != extensions->end_keys(); ++extension_id) { | |
1474 int value = GetAppLaunchIndex(*extension_id); | |
1475 int page = GetPageIndex(*extension_id); | |
1476 if (page == on_page && value > max_value) | |
1477 max_value = value; | |
1478 } | |
1479 return max_value + 1; | |
1480 } | 1622 } |
1481 | 1623 |
1482 int ExtensionPrefs::GetNaturalAppPageIndex() { | 1624 StringOrdinal ExtensionPrefs::CreateFirstAppLaunchOrdinal( |
| 1625 const StringOrdinal& page_ordinal) const { |
| 1626 const StringOrdinal& min_ordinal = |
| 1627 GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal, |
| 1628 ExtensionPrefs::MIN_ORDINAL); |
| 1629 |
| 1630 if (min_ordinal.IsValid()) |
| 1631 return min_ordinal.CreateBefore(); |
| 1632 else |
| 1633 return StringOrdinal::CreateInitialOrdinal(); |
| 1634 } |
| 1635 |
| 1636 StringOrdinal ExtensionPrefs::CreateNextAppLaunchOrdinal( |
| 1637 const StringOrdinal& page_ordinal) const { |
| 1638 const StringOrdinal& max_ordinal = |
| 1639 GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal, |
| 1640 ExtensionPrefs::MAX_ORDINAL); |
| 1641 |
| 1642 if (max_ordinal.IsValid()) |
| 1643 return max_ordinal.CreateAfter(); |
| 1644 else |
| 1645 return StringOrdinal::CreateInitialOrdinal(); |
| 1646 } |
| 1647 |
| 1648 StringOrdinal ExtensionPrefs::CreateFirstAppPageOrdinal() const { |
1483 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); | 1649 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
1484 if (!extensions) | 1650 CHECK(extensions); |
1485 return 0; | |
1486 | 1651 |
1487 std::map<int, int> page_counts; | 1652 if (page_ordinal_map_.empty()) |
1488 for (DictionaryValue::key_iterator extension_id = extensions->begin_keys(); | 1653 return StringOrdinal::CreateInitialOrdinal(); |
1489 extension_id != extensions->end_keys(); ++extension_id) { | 1654 |
1490 int page_index = GetPageIndex(*extension_id); | 1655 return page_ordinal_map_.begin()->first; |
1491 if (page_index >= 0) | 1656 } |
1492 page_counts[page_index] = page_counts[page_index] + 1; | 1657 |
| 1658 StringOrdinal ExtensionPrefs::GetNaturalAppPageOrdinal() const { |
| 1659 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
| 1660 CHECK(extensions); |
| 1661 |
| 1662 if (page_ordinal_map_.empty()) |
| 1663 return StringOrdinal::CreateInitialOrdinal(); |
| 1664 |
| 1665 for (PageOrdinalMap::const_iterator it = page_ordinal_map_.begin(); |
| 1666 it != page_ordinal_map_.end(); ++it) { |
| 1667 if (it->second < kNaturalAppPageSize) |
| 1668 return it->first; |
1493 } | 1669 } |
1494 for (int i = 0; ; i++) { | 1670 |
1495 std::map<int, int>::const_iterator it = page_counts.find(i); | 1671 // Add a new page as all existing pages are full. |
1496 if (it == page_counts.end() || it->second < kNaturalAppPageSize) | 1672 StringOrdinal last_element = page_ordinal_map_.rbegin()->first; |
1497 return i; | 1673 return last_element.CreateAfter(); |
| 1674 } |
| 1675 |
| 1676 StringOrdinal ExtensionPrefs::GetPageOrdinal(const std::string& extension_id) |
| 1677 const { |
| 1678 std::string raw_data; |
| 1679 // If the preference read fails then raw_data will still be unset and we will |
| 1680 // return an invalid StringOrdinal to signal that no page ordinal was found. |
| 1681 ReadExtensionPrefString(extension_id, kPrefPageOrdinal, &raw_data); |
| 1682 return StringOrdinal(raw_data); |
| 1683 } |
| 1684 |
| 1685 void ExtensionPrefs::SetPageOrdinal(const std::string& extension_id, |
| 1686 const StringOrdinal& page_ordinal) { |
| 1687 UpdatePageOrdinalMap(GetPageOrdinal(extension_id), page_ordinal); |
| 1688 UpdateExtensionPref(extension_id, kPrefPageOrdinal, |
| 1689 Value::CreateStringValue(page_ordinal.ToString())); |
| 1690 } |
| 1691 |
| 1692 void ExtensionPrefs::ClearPageOrdinal(const std::string& extension_id) { |
| 1693 UpdatePageOrdinalMap(GetPageOrdinal(extension_id), StringOrdinal()); |
| 1694 UpdateExtensionPref(extension_id, kPrefPageOrdinal, NULL); |
| 1695 } |
| 1696 |
| 1697 void ExtensionPrefs::InitializePageOrdinalMap( |
| 1698 const ExtensionIdSet& extension_ids) { |
| 1699 for (ExtensionIdSet::const_iterator ext_it = extension_ids.begin(); |
| 1700 ext_it != extension_ids.end(); ++ext_it) { |
| 1701 UpdatePageOrdinalMap(StringOrdinal(), GetPageOrdinal(*ext_it)); |
1498 } | 1702 } |
1499 } | 1703 } |
1500 | 1704 |
1501 void ExtensionPrefs::SetAppLauncherOrder( | 1705 void ExtensionPrefs::UpdatePageOrdinalMap(const StringOrdinal& old_value, |
1502 const std::vector<std::string>& extension_ids) { | 1706 const StringOrdinal& new_value) { |
1503 for (size_t i = 0; i < extension_ids.size(); ++i) | 1707 if (new_value.IsValid()) |
1504 SetAppLaunchIndex(extension_ids.at(i), i); | 1708 ++page_ordinal_map_[new_value]; |
1505 | 1709 |
1506 content::NotificationService::current()->Notify( | 1710 if (old_value.IsValid()) { |
1507 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, | 1711 --page_ordinal_map_[old_value]; |
1508 content::Source<ExtensionPrefs>(this), | 1712 |
1509 content::NotificationService::NoDetails()); | 1713 if (page_ordinal_map_[old_value] == 0) |
| 1714 page_ordinal_map_.erase(old_value); |
| 1715 } |
1510 } | 1716 } |
1511 | 1717 |
1512 int ExtensionPrefs::GetPageIndex(const std::string& extension_id) { | 1718 int ExtensionPrefs::PageStringOrdinalAsInteger( |
1513 int value = -1; | 1719 const StringOrdinal& page_ordinal) const { |
1514 ReadExtensionPrefInteger(extension_id, kPrefPageIndex, &value); | 1720 if (!page_ordinal.IsValid()) |
1515 return value; | 1721 return -1; |
| 1722 |
| 1723 PageOrdinalMap::const_iterator it = page_ordinal_map_.find(page_ordinal); |
| 1724 if (it != page_ordinal_map_.end()) { |
| 1725 return std::distance(page_ordinal_map_.begin(), it); |
| 1726 } else { |
| 1727 return -1; |
| 1728 } |
1516 } | 1729 } |
1517 | 1730 |
1518 void ExtensionPrefs::SetPageIndex(const std::string& extension_id, int index) { | 1731 StringOrdinal ExtensionPrefs::PageIntegerAsStringOrdinal(size_t page_index) |
1519 UpdateExtensionPref(extension_id, kPrefPageIndex, | 1732 const { |
1520 Value::CreateIntegerValue(index)); | 1733 // We shouldn't have a page_index that is more than 1 position away from the |
1521 } | 1734 // current end as that would imply we have empty pages which is not allowed. |
| 1735 CHECK_LE(page_index, page_ordinal_map_.size()); |
1522 | 1736 |
1523 void ExtensionPrefs::ClearPageIndex(const std::string& extension_id) { | 1737 const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref); |
1524 UpdateExtensionPref(extension_id, kPrefPageIndex, NULL); | 1738 if (!extensions) |
| 1739 return StringOrdinal(); |
| 1740 |
| 1741 if (page_index < page_ordinal_map_.size()) { |
| 1742 PageOrdinalMap::const_iterator it = page_ordinal_map_.begin(); |
| 1743 std::advance(it, page_index); |
| 1744 |
| 1745 return it->first; |
| 1746 |
| 1747 } else { |
| 1748 if (page_ordinal_map_.empty()) |
| 1749 return StringOrdinal::CreateInitialOrdinal(); |
| 1750 else |
| 1751 return page_ordinal_map_.rbegin()->first.CreateAfter(); |
| 1752 } |
1525 } | 1753 } |
1526 | 1754 |
1527 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) { | 1755 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) { |
1528 return ReadExtensionPrefBoolean(extension_id, kPrefUserDraggedApp); | 1756 return ReadExtensionPrefBoolean(extension_id, kPrefUserDraggedApp); |
1529 } | 1757 } |
1530 | 1758 |
1531 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) { | 1759 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) { |
1532 UpdateExtensionPref(extension_id, kPrefUserDraggedApp, | 1760 UpdateExtensionPref(extension_id, kPrefUserDraggedApp, |
1533 Value::CreateBooleanValue(true)); | 1761 Value::CreateBooleanValue(true)); |
1534 } | 1762 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 // Create empty preferences dictionary for each extension (these dictionaries | 1889 // Create empty preferences dictionary for each extension (these dictionaries |
1662 // are pruned when persisting the preferences to disk). | 1890 // are pruned when persisting the preferences to disk). |
1663 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); | 1891 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); |
1664 ext_id != extension_ids.end(); ++ext_id) { | 1892 ext_id != extension_ids.end(); ++ext_id) { |
1665 ScopedExtensionPrefUpdate update(prefs_, *ext_id); | 1893 ScopedExtensionPrefUpdate update(prefs_, *ext_id); |
1666 // This creates an empty dictionary if none is stored. | 1894 // This creates an empty dictionary if none is stored. |
1667 update.Get(); | 1895 update.Get(); |
1668 } | 1896 } |
1669 | 1897 |
1670 FixMissingPrefs(extension_ids); | 1898 FixMissingPrefs(extension_ids); |
| 1899 InitializePageOrdinalMap(extension_ids); |
1671 MigratePermissions(extension_ids); | 1900 MigratePermissions(extension_ids); |
| 1901 MigrateAppIndex(extension_ids); |
1672 | 1902 |
1673 // Store extension controlled preference values in the | 1903 // Store extension controlled preference values in the |
1674 // |extension_pref_value_map_|, which then informs the subscribers | 1904 // |extension_pref_value_map_|, which then informs the subscribers |
1675 // (ExtensionPrefStores) about the winning values. | 1905 // (ExtensionPrefStores) about the winning values. |
1676 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); | 1906 for (ExtensionIdSet::iterator ext_id = extension_ids.begin(); |
1677 ext_id != extension_ids.end(); ++ext_id) { | 1907 ext_id != extension_ids.end(); ++ext_id) { |
1678 extension_pref_value_map_->RegisterExtension( | 1908 extension_pref_value_map_->RegisterExtension( |
1679 *ext_id, | 1909 *ext_id, |
1680 GetInstallTime(*ext_id), | 1910 GetInstallTime(*ext_id), |
1681 !IsExtensionDisabled(*ext_id)); | 1911 !IsExtensionDisabled(*ext_id)); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 prefs->RegisterListPref(prefs::kExtensionInstallAllowList, | 2059 prefs->RegisterListPref(prefs::kExtensionInstallAllowList, |
1830 PrefService::UNSYNCABLE_PREF); | 2060 PrefService::UNSYNCABLE_PREF); |
1831 prefs->RegisterListPref(prefs::kExtensionInstallDenyList, | 2061 prefs->RegisterListPref(prefs::kExtensionInstallDenyList, |
1832 PrefService::UNSYNCABLE_PREF); | 2062 PrefService::UNSYNCABLE_PREF); |
1833 prefs->RegisterListPref(prefs::kExtensionInstallForceList, | 2063 prefs->RegisterListPref(prefs::kExtensionInstallForceList, |
1834 PrefService::UNSYNCABLE_PREF); | 2064 PrefService::UNSYNCABLE_PREF); |
1835 prefs->RegisterStringPref(kWebStoreLogin, | 2065 prefs->RegisterStringPref(kWebStoreLogin, |
1836 std::string() /* default_value */, | 2066 std::string() /* default_value */, |
1837 PrefService::UNSYNCABLE_PREF); | 2067 PrefService::UNSYNCABLE_PREF); |
1838 } | 2068 } |
OLD | NEW |