app_list_syncable_service.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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  void ResetDriveAppProviderForTest();
88
89  // syncer::SyncableService
90  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
91      syncer::ModelType type,
92      const syncer::SyncDataList& initial_sync_data,
93      scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
94      scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
95  virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
96  virtual syncer::SyncDataList GetAllSyncData(
97      syncer::ModelType type) const OVERRIDE;
98  virtual syncer::SyncError ProcessSyncChanges(
99      const tracked_objects::Location& from_here,
100      const syncer::SyncChangeList& change_list) OVERRIDE;
101
102 private:
103  class ModelObserver;
104  typedef std::map<std::string, SyncItem*> SyncItemMap;
105
106  // KeyedService
107  virtual void Shutdown() OVERRIDE;
108
109  // content::NotificationObserver
110  virtual void Observe(int type,
111                       const content::NotificationSource& source,
112                       const content::NotificationDetails& details) OVERRIDE;
113
114  // Builds the model once ExtensionService is ready.
115  void BuildModel();
116
117  // Returns true if sync has restarted, otherwise runs |flare_|.
118  bool SyncStarted();
119
120  // If |app_item| matches an existing sync item, returns it. Otherwise adds
121  // |app_item| to |sync_items_| and returns the new item. If |app_item| is
122  // invalid returns NULL.
123  SyncItem* FindOrAddSyncItem(AppListItem* app_item);
124
125  // Creates a sync item for |app_item| and sends an ADD SyncChange event.
126  SyncItem* CreateSyncItemFromAppItem(AppListItem* app_item);
127
128  // If a sync item for |app_item| already exists, update |app_item| from the
129  // sync item, otherwise create a new sync item from |app_item|.
130  void AddOrUpdateFromSyncItem(AppListItem* app_item);
131
132  // Either uninstalling a default app or remove the REMOVE_DEFAULT sync item.
133  // Returns true if the app is removed. Otherwise deletes the existing sync
134  // item and returns false.
135  bool RemoveDefaultApp(AppListItem* item, SyncItem* sync_item);
136
137  // Deletes a sync item from |sync_items_| and sends a DELETE action.
138  void DeleteSyncItem(SyncItem* sync_item);
139
140  // Updates existing entry in |sync_items_| from |app_item|.
141  void UpdateSyncItem(AppListItem* app_item);
142
143  // Removes sync item matching |id|.
144  void RemoveSyncItem(const std::string& id);
145
146  // Updates folder items that may get created during initial sync.
147  void ResolveFolderPositions();
148
149  // Removes any empty SyncItem folders and deletes them from sync. Called
150  // after a sync item is removed (which may result in an empty folder).
151  void PruneEmptySyncFolders();
152
153  // Creates or updates a SyncItem from |specifics|. Returns true if a new item
154  // was created.
155  bool ProcessSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
156
157  // Handles a newly created sync item (e.g. creates a new AppItem and adds it
158  // to the model or uninstalls a deleted default item.
159  void ProcessNewSyncItem(SyncItem* sync_item);
160
161  // Handles an existing sync item.
162  void ProcessExistingSyncItem(SyncItem* sync_item);
163
164  // Updates |app_item| from |sync_item| (e.g. updates item positions).
165  void UpdateAppItemFromSyncItem(const SyncItem* sync_item,
166                                 AppListItem* app_item);
167
168  // Sends ADD or CHANGED for sync item.
169  void SendSyncChange(SyncItem* sync_item,
170                      syncer::SyncChange::SyncChangeType sync_change_type);
171
172  // Returns an existing SyncItem corresponding to |item_id| or NULL.
173  SyncItem* FindSyncItem(const std::string& item_id);
174
175  // Creates a new sync item for |item_id|.
176  SyncItem* CreateSyncItem(
177      const std::string& item_id,
178      sync_pb::AppListSpecifics::AppListItemType item_type);
179
180  // Deletes a SyncItem matching |specifics|.
181  void DeleteSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
182
183  // Creates the OEM folder and sets its name if necessary. Returns the OEM
184  // folder id.
185  std::string FindOrCreateOemFolder();
186
187  // Gets the location for the OEM folder. Called when the folder is first
188  // created.
189  syncer::StringOrdinal GetOemFolderPos();
190
191  // Returns true if an extension matching |id| exists and was installed by
192  // an OEM (extension->was_installed_by_oem() is true).
193  bool AppIsOem(const std::string& id);
194
195  Profile* profile_;
196  extensions::ExtensionSystem* extension_system_;
197  content::NotificationRegistrar registrar_;
198  scoped_ptr<AppListModel> model_;
199  scoped_ptr<ModelObserver> model_observer_;
200  scoped_ptr<ExtensionAppModelBuilder> apps_builder_;
201  scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
202  scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_;
203  SyncItemMap sync_items_;
204  syncer::SyncableService::StartSyncFlare flare_;
205  bool initial_sync_data_processed_;
206  bool first_app_list_sync_;
207  std::string oem_folder_name_;
208
209  // Provides integration with Drive apps.
210  scoped_ptr<DriveAppProvider> drive_app_provider_;
211
212  DISALLOW_COPY_AND_ASSIGN(AppListSyncableService);
213};
214
215}  // namespace app_list
216
217#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
218