app_list_syncable_service.h revision 116680a4aac90f2aa7413d9095a592090648e557
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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
6#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
7
8#include <map>
9
10#include "base/memory/scoped_ptr.h"
11#include "chrome/browser/sync/glue/sync_start_util.h"
12#include "components/keyed_service/core/keyed_service.h"
13#include "content/public/browser/notification_observer.h"
14#include "content/public/browser/notification_registrar.h"
15#include "sync/api/string_ordinal.h"
16#include "sync/api/sync_change.h"
17#include "sync/api/sync_change_processor.h"
18#include "sync/api/sync_error_factory.h"
19#include "sync/api/syncable_service.h"
20#include "sync/protocol/app_list_specifics.pb.h"
21
22class DriveAppProvider;
23class ExtensionAppModelBuilder;
24class Profile;
25
26namespace extensions {
27class ExtensionSystem;
28}
29
30namespace sync_pb {
31class AppListSpecifics;
32}
33
34namespace app_list {
35
36class AppListFolderItem;
37class AppListItem;
38class AppListModel;
39
40// Keyed Service that owns, stores, and syncs an AppListModel for a profile.
41class AppListSyncableService : public syncer::SyncableService,
42                               public KeyedService,
43                               public content::NotificationObserver {
44 public:
45  struct SyncItem {
46    SyncItem(const std::string& id,
47             sync_pb::AppListSpecifics::AppListItemType type);
48    ~SyncItem();
49    const std::string item_id;
50    sync_pb::AppListSpecifics::AppListItemType item_type;
51    std::string item_name;
52    std::string parent_id;
53    syncer::StringOrdinal page_ordinal;
54    syncer::StringOrdinal item_ordinal;
55
56    std::string ToString() const;
57  };
58
59  // Populates the model when |extension_system| is ready.
60  AppListSyncableService(Profile* profile,
61                         extensions::ExtensionSystem* extension_system);
62
63  virtual ~AppListSyncableService();
64
65  // Adds |item| to |sync_items_| and |model_|. If a sync item already exists,
66  // updates the existing sync item instead.
67  void AddItem(scoped_ptr<AppListItem> app_item);
68
69  // Removes sync item matching |id|.
70  void RemoveItem(const std::string& id);
71
72  // Called when properties of an item may have changed, e.g. default/oem state.
73  void UpdateItem(AppListItem* app_item);
74
75  // Returns the existing sync item matching |id| or NULL.
76  const SyncItem* GetSyncItem(const std::string& id) const;
77
78  // Sets the name of the folder for OEM apps.
79  void SetOemFolderName(const std::string& name);
80
81  Profile* profile() { return profile_; }
82  AppListModel* model() { return model_.get(); }
83  size_t GetNumSyncItemsForTest() const { return sync_items_.size(); }
84  const std::string& GetOemFolderNameForTest() const {
85    return oem_folder_name_;
86  }
87
88  // syncer::SyncableService
89  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
90      syncer::ModelType type,
91      const syncer::SyncDataList& initial_sync_data,
92      scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
93      scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
94  virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
95  virtual syncer::SyncDataList GetAllSyncData(
96      syncer::ModelType type) const OVERRIDE;
97  virtual syncer::SyncError ProcessSyncChanges(
98      const tracked_objects::Location& from_here,
99      const syncer::SyncChangeList& change_list) OVERRIDE;
100
101 private:
102  class ModelObserver;
103  typedef std::map<std::string, SyncItem*> SyncItemMap;
104
105  // KeyedService
106  virtual void Shutdown() OVERRIDE;
107
108  // content::NotificationObserver
109  virtual void Observe(int type,
110                       const content::NotificationSource& source,
111                       const content::NotificationDetails& details) OVERRIDE;
112
113  // Builds the model once ExtensionService is ready.
114  void BuildModel();
115
116  // Returns true if sync has restarted, otherwise runs |flare_|.
117  bool SyncStarted();
118
119  // If |app_item| matches an existing sync item, returns it. Otherwise adds
120  // |app_item| to |sync_items_| and returns the new item. If |app_item| is
121  // invalid returns NULL.
122  SyncItem* FindOrAddSyncItem(AppListItem* app_item);
123
124  // Creates a sync item for |app_item| and sends an ADD SyncChange event.
125  SyncItem* CreateSyncItemFromAppItem(AppListItem* app_item);
126
127  // If a sync item for |app_item| already exists, update |app_item| from the
128  // sync item, otherwise create a new sync item from |app_item|.
129  void AddOrUpdateFromSyncItem(AppListItem* app_item);
130
131  // Either uninstalling a default app or remove the REMOVE_DEFAULT sync item.
132  // Returns true if the app is removed. Otherwise deletes the existing sync
133  // item and returns false.
134  bool RemoveDefaultApp(AppListItem* item, SyncItem* sync_item);
135
136  // Deletes a sync item from |sync_items_| and sends a DELETE action.
137  void DeleteSyncItem(SyncItem* sync_item);
138
139  // Updates existing entry in |sync_items_| from |app_item|.
140  void UpdateSyncItem(AppListItem* app_item);
141
142  // Removes sync item matching |id|.
143  void RemoveSyncItem(const std::string& id);
144
145  // Updates folder items that may get created during initial sync.
146  void ResolveFolderPositions();
147
148  // Removes any empty SyncItem folders and deletes them from sync. Called
149  // after a sync item is removed (which may result in an empty folder).
150  void PruneEmptySyncFolders();
151
152  // Creates or updates a SyncItem from |specifics|. Returns true if a new item
153  // was created.
154  bool ProcessSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
155
156  // Handles a newly created sync item (e.g. creates a new AppItem and adds it
157  // to the model or uninstalls a deleted default item.
158  void ProcessNewSyncItem(SyncItem* sync_item);
159
160  // Handles an existing sync item.
161  void ProcessExistingSyncItem(SyncItem* sync_item);
162
163  // Updates |app_item| from |sync_item| (e.g. updates item positions).
164  void UpdateAppItemFromSyncItem(const SyncItem* sync_item,
165                                 AppListItem* app_item);
166
167  // Sends ADD or CHANGED for sync item.
168  void SendSyncChange(SyncItem* sync_item,
169                      syncer::SyncChange::SyncChangeType sync_change_type);
170
171  // Returns an existing SyncItem corresponding to |item_id| or NULL.
172  SyncItem* FindSyncItem(const std::string& item_id);
173
174  // Creates a new sync item for |item_id|.
175  SyncItem* CreateSyncItem(
176      const std::string& item_id,
177      sync_pb::AppListSpecifics::AppListItemType item_type);
178
179  // Deletes a SyncItem matching |specifics|.
180  void DeleteSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
181
182  // Creates the OEM folder and sets its name if necessary. Returns the OEM
183  // folder id or an empty string if the folder can not be created. |item_id|
184  // is the item that needs to be placed in the folder, used only for tracking
185  // if the folder can not be created.
186  std::string FindOrCreateOemFolder(const std::string& item_id);
187
188  // Gets the location for the OEM folder. Called when the folder is first
189  // created.
190  syncer::StringOrdinal GetOemFolderPos();
191
192  // Returns true if an extension matching |id| exists and was installed by
193  // an OEM (extension->was_installed_by_oem() is true).
194  bool AppIsOem(const std::string& id);
195
196  Profile* profile_;
197  extensions::ExtensionSystem* extension_system_;
198  content::NotificationRegistrar registrar_;
199  scoped_ptr<AppListModel> model_;
200  scoped_ptr<ModelObserver> model_observer_;
201  scoped_ptr<ExtensionAppModelBuilder> apps_builder_;
202  scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
203  scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_;
204  SyncItemMap sync_items_;
205  syncer::SyncableService::StartSyncFlare flare_;
206  bool first_app_list_sync_;
207  std::string oem_folder_name_;
208  std::vector<std::string> oem_folder_item_ids_;
209
210  // Provides integration with Drive apps.
211  scoped_ptr<DriveAppProvider> drive_app_provider_;
212
213  DISALLOW_COPY_AND_ASSIGN(AppListSyncableService);
214};
215
216}  // namespace app_list
217
218#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
219