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