| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_sorting.h" | 5 #include "chrome/browser/extensions/extension_sorting.h" |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/extension_scoped_prefs.h" | 7 #include "chrome/browser/extensions/extension_scoped_prefs.h" |
| 8 #include "chrome/browser/extensions/extension_service.h" | 8 #include "chrome/browser/extensions/extension_service.h" |
| 9 #include "chrome/browser/prefs/pref_service.h" | 9 #include "chrome/browser/prefs/pref_service.h" |
| 10 #include "chrome/common/chrome_notification_types.h" | 10 #include "chrome/common/chrome_notification_types.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 const ExtensionPrefs::ExtensionIds& extension_ids) { | 47 const ExtensionPrefs::ExtensionIds& extension_ids) { |
| 48 InitializePageOrdinalMap(extension_ids); | 48 InitializePageOrdinalMap(extension_ids); |
| 49 | 49 |
| 50 MigrateAppIndex(extension_ids); | 50 MigrateAppIndex(extension_ids); |
| 51 } | 51 } |
| 52 | 52 |
| 53 void ExtensionSorting::CreateOrdinalsIfNecessary(size_t minimum_size) { | 53 void ExtensionSorting::CreateOrdinalsIfNecessary(size_t minimum_size) { |
| 54 // Create StringOrdinal values as required to ensure |ntp_ordinal_map_| has at | 54 // Create StringOrdinal values as required to ensure |ntp_ordinal_map_| has at |
| 55 // least |minimum_size| entries. | 55 // least |minimum_size| entries. |
| 56 if (ntp_ordinal_map_.empty() && minimum_size > 0) | 56 if (ntp_ordinal_map_.empty() && minimum_size > 0) |
| 57 ntp_ordinal_map_[StringOrdinal::CreateInitialOrdinal()]; | 57 ntp_ordinal_map_[syncer::StringOrdinal::CreateInitialOrdinal()]; |
| 58 | 58 |
| 59 while (ntp_ordinal_map_.size() < minimum_size) { | 59 while (ntp_ordinal_map_.size() < minimum_size) { |
| 60 StringOrdinal filler = ntp_ordinal_map_.rbegin()->first.CreateAfter(); | 60 syncer::StringOrdinal filler = |
| 61 ntp_ordinal_map_.rbegin()->first.CreateAfter(); |
| 61 AppLaunchOrdinalMap empty_ordinal_map; | 62 AppLaunchOrdinalMap empty_ordinal_map; |
| 62 ntp_ordinal_map_.insert(std::make_pair(filler, empty_ordinal_map)); | 63 ntp_ordinal_map_.insert(std::make_pair(filler, empty_ordinal_map)); |
| 63 } | 64 } |
| 64 } | 65 } |
| 65 | 66 |
| 66 void ExtensionSorting::MigrateAppIndex( | 67 void ExtensionSorting::MigrateAppIndex( |
| 67 const ExtensionPrefs::ExtensionIds& extension_ids) { | 68 const ExtensionPrefs::ExtensionIds& extension_ids) { |
| 68 if (extension_ids.empty()) | 69 if (extension_ids.empty()) |
| 69 return; | 70 return; |
| 70 | 71 |
| 71 // Convert all the page index values to page ordinals. If there are any | 72 // Convert all the page index values to page ordinals. If there are any |
| 72 // app launch values that need to be migrated, inserted them into a sorted | 73 // app launch values that need to be migrated, inserted them into a sorted |
| 73 // set to be dealt with later. | 74 // set to be dealt with later. |
| 74 typedef std::map<StringOrdinal, std::map<int, const std::string*>, | 75 typedef std::map<syncer::StringOrdinal, std::map<int, const std::string*>, |
| 75 StringOrdinalLessThan> AppPositionToIdMapping; | 76 syncer::StringOrdinal::LessThanFn> AppPositionToIdMapping; |
| 76 AppPositionToIdMapping app_launches_to_convert; | 77 AppPositionToIdMapping app_launches_to_convert; |
| 77 for (ExtensionPrefs::ExtensionIds::const_iterator ext_id = | 78 for (ExtensionPrefs::ExtensionIds::const_iterator ext_id = |
| 78 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) { | 79 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) { |
| 79 int old_page_index = 0; | 80 int old_page_index = 0; |
| 80 StringOrdinal page = GetPageOrdinal(*ext_id); | 81 syncer::StringOrdinal page = GetPageOrdinal(*ext_id); |
| 81 if (extension_scoped_prefs_->ReadExtensionPrefInteger( | 82 if (extension_scoped_prefs_->ReadExtensionPrefInteger( |
| 82 *ext_id, | 83 *ext_id, |
| 83 kPrefPageIndexDeprecated, | 84 kPrefPageIndexDeprecated, |
| 84 &old_page_index)) { | 85 &old_page_index)) { |
| 85 // Some extensions have invalid page index, so we don't | 86 // Some extensions have invalid page index, so we don't |
| 86 // attempt to convert them. | 87 // attempt to convert them. |
| 87 if (old_page_index < 0) { | 88 if (old_page_index < 0) { |
| 88 DLOG(WARNING) << "Extension " << *ext_id | 89 DLOG(WARNING) << "Extension " << *ext_id |
| 89 << " has an invalid page index " << old_page_index | 90 << " has an invalid page index " << old_page_index |
| 90 << ". Aborting attempt to convert its index."; | 91 << ". Aborting attempt to convert its index."; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 if (app_launches_to_convert.empty()) | 135 if (app_launches_to_convert.empty()) |
| 135 return; | 136 return; |
| 136 | 137 |
| 137 // Create the new app launch ordinals and remove the old preferences. Since | 138 // Create the new app launch ordinals and remove the old preferences. Since |
| 138 // the set is sorted, each time we migrate an apps index, we know that all of | 139 // the set is sorted, each time we migrate an apps index, we know that all of |
| 139 // the remaining apps will appear further down the NTP than it or on a | 140 // the remaining apps will appear further down the NTP than it or on a |
| 140 // different page. | 141 // different page. |
| 141 for (AppPositionToIdMapping::const_iterator page_it = | 142 for (AppPositionToIdMapping::const_iterator page_it = |
| 142 app_launches_to_convert.begin(); | 143 app_launches_to_convert.begin(); |
| 143 page_it != app_launches_to_convert.end(); ++page_it) { | 144 page_it != app_launches_to_convert.end(); ++page_it) { |
| 144 StringOrdinal page = page_it->first; | 145 syncer::StringOrdinal page = page_it->first; |
| 145 for (std::map<int, const std::string*>::const_iterator launch_it = | 146 for (std::map<int, const std::string*>::const_iterator launch_it = |
| 146 page_it->second.begin(); launch_it != page_it->second.end(); | 147 page_it->second.begin(); launch_it != page_it->second.end(); |
| 147 ++launch_it) { | 148 ++launch_it) { |
| 148 SetAppLaunchOrdinal(*(launch_it->second), | 149 SetAppLaunchOrdinal(*(launch_it->second), |
| 149 CreateNextAppLaunchOrdinal(page)); | 150 CreateNextAppLaunchOrdinal(page)); |
| 150 } | 151 } |
| 151 } | 152 } |
| 152 } | 153 } |
| 153 | 154 |
| 154 void ExtensionSorting::FixNTPOrdinalCollisions() { | 155 void ExtensionSorting::FixNTPOrdinalCollisions() { |
| 155 for (PageOrdinalMap::iterator page_it = ntp_ordinal_map_.begin(); | 156 for (PageOrdinalMap::iterator page_it = ntp_ordinal_map_.begin(); |
| 156 page_it != ntp_ordinal_map_.end(); ++page_it) { | 157 page_it != ntp_ordinal_map_.end(); ++page_it) { |
| 157 AppLaunchOrdinalMap& page = page_it->second; | 158 AppLaunchOrdinalMap& page = page_it->second; |
| 158 | 159 |
| 159 AppLaunchOrdinalMap::iterator app_launch_it = page.begin(); | 160 AppLaunchOrdinalMap::iterator app_launch_it = page.begin(); |
| 160 while (app_launch_it != page.end()) { | 161 while (app_launch_it != page.end()) { |
| 161 int app_count = page.count(app_launch_it->first); | 162 int app_count = page.count(app_launch_it->first); |
| 162 if (app_count == 1) { | 163 if (app_count == 1) { |
| 163 ++app_launch_it; | 164 ++app_launch_it; |
| 164 continue; | 165 continue; |
| 165 } | 166 } |
| 166 | 167 |
| 167 StringOrdinal repeated_ordinal = app_launch_it->first; | 168 syncer::StringOrdinal repeated_ordinal = app_launch_it->first; |
| 168 | 169 |
| 169 // Sort the conflicting keys by their extension id, this is how | 170 // Sort the conflicting keys by their extension id, this is how |
| 170 // the order is decided. | 171 // the order is decided. |
| 171 std::vector<std::string> conflicting_ids; | 172 std::vector<std::string> conflicting_ids; |
| 172 for (int i = 0; i < app_count; ++i, ++app_launch_it) | 173 for (int i = 0; i < app_count; ++i, ++app_launch_it) |
| 173 conflicting_ids.push_back(app_launch_it->second); | 174 conflicting_ids.push_back(app_launch_it->second); |
| 174 std::sort(conflicting_ids.begin(), conflicting_ids.end()); | 175 std::sort(conflicting_ids.begin(), conflicting_ids.end()); |
| 175 | 176 |
| 176 StringOrdinal upper_bound_ordinal = app_launch_it == page.end() ? | 177 syncer::StringOrdinal upper_bound_ordinal = app_launch_it == page.end() ? |
| 177 StringOrdinal() : | 178 syncer::StringOrdinal() : |
| 178 app_launch_it->first; | 179 app_launch_it->first; |
| 179 StringOrdinal lower_bound_ordinal = repeated_ordinal; | 180 syncer::StringOrdinal lower_bound_ordinal = repeated_ordinal; |
| 180 | 181 |
| 181 // Start at position 1 because the first extension can keep the conflicted | 182 // Start at position 1 because the first extension can keep the conflicted |
| 182 // value. | 183 // value. |
| 183 for (int i = 1; i < app_count; ++i) { | 184 for (int i = 1; i < app_count; ++i) { |
| 184 StringOrdinal unique_app_launch; | 185 syncer::StringOrdinal unique_app_launch; |
| 185 if (upper_bound_ordinal.IsValid()) { | 186 if (upper_bound_ordinal.IsValid()) { |
| 186 unique_app_launch = | 187 unique_app_launch = |
| 187 lower_bound_ordinal.CreateBetween(upper_bound_ordinal); | 188 lower_bound_ordinal.CreateBetween(upper_bound_ordinal); |
| 188 } else { | 189 } else { |
| 189 unique_app_launch = lower_bound_ordinal.CreateAfter(); | 190 unique_app_launch = lower_bound_ordinal.CreateAfter(); |
| 190 } | 191 } |
| 191 | 192 |
| 192 SetAppLaunchOrdinal(conflicting_ids[i], unique_app_launch); | 193 SetAppLaunchOrdinal(conflicting_ids[i], unique_app_launch); |
| 193 lower_bound_ordinal = unique_app_launch; | 194 lower_bound_ordinal = unique_app_launch; |
| 194 } | 195 } |
| 195 } | 196 } |
| 196 } | 197 } |
| 197 | 198 |
| 198 content::NotificationService::current()->Notify( | 199 content::NotificationService::current()->Notify( |
| 199 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, | 200 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, |
| 200 content::Source<ExtensionSorting>(this), | 201 content::Source<ExtensionSorting>(this), |
| 201 content::NotificationService::NoDetails()); | 202 content::NotificationService::NoDetails()); |
| 202 } | 203 } |
| 203 | 204 |
| 204 void ExtensionSorting::EnsureValidOrdinals(const std::string& extension_id) { | 205 void ExtensionSorting::EnsureValidOrdinals(const std::string& extension_id) { |
| 205 StringOrdinal page_ordinal = GetPageOrdinal(extension_id); | 206 syncer::StringOrdinal page_ordinal = GetPageOrdinal(extension_id); |
| 206 if (!page_ordinal.IsValid()) { | 207 if (!page_ordinal.IsValid()) { |
| 207 // The webstore app should always start be on the first page. | 208 // The webstore app should always start be on the first page. |
| 208 page_ordinal = extension_id == extension_misc::kWebStoreAppId ? | 209 page_ordinal = extension_id == extension_misc::kWebStoreAppId ? |
| 209 CreateFirstAppPageOrdinal() : | 210 CreateFirstAppPageOrdinal() : |
| 210 GetNaturalAppPageOrdinal(); | 211 GetNaturalAppPageOrdinal(); |
| 211 SetPageOrdinal(extension_id, page_ordinal); | 212 SetPageOrdinal(extension_id, page_ordinal); |
| 212 } | 213 } |
| 213 | 214 |
| 214 StringOrdinal app_launch_ordinal = GetAppLaunchOrdinal(extension_id); | 215 syncer::StringOrdinal app_launch_ordinal = GetAppLaunchOrdinal(extension_id); |
| 215 if (!app_launch_ordinal.IsValid()) { | 216 if (!app_launch_ordinal.IsValid()) { |
| 216 // The webstore app should always start in the position. | 217 // The webstore app should always start in the position. |
| 217 app_launch_ordinal = extension_id == extension_misc::kWebStoreAppId ? | 218 app_launch_ordinal = extension_id == extension_misc::kWebStoreAppId ? |
| 218 CreateFirstAppLaunchOrdinal(page_ordinal) : | 219 CreateFirstAppLaunchOrdinal(page_ordinal) : |
| 219 CreateNextAppLaunchOrdinal(page_ordinal); | 220 CreateNextAppLaunchOrdinal(page_ordinal); |
| 220 SetAppLaunchOrdinal(extension_id, | 221 SetAppLaunchOrdinal(extension_id, |
| 221 app_launch_ordinal); | 222 app_launch_ordinal); |
| 222 } | 223 } |
| 223 } | 224 } |
| 224 | 225 |
| 225 void ExtensionSorting::OnExtensionMoved( | 226 void ExtensionSorting::OnExtensionMoved( |
| 226 const std::string& moved_extension_id, | 227 const std::string& moved_extension_id, |
| 227 const std::string& predecessor_extension_id, | 228 const std::string& predecessor_extension_id, |
| 228 const std::string& successor_extension_id) { | 229 const std::string& successor_extension_id) { |
| 229 // We only need to change the StringOrdinal if there are neighbours. | 230 // We only need to change the StringOrdinal if there are neighbours. |
| 230 if (!predecessor_extension_id.empty() || !successor_extension_id.empty()) { | 231 if (!predecessor_extension_id.empty() || !successor_extension_id.empty()) { |
| 231 if (predecessor_extension_id.empty()) { | 232 if (predecessor_extension_id.empty()) { |
| 232 // Only a successor. | 233 // Only a successor. |
| 233 SetAppLaunchOrdinal( | 234 SetAppLaunchOrdinal( |
| 234 moved_extension_id, | 235 moved_extension_id, |
| 235 GetAppLaunchOrdinal(successor_extension_id).CreateBefore()); | 236 GetAppLaunchOrdinal(successor_extension_id).CreateBefore()); |
| 236 } else if (successor_extension_id.empty()) { | 237 } else if (successor_extension_id.empty()) { |
| 237 // Only a predecessor. | 238 // Only a predecessor. |
| 238 SetAppLaunchOrdinal( | 239 SetAppLaunchOrdinal( |
| 239 moved_extension_id, | 240 moved_extension_id, |
| 240 GetAppLaunchOrdinal(predecessor_extension_id).CreateAfter()); | 241 GetAppLaunchOrdinal(predecessor_extension_id).CreateAfter()); |
| 241 } else { | 242 } else { |
| 242 // Both a successor and predecessor | 243 // Both a successor and predecessor |
| 243 const StringOrdinal& predecessor_ordinal = | 244 const syncer::StringOrdinal& predecessor_ordinal = |
| 244 GetAppLaunchOrdinal(predecessor_extension_id); | 245 GetAppLaunchOrdinal(predecessor_extension_id); |
| 245 const StringOrdinal& successor_ordinal = | 246 const syncer::StringOrdinal& successor_ordinal = |
| 246 GetAppLaunchOrdinal(successor_extension_id); | 247 GetAppLaunchOrdinal(successor_extension_id); |
| 247 SetAppLaunchOrdinal(moved_extension_id, | 248 SetAppLaunchOrdinal(moved_extension_id, |
| 248 predecessor_ordinal.CreateBetween(successor_ordinal)); | 249 predecessor_ordinal.CreateBetween(successor_ordinal)); |
| 249 } | 250 } |
| 250 } | 251 } |
| 251 | 252 |
| 252 content::NotificationService::current()->Notify( | 253 content::NotificationService::current()->Notify( |
| 253 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, | 254 chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED, |
| 254 content::Source<ExtensionSorting>(this), | 255 content::Source<ExtensionSorting>(this), |
| 255 content::Details<const std::string>(&moved_extension_id)); | 256 content::Details<const std::string>(&moved_extension_id)); |
| 256 } | 257 } |
| 257 | 258 |
| 258 | 259 |
| 259 StringOrdinal ExtensionSorting::GetAppLaunchOrdinal( | 260 syncer::StringOrdinal ExtensionSorting::GetAppLaunchOrdinal( |
| 260 const std::string& extension_id) const { | 261 const std::string& extension_id) const { |
| 261 std::string raw_value; | 262 std::string raw_value; |
| 262 // If the preference read fails then raw_value will still be unset and we | 263 // If the preference read fails then raw_value will still be unset and we |
| 263 // will return an invalid StringOrdinal to signal that no app launch ordinal | 264 // will return an invalid StringOrdinal to signal that no app launch ordinal |
| 264 // was found. | 265 // was found. |
| 265 extension_scoped_prefs_->ReadExtensionPrefString( | 266 extension_scoped_prefs_->ReadExtensionPrefString( |
| 266 extension_id, kPrefAppLaunchOrdinal, &raw_value); | 267 extension_id, kPrefAppLaunchOrdinal, &raw_value); |
| 267 return StringOrdinal(raw_value); | 268 return syncer::StringOrdinal(raw_value); |
| 268 } | 269 } |
| 269 | 270 |
| 270 void ExtensionSorting::SetAppLaunchOrdinal( | 271 void ExtensionSorting::SetAppLaunchOrdinal( |
| 271 const std::string& extension_id, | 272 const std::string& extension_id, |
| 272 const StringOrdinal& new_app_launch_ordinal) { | 273 const syncer::StringOrdinal& new_app_launch_ordinal) { |
| 273 // No work is required if the old and new values are the same. | 274 // No work is required if the old and new values are the same. |
| 274 if (new_app_launch_ordinal.EqualOrBothInvalid( | 275 if (new_app_launch_ordinal.EqualsOrBothInvalid( |
| 275 GetAppLaunchOrdinal(extension_id))) { | 276 GetAppLaunchOrdinal(extension_id))) { |
| 276 return; | 277 return; |
| 277 } | 278 } |
| 278 | 279 |
| 279 StringOrdinal page_ordinal = GetPageOrdinal(extension_id); | 280 syncer::StringOrdinal page_ordinal = GetPageOrdinal(extension_id); |
| 280 RemoveOrdinalMapping( | 281 RemoveOrdinalMapping( |
| 281 extension_id, page_ordinal, GetAppLaunchOrdinal(extension_id)); | 282 extension_id, page_ordinal, GetAppLaunchOrdinal(extension_id)); |
| 282 AddOrdinalMapping(extension_id, page_ordinal, new_app_launch_ordinal); | 283 AddOrdinalMapping(extension_id, page_ordinal, new_app_launch_ordinal); |
| 283 | 284 |
| 284 Value* new_value = new_app_launch_ordinal.IsValid() ? | 285 Value* new_value = new_app_launch_ordinal.IsValid() ? |
| 285 Value::CreateStringValue(new_app_launch_ordinal.ToString()) : | 286 Value::CreateStringValue(new_app_launch_ordinal.ToInternalValue()) : |
| 286 NULL; | 287 NULL; |
| 287 | 288 |
| 288 extension_scoped_prefs_->UpdateExtensionPref( | 289 extension_scoped_prefs_->UpdateExtensionPref( |
| 289 extension_id, | 290 extension_id, |
| 290 kPrefAppLaunchOrdinal, | 291 kPrefAppLaunchOrdinal, |
| 291 new_value); | 292 new_value); |
| 292 SyncIfNeeded(extension_id); | 293 SyncIfNeeded(extension_id); |
| 293 } | 294 } |
| 294 | 295 |
| 295 StringOrdinal ExtensionSorting::CreateFirstAppLaunchOrdinal( | 296 syncer::StringOrdinal ExtensionSorting::CreateFirstAppLaunchOrdinal( |
| 296 const StringOrdinal& page_ordinal) const { | 297 const syncer::StringOrdinal& page_ordinal) const { |
| 297 const StringOrdinal& min_ordinal = | 298 const syncer::StringOrdinal& min_ordinal = |
| 298 GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal, | 299 GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal, |
| 299 ExtensionSorting::MIN_ORDINAL); | 300 ExtensionSorting::MIN_ORDINAL); |
| 300 | 301 |
| 301 if (min_ordinal.IsValid()) | 302 if (min_ordinal.IsValid()) |
| 302 return min_ordinal.CreateBefore(); | 303 return min_ordinal.CreateBefore(); |
| 303 else | 304 else |
| 304 return StringOrdinal::CreateInitialOrdinal(); | 305 return syncer::StringOrdinal::CreateInitialOrdinal(); |
| 305 } | 306 } |
| 306 | 307 |
| 307 StringOrdinal ExtensionSorting::CreateNextAppLaunchOrdinal( | 308 syncer::StringOrdinal ExtensionSorting::CreateNextAppLaunchOrdinal( |
| 308 const StringOrdinal& page_ordinal) const { | 309 const syncer::StringOrdinal& page_ordinal) const { |
| 309 const StringOrdinal& max_ordinal = | 310 const syncer::StringOrdinal& max_ordinal = |
| 310 GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal, | 311 GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal, |
| 311 ExtensionSorting::MAX_ORDINAL); | 312 ExtensionSorting::MAX_ORDINAL); |
| 312 | 313 |
| 313 if (max_ordinal.IsValid()) | 314 if (max_ordinal.IsValid()) |
| 314 return max_ordinal.CreateAfter(); | 315 return max_ordinal.CreateAfter(); |
| 315 else | 316 else |
| 316 return StringOrdinal::CreateInitialOrdinal(); | 317 return syncer::StringOrdinal::CreateInitialOrdinal(); |
| 317 } | 318 } |
| 318 | 319 |
| 319 StringOrdinal ExtensionSorting::CreateFirstAppPageOrdinal() const { | 320 syncer::StringOrdinal ExtensionSorting::CreateFirstAppPageOrdinal() const { |
| 320 const DictionaryValue* extensions = pref_service_->GetDictionary( | 321 const DictionaryValue* extensions = pref_service_->GetDictionary( |
| 321 ExtensionPrefs::kExtensionsPref); | 322 ExtensionPrefs::kExtensionsPref); |
| 322 CHECK(extensions); | 323 CHECK(extensions); |
| 323 | 324 |
| 324 if (ntp_ordinal_map_.empty()) | 325 if (ntp_ordinal_map_.empty()) |
| 325 return StringOrdinal::CreateInitialOrdinal(); | 326 return syncer::StringOrdinal::CreateInitialOrdinal(); |
| 326 | 327 |
| 327 return ntp_ordinal_map_.begin()->first; | 328 return ntp_ordinal_map_.begin()->first; |
| 328 } | 329 } |
| 329 | 330 |
| 330 StringOrdinal ExtensionSorting::GetNaturalAppPageOrdinal() const { | 331 syncer::StringOrdinal ExtensionSorting::GetNaturalAppPageOrdinal() const { |
| 331 const DictionaryValue* extensions = pref_service_->GetDictionary( | 332 const DictionaryValue* extensions = pref_service_->GetDictionary( |
| 332 ExtensionPrefs::kExtensionsPref); | 333 ExtensionPrefs::kExtensionsPref); |
| 333 CHECK(extensions); | 334 CHECK(extensions); |
| 334 | 335 |
| 335 if (ntp_ordinal_map_.empty()) | 336 if (ntp_ordinal_map_.empty()) |
| 336 return StringOrdinal::CreateInitialOrdinal(); | 337 return syncer::StringOrdinal::CreateInitialOrdinal(); |
| 337 | 338 |
| 338 for (PageOrdinalMap::const_iterator it = ntp_ordinal_map_.begin(); | 339 for (PageOrdinalMap::const_iterator it = ntp_ordinal_map_.begin(); |
| 339 it != ntp_ordinal_map_.end(); ++it) { | 340 it != ntp_ordinal_map_.end(); ++it) { |
| 340 if (it->second.size() < kNaturalAppPageSize) | 341 if (it->second.size() < kNaturalAppPageSize) |
| 341 return it->first; | 342 return it->first; |
| 342 } | 343 } |
| 343 | 344 |
| 344 // Add a new page as all existing pages are full. | 345 // Add a new page as all existing pages are full. |
| 345 StringOrdinal last_element = ntp_ordinal_map_.rbegin()->first; | 346 syncer::StringOrdinal last_element = ntp_ordinal_map_.rbegin()->first; |
| 346 return last_element.CreateAfter(); | 347 return last_element.CreateAfter(); |
| 347 } | 348 } |
| 348 | 349 |
| 349 StringOrdinal ExtensionSorting::GetPageOrdinal(const std::string& extension_id) | 350 syncer::StringOrdinal ExtensionSorting::GetPageOrdinal( |
| 350 const { | 351 const std::string& extension_id) const { |
| 351 std::string raw_data; | 352 std::string raw_data; |
| 352 // If the preference read fails then raw_data will still be unset and we will | 353 // If the preference read fails then raw_data will still be unset and we will |
| 353 // return an invalid StringOrdinal to signal that no page ordinal was found. | 354 // return an invalid StringOrdinal to signal that no page ordinal was found. |
| 354 extension_scoped_prefs_->ReadExtensionPrefString( | 355 extension_scoped_prefs_->ReadExtensionPrefString( |
| 355 extension_id, kPrefPageOrdinal, &raw_data); | 356 extension_id, kPrefPageOrdinal, &raw_data); |
| 356 return StringOrdinal(raw_data); | 357 return syncer::StringOrdinal(raw_data); |
| 357 } | 358 } |
| 358 | 359 |
| 359 void ExtensionSorting::SetPageOrdinal(const std::string& extension_id, | 360 void ExtensionSorting::SetPageOrdinal( |
| 360 const StringOrdinal& new_page_ordinal) { | 361 const std::string& extension_id, |
| 362 const syncer::StringOrdinal& new_page_ordinal) { |
| 361 // No work is required if the old and new values are the same. | 363 // No work is required if the old and new values are the same. |
| 362 if (new_page_ordinal.EqualOrBothInvalid(GetPageOrdinal(extension_id))) | 364 if (new_page_ordinal.EqualsOrBothInvalid(GetPageOrdinal(extension_id))) |
| 363 return; | 365 return; |
| 364 | 366 |
| 365 StringOrdinal app_launch_ordinal = GetAppLaunchOrdinal(extension_id); | 367 syncer::StringOrdinal app_launch_ordinal = GetAppLaunchOrdinal(extension_id); |
| 366 RemoveOrdinalMapping( | 368 RemoveOrdinalMapping( |
| 367 extension_id, GetPageOrdinal(extension_id), app_launch_ordinal); | 369 extension_id, GetPageOrdinal(extension_id), app_launch_ordinal); |
| 368 AddOrdinalMapping(extension_id, new_page_ordinal, app_launch_ordinal); | 370 AddOrdinalMapping(extension_id, new_page_ordinal, app_launch_ordinal); |
| 369 | 371 |
| 370 Value* new_value = new_page_ordinal.IsValid() ? | 372 Value* new_value = new_page_ordinal.IsValid() ? |
| 371 Value::CreateStringValue(new_page_ordinal.ToString()) : | 373 Value::CreateStringValue(new_page_ordinal.ToInternalValue()) : |
| 372 NULL; | 374 NULL; |
| 373 | 375 |
| 374 extension_scoped_prefs_->UpdateExtensionPref( | 376 extension_scoped_prefs_->UpdateExtensionPref( |
| 375 extension_id, | 377 extension_id, |
| 376 kPrefPageOrdinal, | 378 kPrefPageOrdinal, |
| 377 new_value); | 379 new_value); |
| 378 SyncIfNeeded(extension_id); | 380 SyncIfNeeded(extension_id); |
| 379 } | 381 } |
| 380 | 382 |
| 381 void ExtensionSorting::ClearOrdinals(const std::string& extension_id) { | 383 void ExtensionSorting::ClearOrdinals(const std::string& extension_id) { |
| 382 RemoveOrdinalMapping(extension_id, | 384 RemoveOrdinalMapping(extension_id, |
| 383 GetPageOrdinal(extension_id), | 385 GetPageOrdinal(extension_id), |
| 384 GetAppLaunchOrdinal(extension_id)); | 386 GetAppLaunchOrdinal(extension_id)); |
| 385 | 387 |
| 386 extension_scoped_prefs_->UpdateExtensionPref( | 388 extension_scoped_prefs_->UpdateExtensionPref( |
| 387 extension_id, kPrefPageOrdinal, NULL); | 389 extension_id, kPrefPageOrdinal, NULL); |
| 388 extension_scoped_prefs_->UpdateExtensionPref( | 390 extension_scoped_prefs_->UpdateExtensionPref( |
| 389 extension_id, kPrefAppLaunchOrdinal, NULL); | 391 extension_id, kPrefAppLaunchOrdinal, NULL); |
| 390 } | 392 } |
| 391 | 393 |
| 392 int ExtensionSorting::PageStringOrdinalAsInteger( | 394 int ExtensionSorting::PageStringOrdinalAsInteger( |
| 393 const StringOrdinal& page_ordinal) const { | 395 const syncer::StringOrdinal& page_ordinal) const { |
| 394 if (!page_ordinal.IsValid()) | 396 if (!page_ordinal.IsValid()) |
| 395 return -1; | 397 return -1; |
| 396 | 398 |
| 397 PageOrdinalMap::const_iterator it = ntp_ordinal_map_.find(page_ordinal); | 399 PageOrdinalMap::const_iterator it = ntp_ordinal_map_.find(page_ordinal); |
| 398 return it != ntp_ordinal_map_.end() ? | 400 return it != ntp_ordinal_map_.end() ? |
| 399 std::distance(ntp_ordinal_map_.begin(), it) : -1; | 401 std::distance(ntp_ordinal_map_.begin(), it) : -1; |
| 400 } | 402 } |
| 401 | 403 |
| 402 StringOrdinal ExtensionSorting::PageIntegerAsStringOrdinal(size_t page_index) { | 404 syncer::StringOrdinal ExtensionSorting::PageIntegerAsStringOrdinal( |
| 405 size_t page_index) { |
| 403 const DictionaryValue* extensions = pref_service_->GetDictionary( | 406 const DictionaryValue* extensions = pref_service_->GetDictionary( |
| 404 ExtensionPrefs::kExtensionsPref); | 407 ExtensionPrefs::kExtensionsPref); |
| 405 | 408 |
| 406 if (!extensions) | 409 if (!extensions) |
| 407 return StringOrdinal(); | 410 return syncer::StringOrdinal(); |
| 408 | 411 |
| 409 if (page_index < ntp_ordinal_map_.size()) { | 412 if (page_index < ntp_ordinal_map_.size()) { |
| 410 PageOrdinalMap::const_iterator it = ntp_ordinal_map_.begin(); | 413 PageOrdinalMap::const_iterator it = ntp_ordinal_map_.begin(); |
| 411 std::advance(it, page_index); | 414 std::advance(it, page_index); |
| 412 return it->first; | 415 return it->first; |
| 413 } | 416 } |
| 414 | 417 |
| 415 CreateOrdinalsIfNecessary(page_index + 1); | 418 CreateOrdinalsIfNecessary(page_index + 1); |
| 416 return ntp_ordinal_map_.rbegin()->first; | 419 return ntp_ordinal_map_.rbegin()->first; |
| 417 } | 420 } |
| 418 | 421 |
| 419 StringOrdinal ExtensionSorting::GetMinOrMaxAppLaunchOrdinalsOnPage( | 422 syncer::StringOrdinal ExtensionSorting::GetMinOrMaxAppLaunchOrdinalsOnPage( |
| 420 const StringOrdinal& target_page_ordinal, | 423 const syncer::StringOrdinal& target_page_ordinal, |
| 421 AppLaunchOrdinalReturn return_type) const { | 424 AppLaunchOrdinalReturn return_type) const { |
| 422 CHECK(target_page_ordinal.IsValid()); | 425 CHECK(target_page_ordinal.IsValid()); |
| 423 | 426 |
| 424 StringOrdinal return_value; | 427 syncer::StringOrdinal return_value; |
| 425 | 428 |
| 426 PageOrdinalMap::const_iterator page = | 429 PageOrdinalMap::const_iterator page = |
| 427 ntp_ordinal_map_.find(target_page_ordinal); | 430 ntp_ordinal_map_.find(target_page_ordinal); |
| 428 if (page != ntp_ordinal_map_.end()) { | 431 if (page != ntp_ordinal_map_.end()) { |
| 429 const AppLaunchOrdinalMap& app_list = page->second; | 432 const AppLaunchOrdinalMap& app_list = page->second; |
| 430 | 433 |
| 431 if (app_list.empty()) | 434 if (app_list.empty()) |
| 432 return StringOrdinal(); | 435 return syncer::StringOrdinal(); |
| 433 | 436 |
| 434 if (return_type == ExtensionSorting::MAX_ORDINAL) | 437 if (return_type == ExtensionSorting::MAX_ORDINAL) |
| 435 return_value = app_list.rbegin()->first; | 438 return_value = app_list.rbegin()->first; |
| 436 else if (return_type == ExtensionSorting::MIN_ORDINAL) | 439 else if (return_type == ExtensionSorting::MIN_ORDINAL) |
| 437 return_value = app_list.begin()->first; | 440 return_value = app_list.begin()->first; |
| 438 } | 441 } |
| 439 | 442 |
| 440 return return_value; | 443 return return_value; |
| 441 } | 444 } |
| 442 | 445 |
| 443 void ExtensionSorting::InitializePageOrdinalMap( | 446 void ExtensionSorting::InitializePageOrdinalMap( |
| 444 const ExtensionPrefs::ExtensionIds& extension_ids) { | 447 const ExtensionPrefs::ExtensionIds& extension_ids) { |
| 445 for (ExtensionPrefs::ExtensionIds::const_iterator ext_it = | 448 for (ExtensionPrefs::ExtensionIds::const_iterator ext_it = |
| 446 extension_ids.begin(); ext_it != extension_ids.end(); ++ext_it) { | 449 extension_ids.begin(); ext_it != extension_ids.end(); ++ext_it) { |
| 447 AddOrdinalMapping(*ext_it, | 450 AddOrdinalMapping(*ext_it, |
| 448 GetPageOrdinal(*ext_it), | 451 GetPageOrdinal(*ext_it), |
| 449 GetAppLaunchOrdinal(*ext_it)); | 452 GetAppLaunchOrdinal(*ext_it)); |
| 450 | 453 |
| 451 // Ensure that the web store app still isn't found in this list, since | 454 // Ensure that the web store app still isn't found in this list, since |
| 452 // it is added after this loop. | 455 // it is added after this loop. |
| 453 DCHECK(*ext_it != extension_misc::kWebStoreAppId); | 456 DCHECK(*ext_it != extension_misc::kWebStoreAppId); |
| 454 } | 457 } |
| 455 | 458 |
| 456 // Include the Web Store App since it is displayed on the NTP. | 459 // Include the Web Store App since it is displayed on the NTP. |
| 457 StringOrdinal web_store_app_page = | 460 syncer::StringOrdinal web_store_app_page = |
| 458 GetPageOrdinal(extension_misc::kWebStoreAppId); | 461 GetPageOrdinal(extension_misc::kWebStoreAppId); |
| 459 if (web_store_app_page.IsValid()) { | 462 if (web_store_app_page.IsValid()) { |
| 460 AddOrdinalMapping(extension_misc::kWebStoreAppId, | 463 AddOrdinalMapping(extension_misc::kWebStoreAppId, |
| 461 web_store_app_page, | 464 web_store_app_page, |
| 462 GetAppLaunchOrdinal(extension_misc::kWebStoreAppId)); | 465 GetAppLaunchOrdinal(extension_misc::kWebStoreAppId)); |
| 463 } | 466 } |
| 464 } | 467 } |
| 465 | 468 |
| 466 void ExtensionSorting::AddOrdinalMapping( | 469 void ExtensionSorting::AddOrdinalMapping( |
| 467 const std::string& extension_id, | 470 const std::string& extension_id, |
| 468 const StringOrdinal& page_ordinal, | 471 const syncer::StringOrdinal& page_ordinal, |
| 469 const StringOrdinal& app_launch_ordinal) { | 472 const syncer::StringOrdinal& app_launch_ordinal) { |
| 470 if (!page_ordinal.IsValid() || !app_launch_ordinal.IsValid()) | 473 if (!page_ordinal.IsValid() || !app_launch_ordinal.IsValid()) |
| 471 return; | 474 return; |
| 472 | 475 |
| 473 ntp_ordinal_map_[page_ordinal].insert( | 476 ntp_ordinal_map_[page_ordinal].insert( |
| 474 std::make_pair(app_launch_ordinal, extension_id)); | 477 std::make_pair(app_launch_ordinal, extension_id)); |
| 475 } | 478 } |
| 476 | 479 |
| 477 void ExtensionSorting::RemoveOrdinalMapping( | 480 void ExtensionSorting::RemoveOrdinalMapping( |
| 478 const std::string& extension_id, | 481 const std::string& extension_id, |
| 479 const StringOrdinal& page_ordinal, | 482 const syncer::StringOrdinal& page_ordinal, |
| 480 const StringOrdinal& app_launch_ordinal) { | 483 const syncer::StringOrdinal& app_launch_ordinal) { |
| 481 if (!page_ordinal.IsValid() || !app_launch_ordinal.IsValid()) | 484 if (!page_ordinal.IsValid() || !app_launch_ordinal.IsValid()) |
| 482 return; | 485 return; |
| 483 | 486 |
| 484 // Check that the page exists using find to prevent creating a new page | 487 // Check that the page exists using find to prevent creating a new page |
| 485 // if |page_ordinal| isn't a used page. | 488 // if |page_ordinal| isn't a used page. |
| 486 PageOrdinalMap::iterator page_map = ntp_ordinal_map_.find(page_ordinal); | 489 PageOrdinalMap::iterator page_map = ntp_ordinal_map_.find(page_ordinal); |
| 487 if (page_map == ntp_ordinal_map_.end()) | 490 if (page_map == ntp_ordinal_map_.end()) |
| 488 return; | 491 return; |
| 489 | 492 |
| 490 for (AppLaunchOrdinalMap::iterator it = | 493 for (AppLaunchOrdinalMap::iterator it = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 505 if (ext) { | 508 if (ext) { |
| 506 // It is possible for old extension to have ordinal values, but they | 509 // It is possible for old extension to have ordinal values, but they |
| 507 // shouldn't so we clear them. | 510 // shouldn't so we clear them. |
| 508 if (!ext->is_app()) | 511 if (!ext->is_app()) |
| 509 ClearOrdinals(extension_id); | 512 ClearOrdinals(extension_id); |
| 510 | 513 |
| 511 extension_service_->SyncExtensionChangeIfNeeded(*ext); | 514 extension_service_->SyncExtensionChangeIfNeeded(*ext); |
| 512 } | 515 } |
| 513 } | 516 } |
| 514 } | 517 } |
| OLD | NEW |