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/ui/app_list/apps_model_builder.h" | 5 #include "chrome/browser/ui/app_list/apps_model_builder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
11 #include "chrome/browser/chrome_notification_types.h" | 11 #include "chrome/browser/chrome_notification_types.h" |
12 #include "chrome/browser/extensions/extension_prefs.h" | 12 #include "chrome/browser/extensions/extension_prefs.h" |
13 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
14 #include "chrome/browser/extensions/extension_sorting.h" | 14 #include "chrome/browser/extensions/extension_sorting.h" |
15 #include "chrome/browser/extensions/extension_system.h" | 15 #include "chrome/browser/extensions/extension_system.h" |
16 #include "chrome/browser/extensions/install_tracker.h" | 16 #include "chrome/browser/extensions/install_tracker.h" |
17 #include "chrome/browser/extensions/install_tracker_factory.h" | 17 #include "chrome/browser/extensions/install_tracker_factory.h" |
18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/ui/app_list/extension_app_item.h" | 19 #include "chrome/browser/ui/app_list/extension_app_item.h" |
20 #include "chrome/common/extensions/extension.h" | 20 #include "chrome/common/extensions/extension.h" |
21 #include "chrome/common/extensions/extension_constants.h" | 21 #include "chrome/common/extensions/extension_constants.h" |
22 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
23 #include "content/public/browser/notification_service.h" | 23 #include "content/public/browser/notification_service.h" |
24 #include "ui/gfx/image/image_skia.h" | 24 #include "ui/gfx/image/image_skia.h" |
25 | 25 |
26 using extensions::Extension; | 26 using extensions::Extension; |
27 using app_list::AppListItemModel; | |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 bool AppPrecedes(const ExtensionAppItem* app1, const ExtensionAppItem* app2) { | 31 bool AppPrecedes(const ExtensionAppItem* app1, const ExtensionAppItem* app2) { |
32 if (!app1) | |
33 return app2; // non-ExtensionAppItem follows ExtensionAppItem | |
34 if (!app2) | |
35 return true; // ExtensionAppItem preceeds non-ExtensionAppItem | |
jennyz
2013/10/03 20:45:51
Do you mean we should pass null for non-ExtensionA
| |
31 const syncer::StringOrdinal& page1 = app1->GetPageOrdinal(); | 36 const syncer::StringOrdinal& page1 = app1->GetPageOrdinal(); |
32 const syncer::StringOrdinal& page2 = app2->GetPageOrdinal(); | 37 const syncer::StringOrdinal& page2 = app2->GetPageOrdinal(); |
33 if (page1.LessThan(page2)) | 38 if (page1.LessThan(page2)) |
34 return true; | 39 return true; |
35 | 40 |
36 if (page1.Equals(page2)) | 41 if (page1.Equals(page2)) |
37 return app1->GetAppLaunchOrdinal().LessThan(app2->GetAppLaunchOrdinal()); | 42 return app1->GetAppLaunchOrdinal().LessThan(app2->GetAppLaunchOrdinal()); |
38 | 43 |
39 return false; | 44 return false; |
40 } | 45 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 return; | 106 return; |
102 model_->DeleteAt(i); | 107 model_->DeleteAt(i); |
103 } | 108 } |
104 | 109 |
105 void AppsModelBuilder::OnExtensionLoaded(const Extension* extension) { | 110 void AppsModelBuilder::OnExtensionLoaded(const Extension* extension) { |
106 if (!extension->ShouldDisplayInAppLauncher()) | 111 if (!extension->ShouldDisplayInAppLauncher()) |
107 return; | 112 return; |
108 | 113 |
109 const int existing_index = FindApp(extension->id()); | 114 const int existing_index = FindApp(extension->id()); |
110 if (existing_index != -1) { | 115 if (existing_index != -1) { |
111 GetAppAt(existing_index)->Reload(); | 116 GetAppAt(existing_index)->Update(); |
112 return; | 117 return; |
113 } | 118 } |
114 | 119 |
115 InsertApp(new ExtensionAppItem(profile_, | 120 InsertApp(new ExtensionAppItem(profile_, |
116 extension->id(), | 121 extension->id(), |
117 controller_, | 122 controller_, |
118 "", | 123 "", |
119 gfx::ImageSkia(), | 124 gfx::ImageSkia(), |
120 extension->is_platform_app())); | 125 extension->is_platform_app())); |
121 UpdateHighlight(); | 126 UpdateHighlight(); |
122 } | 127 } |
123 | 128 |
124 void AppsModelBuilder::OnExtensionUnloaded(const Extension* extension) { | 129 void AppsModelBuilder::OnExtensionUnloaded(const Extension* extension) { |
125 int index = FindApp(extension->id()); | 130 int index = FindApp(extension->id()); |
126 if (index < 0) | 131 if (index < 0) |
127 return; | 132 return; |
128 GetAppAt(index)->UpdateIcon(); | 133 GetAppAt(index)->Update(); |
129 } | 134 } |
130 | 135 |
131 void AppsModelBuilder::OnExtensionUninstalled(const Extension* extension) { | 136 void AppsModelBuilder::OnExtensionUninstalled(const Extension* extension) { |
132 int index = FindApp(extension->id()); | 137 int index = FindApp(extension->id()); |
133 if (index < 0) | 138 if (index < 0) |
134 return; | 139 return; |
135 model_->DeleteAt(index); | 140 model_->DeleteAt(index); |
136 } | 141 } |
137 | 142 |
138 void AppsModelBuilder::OnAppsReordered() { | 143 void AppsModelBuilder::OnAppsReordered() { |
139 ResortApps(); | 144 ResortApps(); |
140 } | 145 } |
141 | 146 |
142 void AppsModelBuilder::OnAppInstalledToAppList( | 147 void AppsModelBuilder::OnAppInstalledToAppList( |
143 const std::string& extension_id) { | 148 const std::string& extension_id) { |
144 SetHighlightedApp(extension_id); | 149 SetHighlightedApp(extension_id); |
145 } | 150 } |
146 | 151 |
147 void AppsModelBuilder::OnShutdown() { | 152 void AppsModelBuilder::OnShutdown() { |
148 if (tracker_) { | 153 if (tracker_) { |
149 tracker_->RemoveObserver(this); | 154 tracker_->RemoveObserver(this); |
150 tracker_ = NULL; | 155 tracker_ = NULL; |
151 } | 156 } |
152 } | 157 } |
153 | 158 |
154 void AppsModelBuilder::AddApps(const ExtensionSet* extensions, Apps* apps) { | 159 void AppsModelBuilder::AddApps(const ExtensionSet* extensions, |
160 ExtensionApps* apps) { | |
155 for (ExtensionSet::const_iterator app = extensions->begin(); | 161 for (ExtensionSet::const_iterator app = extensions->begin(); |
156 app != extensions->end(); ++app) { | 162 app != extensions->end(); ++app) { |
157 if (ShouldDisplayInAppLauncher(profile_, *app)) | 163 if (ShouldDisplayInAppLauncher(profile_, *app)) |
158 apps->push_back(new ExtensionAppItem(profile_, | 164 apps->push_back(new ExtensionAppItem(profile_, |
159 (*app)->id(), | 165 (*app)->id(), |
160 controller_, | 166 controller_, |
161 "", | 167 "", |
162 gfx::ImageSkia(), | 168 gfx::ImageSkia(), |
163 (*app)->is_platform_app())); | 169 (*app)->is_platform_app())); |
164 } | 170 } |
(...skipping 18 matching lines...) Expand all Loading... | |
183 // Start observing after model is built. | 189 // Start observing after model is built. |
184 tracker_->AddObserver(this); | 190 tracker_->AddObserver(this); |
185 } | 191 } |
186 | 192 |
187 void AppsModelBuilder::PopulateApps() { | 193 void AppsModelBuilder::PopulateApps() { |
188 ExtensionService* service = | 194 ExtensionService* service = |
189 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 195 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
190 if (!service) | 196 if (!service) |
191 return; | 197 return; |
192 | 198 |
193 Apps apps; | 199 ExtensionApps apps; |
194 AddApps(service->extensions(), &apps); | 200 AddApps(service->extensions(), &apps); |
195 AddApps(service->disabled_extensions(), &apps); | 201 AddApps(service->disabled_extensions(), &apps); |
196 AddApps(service->terminated_extensions(), &apps); | 202 AddApps(service->terminated_extensions(), &apps); |
197 | 203 |
198 if (apps.empty()) | 204 if (apps.empty()) |
199 return; | 205 return; |
200 | 206 |
201 service->extension_prefs()->extension_sorting()->FixNTPOrdinalCollisions(); | 207 service->extension_prefs()->extension_sorting()->FixNTPOrdinalCollisions(); |
202 std::sort(apps.begin(), apps.end(), &AppPrecedes); | 208 std::sort(apps.begin(), apps.end(), &AppPrecedes); |
203 | 209 |
204 for (size_t i = 0; i < apps.size(); ++i) | 210 for (size_t i = 0; i < apps.size(); ++i) |
205 model_->Add(apps[i]); | 211 model_->Add(apps[i]); |
206 } | 212 } |
207 | 213 |
208 void AppsModelBuilder::ResortApps() { | 214 void AppsModelBuilder::ResortApps() { |
209 // Scan app items in |model_| and put the apps that do not have valid ordinals | 215 // Scan app items in |model_| and put the apps that do not have valid ordinals |
210 // into |invalid_ordinal_apps|. This is needed to handle uninstalling a | 216 // into |invalid_ordinal_apps|. This is needed to handle uninstalling a |
211 // terminated app case, where there is no unload notification and uninstall | 217 // terminated app case, where there is no unload notification and uninstall |
212 // notification comes in after the app's ordinals are cleared. | 218 // notification comes in after the app's ordinals are cleared. |
213 // See http://crbug.com/256749. | 219 // See http://crbug.com/256749. |
214 Apps apps; | 220 ExtensionApps apps; |
215 Apps invalid_ordinal_apps; | 221 ExtensionApps invalid_ordinal_apps; |
216 for (size_t i = 0; i < model_->item_count(); ++i) { | 222 for (size_t i = 0; i < model_->item_count(); ++i) { |
217 ExtensionAppItem* app = GetAppAt(i); | 223 ExtensionAppItem* app = GetExtensionAppAt(i); |
218 if (app->GetPageOrdinal().IsValid() && app->GetAppLaunchOrdinal().IsValid()) | 224 if (app->GetPageOrdinal().IsValid() && app->GetAppLaunchOrdinal().IsValid()) |
219 apps.push_back(app); | 225 apps.push_back(app); |
220 else | 226 else |
221 invalid_ordinal_apps.push_back(app); | 227 invalid_ordinal_apps.push_back(app); |
222 } | 228 } |
223 | 229 |
224 std::sort(apps.begin(), apps.end(), &AppPrecedes); | 230 std::sort(apps.begin(), apps.end(), &AppPrecedes); |
225 apps.insert( | 231 apps.insert( |
226 apps.end(), invalid_ordinal_apps.begin(), invalid_ordinal_apps.end()); | 232 apps.end(), invalid_ordinal_apps.begin(), invalid_ordinal_apps.end()); |
227 | 233 |
(...skipping 14 matching lines...) Expand all Loading... | |
242 } | 248 } |
243 | 249 |
244 void AppsModelBuilder::InsertApp(ExtensionAppItem* app) { | 250 void AppsModelBuilder::InsertApp(ExtensionAppItem* app) { |
245 DCHECK(model_); | 251 DCHECK(model_); |
246 | 252 |
247 size_t start = 0; | 253 size_t start = 0; |
248 size_t end = model_->item_count(); | 254 size_t end = model_->item_count(); |
249 while (start < end) { | 255 while (start < end) { |
250 size_t mid = (start + end) / 2; | 256 size_t mid = (start + end) / 2; |
251 | 257 |
252 if (AppPrecedes(GetAppAt(mid), app)) | 258 if (AppPrecedes(GetExtensionAppAt(mid), app)) |
253 start = mid + 1; | 259 start = mid + 1; |
254 else | 260 else |
255 end = mid; | 261 end = mid; |
256 } | 262 } |
257 model_->AddAt(start, app); | 263 model_->AddAt(start, app); |
258 } | 264 } |
259 | 265 |
260 int AppsModelBuilder::FindApp(const std::string& app_id) { | 266 int AppsModelBuilder::FindApp(const std::string& app_id) { |
261 DCHECK(model_); | 267 DCHECK(model_); |
262 | 268 |
263 for (size_t i = 0; i < model_->item_count(); ++i) { | 269 for (size_t i = 0; i < model_->item_count(); ++i) { |
264 if (GetAppAt(i)->extension_id() == app_id) | 270 if (GetAppAt(i)->app_id() == app_id) |
265 return i; | 271 return i; |
266 } | 272 } |
267 | 273 |
268 return -1; | 274 return -1; |
269 } | 275 } |
270 | 276 |
271 void AppsModelBuilder::SetHighlightedApp(const std::string& extension_id) { | 277 void AppsModelBuilder::SetHighlightedApp(const std::string& extension_id) { |
272 if (extension_id == highlight_app_id_) | 278 if (extension_id == highlight_app_id_) |
273 return; | 279 return; |
274 ExtensionAppItem* old_app = GetApp(highlight_app_id_); | 280 AppListItemModel* old_app = GetApp(highlight_app_id_); |
275 if (old_app) | 281 if (old_app) |
276 old_app->SetHighlighted(false); | 282 old_app->SetHighlighted(false); |
277 highlight_app_id_ = extension_id; | 283 highlight_app_id_ = extension_id; |
278 ExtensionAppItem* new_app = GetApp(highlight_app_id_); | 284 AppListItemModel* new_app = GetApp(highlight_app_id_); |
279 highlighted_app_pending_ = !new_app; | 285 highlighted_app_pending_ = !new_app; |
280 if (new_app) | 286 if (new_app) |
281 new_app->SetHighlighted(true); | 287 new_app->SetHighlighted(true); |
282 } | 288 } |
283 | 289 |
284 ExtensionAppItem* AppsModelBuilder::GetApp( | 290 AppListItemModel* AppsModelBuilder::GetApp( |
285 const std::string& extension_id) { | 291 const std::string& extension_id) { |
286 DCHECK(model_); | 292 DCHECK(model_); |
287 if (extension_id.empty()) | 293 if (extension_id.empty()) |
288 return NULL; | 294 return NULL; |
289 | 295 |
290 int index = FindApp(extension_id); | 296 int index = FindApp(extension_id); |
291 if (index == -1) | 297 if (index == -1) |
292 return NULL; | 298 return NULL; |
293 return GetAppAt(index); | 299 return GetAppAt(index); |
294 } | 300 } |
295 | 301 |
296 void AppsModelBuilder::UpdateHighlight() { | 302 void AppsModelBuilder::UpdateHighlight() { |
297 DCHECK(model_); | 303 DCHECK(model_); |
298 if (!highlighted_app_pending_ || highlight_app_id_.empty()) | 304 if (!highlighted_app_pending_ || highlight_app_id_.empty()) |
299 return; | 305 return; |
300 | 306 |
301 int index = FindApp(highlight_app_id_); | 307 int index = FindApp(highlight_app_id_); |
302 if (index == -1) | 308 if (index == -1) |
303 return; | 309 return; |
304 | 310 |
305 model_->GetItemAt(index)->SetHighlighted(true); | 311 model_->GetItemAt(index)->SetHighlighted(true); |
306 highlighted_app_pending_ = false; | 312 highlighted_app_pending_ = false; |
307 } | 313 } |
308 | 314 |
309 ExtensionAppItem* AppsModelBuilder::GetAppAt(size_t index) { | 315 AppListItemModel* AppsModelBuilder::GetAppAt(size_t index) { |
310 DCHECK_LT(index, model_->item_count()); | 316 DCHECK_LT(index, model_->item_count()); |
311 ChromeAppListItem* item = | 317 return model_->GetItemAt(index); |
312 static_cast<ChromeAppListItem*>(model_->GetItemAt(index)); | 318 } |
313 DCHECK_EQ(item->type(), ChromeAppListItem::TYPE_APP); | |
314 | 319 |
315 return static_cast<ExtensionAppItem*>(item); | 320 ExtensionAppItem* AppsModelBuilder::GetExtensionAppAt(size_t index) { |
321 AppListItemModel* app = GetAppAt(index); | |
322 if (app->AppType() != ExtensionAppItem::ExtensionAppType()) | |
323 return NULL; | |
324 return static_cast<ExtensionAppItem*>(app); | |
316 } | 325 } |
317 | 326 |
318 void AppsModelBuilder::ListItemsAdded(size_t start, size_t count) { | 327 void AppsModelBuilder::ListItemsAdded(size_t start, size_t count) { |
319 } | 328 } |
320 | 329 |
321 void AppsModelBuilder::ListItemsRemoved(size_t start, size_t count) { | 330 void AppsModelBuilder::ListItemsRemoved(size_t start, size_t count) { |
322 } | 331 } |
323 | 332 |
324 void AppsModelBuilder::ListItemMoved(size_t index, size_t target_index) { | 333 void AppsModelBuilder::ListItemMoved(size_t index, size_t target_index) { |
325 if (ignore_changes_) | 334 if (ignore_changes_) |
326 return; | 335 return; |
327 | 336 |
328 ExtensionAppItem* prev = target_index > 0 ? GetAppAt(target_index - 1) : NULL; | 337 ExtensionAppItem* prev = target_index > 0 ? |
338 GetExtensionAppAt(target_index - 1) : NULL; | |
329 ExtensionAppItem* next = target_index + 1 < model_->item_count() ? | 339 ExtensionAppItem* next = target_index + 1 < model_->item_count() ? |
330 GetAppAt(target_index + 1) : NULL; | 340 GetExtensionAppAt(target_index + 1) : NULL; |
331 GetAppAt(target_index)->Move(prev, next); | 341 ExtensionAppItem* target_app = GetExtensionAppAt(target_index); |
342 target_app->Move(prev, next); | |
332 } | 343 } |
333 | 344 |
334 void AppsModelBuilder::ListItemsChanged(size_t start, size_t count) { | 345 void AppsModelBuilder::ListItemsChanged(size_t start, size_t count) { |
335 NOTREACHED(); | 346 NOTREACHED(); |
336 } | 347 } |
OLD | NEW |