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

Side by Side Diff: chrome/browser/ui/app_list/app_list_syncable_service.cc

Issue 981893002: Lazily build the app list model. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix_set_enabled
Patch Set: address comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/app_list_syncable_service.h" 5 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "chrome/browser/apps/drive/drive_app_provider.h" 9 #include "chrome/browser/apps/drive/drive_app_provider.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/extensions/extension_service.h" 10 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/app_list/app_list_prefs.h" 12 #include "chrome/browser/ui/app_list/app_list_prefs.h"
14 #include "chrome/browser/ui/app_list/app_list_service.h" 13 #include "chrome/browser/ui/app_list/app_list_service.h"
15 #include "chrome/browser/ui/app_list/extension_app_item.h" 14 #include "chrome/browser/ui/app_list/extension_app_item.h"
16 #include "chrome/browser/ui/app_list/extension_app_model_builder.h" 15 #include "chrome/browser/ui/app_list/extension_app_model_builder.h"
17 #include "chrome/browser/ui/app_list/model_pref_updater.h" 16 #include "chrome/browser/ui/app_list/model_pref_updater.h"
18 #include "chrome/browser/ui/host_desktop.h" 17 #include "chrome/browser/ui/host_desktop.h"
19 #include "chrome/common/chrome_switches.h" 18 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/extensions/extension_constants.h" 19 #include "chrome/common/extensions/extension_constants.h"
21 #include "chrome/grit/generated_resources.h" 20 #include "chrome/grit/generated_resources.h"
22 #include "content/public/browser/notification_source.h"
23 #include "extensions/browser/extension_prefs.h" 21 #include "extensions/browser/extension_prefs.h"
24 #include "extensions/browser/extension_system.h" 22 #include "extensions/browser/extension_system.h"
25 #include "extensions/browser/uninstall_reason.h" 23 #include "extensions/browser/uninstall_reason.h"
26 #include "extensions/common/constants.h" 24 #include "extensions/common/constants.h"
27 #include "sync/api/sync_change_processor.h" 25 #include "sync/api/sync_change_processor.h"
28 #include "sync/api/sync_data.h" 26 #include "sync/api/sync_data.h"
29 #include "sync/api/sync_merge_result.h" 27 #include "sync/api/sync_merge_result.h"
30 #include "sync/protocol/sync.pb.h" 28 #include "sync/protocol/sync.pb.h"
31 #include "ui/app_list/app_list_folder_item.h" 29 #include "ui/app_list/app_list_folder_item.h"
32 #include "ui/app_list/app_list_item.h" 30 #include "ui/app_list/app_list_item.h"
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } 172 }
175 173
176 // AppListSyncableService::ModelObserver 174 // AppListSyncableService::ModelObserver
177 175
178 class AppListSyncableService::ModelObserver : public AppListModelObserver { 176 class AppListSyncableService::ModelObserver : public AppListModelObserver {
179 public: 177 public:
180 explicit ModelObserver(AppListSyncableService* owner) 178 explicit ModelObserver(AppListSyncableService* owner)
181 : owner_(owner), 179 : owner_(owner),
182 adding_item_(NULL) { 180 adding_item_(NULL) {
183 DVLOG(2) << owner_ << ": ModelObserver Added"; 181 DVLOG(2) << owner_ << ": ModelObserver Added";
184 owner_->model()->AddObserver(this); 182 owner_->GetModel()->AddObserver(this);
185 } 183 }
186 184
187 ~ModelObserver() override { 185 ~ModelObserver() override {
188 owner_->model()->RemoveObserver(this); 186 owner_->GetModel()->RemoveObserver(this);
189 DVLOG(2) << owner_ << ": ModelObserver Removed"; 187 DVLOG(2) << owner_ << ": ModelObserver Removed";
190 } 188 }
191 189
192 private: 190 private:
193 // AppListModelObserver 191 // AppListModelObserver
194 void OnAppListItemAdded(AppListItem* item) override { 192 void OnAppListItemAdded(AppListItem* item) override {
195 DCHECK(!adding_item_); 193 DCHECK(!adding_item_);
196 adding_item_ = item; // Ignore updates while adding an item. 194 adding_item_ = item; // Ignore updates while adding an item.
197 VLOG(2) << owner_ << " OnAppListItemAdded: " << item->ToDebugString(); 195 VLOG(2) << owner_ << " OnAppListItemAdded: " << item->ToDebugString();
198 owner_->AddOrUpdateFromSyncItem(item); 196 owner_->AddOrUpdateFromSyncItem(item);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 model_(new AppListModel), 235 model_(new AppListModel),
238 initial_sync_data_processed_(false), 236 initial_sync_data_processed_(false),
239 first_app_list_sync_(true) { 237 first_app_list_sync_(true) {
240 if (!extension_system) { 238 if (!extension_system) {
241 LOG(ERROR) << "AppListSyncableService created with no ExtensionSystem"; 239 LOG(ERROR) << "AppListSyncableService created with no ExtensionSystem";
242 return; 240 return;
243 } 241 }
244 242
245 oem_folder_name_ = 243 oem_folder_name_ =
246 l10n_util::GetStringUTF8(IDS_APP_LIST_OEM_DEFAULT_FOLDER_NAME); 244 l10n_util::GetStringUTF8(IDS_APP_LIST_OEM_DEFAULT_FOLDER_NAME);
247
248 // Note: model_observer_ is constructed after the initial sync changes are
249 // received in MergeDataAndStartSyncing(). Changes to the model before that
250 // will be synced after the initial sync occurs.
251 if (extension_system->extension_service() &&
252 extension_system->extension_service()->is_ready()) {
253 BuildModel();
254 return;
255 }
256
257 // The extensions for this profile have not yet all been loaded.
258 registrar_.Add(this,
259 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
260 content::Source<Profile>(profile));
261 } 245 }
262 246
263 AppListSyncableService::~AppListSyncableService() { 247 AppListSyncableService::~AppListSyncableService() {
264 // Remove observers. 248 // Remove observers.
265 model_observer_.reset(); 249 model_observer_.reset();
266 model_pref_updater_.reset(); 250 model_pref_updater_.reset();
267 251
268 STLDeleteContainerPairSecondPointers(sync_items_.begin(), sync_items_.end()); 252 STLDeleteContainerPairSecondPointers(sync_items_.begin(), sync_items_.end());
269 } 253 }
270 254
271 void AppListSyncableService::BuildModel() { 255 void AppListSyncableService::BuildModel() {
256 DCHECK(extension_system_->extension_service() &&
tapted 2015/03/20 11:47:15 If we're unsure about an obscure startup sequence,
calamity 2015/03/23 05:14:49 Done.
257 extension_system_->extension_service()->is_ready());
272 // For now, use the AppListControllerDelegate associated with the native 258 // For now, use the AppListControllerDelegate associated with the native
273 // desktop. TODO(stevenjb): Remove ExtensionAppModelBuilder controller 259 // desktop. TODO(stevenjb): Remove ExtensionAppModelBuilder controller
274 // dependency and move the dependent methods from AppListControllerDelegate 260 // dependency and move the dependent methods from AppListControllerDelegate
275 // to an extension service delegate associated with this class. 261 // to an extension service delegate associated with this class.
276 AppListControllerDelegate* controller = NULL; 262 AppListControllerDelegate* controller = NULL;
277 AppListService* service = 263 AppListService* service =
278 AppListService::Get(chrome::HOST_DESKTOP_TYPE_NATIVE); 264 AppListService::Get(chrome::HOST_DESKTOP_TYPE_NATIVE);
279 if (service) 265 if (service)
280 controller = service->GetControllerDelegate(); 266 controller = service->GetControllerDelegate();
281 apps_builder_.reset(new ExtensionAppModelBuilder(controller)); 267 apps_builder_.reset(new ExtensionAppModelBuilder(controller));
282 DCHECK(profile_); 268 DCHECK(profile_);
283 if (app_list::switches::IsAppListSyncEnabled()) { 269 if (app_list::switches::IsAppListSyncEnabled()) {
284 VLOG(1) << this << ": AppListSyncableService: InitializeWithService."; 270 VLOG(1) << this << ": AppListSyncableService: InitializeWithService.";
285 SyncStarted(); 271 SyncStarted();
286 apps_builder_->InitializeWithService(this); 272 apps_builder_->InitializeWithService(this, model_.get());
287 } else { 273 } else {
288 VLOG(1) << this << ": AppListSyncableService: InitializeWithProfile."; 274 VLOG(1) << this << ": AppListSyncableService: InitializeWithProfile.";
289 apps_builder_->InitializeWithProfile(profile_, model_.get()); 275 apps_builder_->InitializeWithProfile(profile_, model_.get());
290 } 276 }
291 277
292 model_pref_updater_.reset( 278 model_pref_updater_.reset(
293 new ModelPrefUpdater(AppListPrefs::Get(profile_), model_.get())); 279 new ModelPrefUpdater(AppListPrefs::Get(profile_), model_.get()));
294 280
295 if (app_list::switches::IsDriveAppsInAppListEnabled()) 281 if (app_list::switches::IsDriveAppsInAppListEnabled())
296 drive_app_provider_.reset(new DriveAppProvider(profile_, this)); 282 drive_app_provider_.reset(new DriveAppProvider(profile_, this));
297 } 283 }
298 284
285 size_t AppListSyncableService::GetNumSyncItemsForTest() {
286 // If the model isn't built yet, there will be no sync items.
287 GetModel();
288
289 return sync_items_.size();
290 }
291
299 void AppListSyncableService::ResetDriveAppProviderForTest() { 292 void AppListSyncableService::ResetDriveAppProviderForTest() {
300 drive_app_provider_.reset(); 293 drive_app_provider_.reset();
301 } 294 }
302 295
303 void AppListSyncableService::Shutdown() { 296 void AppListSyncableService::Shutdown() {
304 // DriveAppProvider touches other KeyedServices in its dtor and needs be 297 // DriveAppProvider touches other KeyedServices in its dtor and needs be
305 // released in shutdown stage. 298 // released in shutdown stage.
306 drive_app_provider_.reset(); 299 drive_app_provider_.reset();
307 } 300 }
308 301
(...skipping 17 matching lines...) Expand all
326 const std::string sync_id = GetDriveAppSyncId(drive_app_id); 319 const std::string sync_id = GetDriveAppSyncId(drive_app_id);
327 SyncItem* sync_item = FindSyncItem(sync_id); 320 SyncItem* sync_item = FindSyncItem(sync_id);
328 if (!sync_item) 321 if (!sync_item)
329 return; 322 return;
330 323
331 DCHECK_EQ(sync_item->item_type, 324 DCHECK_EQ(sync_item->item_type,
332 sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP); 325 sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP);
333 DeleteSyncItem(sync_item); 326 DeleteSyncItem(sync_item);
334 } 327 }
335 328
336 void AppListSyncableService::Observe(
337 int type,
338 const content::NotificationSource& source,
339 const content::NotificationDetails& details) {
340 DCHECK_EQ(extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, type);
341 DCHECK_EQ(profile_, content::Source<Profile>(source).ptr());
342 registrar_.RemoveAll();
343 BuildModel();
344 }
345
346 const AppListSyncableService::SyncItem* 329 const AppListSyncableService::SyncItem*
347 AppListSyncableService::GetSyncItem(const std::string& id) const { 330 AppListSyncableService::GetSyncItem(const std::string& id) const {
348 SyncItemMap::const_iterator iter = sync_items_.find(id); 331 SyncItemMap::const_iterator iter = sync_items_.find(id);
349 if (iter != sync_items_.end()) 332 if (iter != sync_items_.end())
350 return iter->second; 333 return iter->second;
351 return NULL; 334 return NULL;
352 } 335 }
353 336
354 void AppListSyncableService::SetOemFolderName(const std::string& name) { 337 void AppListSyncableService::SetOemFolderName(const std::string& name) {
355 oem_folder_name_ = name; 338 oem_folder_name_ = name;
356 AppListFolderItem* oem_folder = model_->FindFolderItem(kOemFolderId); 339 AppListFolderItem* oem_folder = model_->FindFolderItem(kOemFolderId);
357 if (oem_folder) 340 if (oem_folder)
358 model_->SetItemName(oem_folder, oem_folder_name_); 341 model_->SetItemName(oem_folder, oem_folder_name_);
359 } 342 }
360 343
344 AppListModel* AppListSyncableService::GetModel() {
345 if (!apps_builder_)
346 BuildModel();
347
348 return model_.get();
349 }
350
361 void AppListSyncableService::AddItem(scoped_ptr<AppListItem> app_item) { 351 void AppListSyncableService::AddItem(scoped_ptr<AppListItem> app_item) {
362 SyncItem* sync_item = FindOrAddSyncItem(app_item.get()); 352 SyncItem* sync_item = FindOrAddSyncItem(app_item.get());
363 if (!sync_item) 353 if (!sync_item)
364 return; // Item is not valid. 354 return; // Item is not valid.
365 355
366 std::string folder_id; 356 std::string folder_id;
367 if (app_list::switches::IsFolderUIEnabled()) { 357 if (app_list::switches::IsFolderUIEnabled()) {
368 if (AppIsOem(app_item->id())) { 358 if (AppIsOem(app_item->id())) {
369 folder_id = FindOrCreateOemFolder(); 359 folder_id = FindOrCreateOemFolder();
370 VLOG_IF(2, !folder_id.empty()) 360 VLOG_IF(2, !folder_id.empty())
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 } else { 986 } else {
997 res += " { " + item_name + " }"; 987 res += " { " + item_name + " }";
998 res += " [" + item_ordinal.ToDebugString() + "]"; 988 res += " [" + item_ordinal.ToDebugString() + "]";
999 if (!parent_id.empty()) 989 if (!parent_id.empty())
1000 res += " <" + parent_id.substr(0, 8) + ">"; 990 res += " <" + parent_id.substr(0, 8) + ">";
1001 } 991 }
1002 return res; 992 return res;
1003 } 993 }
1004 994
1005 } // namespace app_list 995 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698