app_list_syncable_service.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/browser_context_keyed_service/browser_context_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 BrowserContextKeyedService,
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> item);
67
68  // Removes sync item matching |id|.
69  void RemoveItem(const std::string& id);
70
71  // Returns the existing sync item matching |id| or NULL.
72  const SyncItem* GetSyncItem(const std::string& id) const;
73
74  Profile* profile() { return profile_; }
75  AppListModel* model() { return model_.get(); }
76  size_t GetNumSyncItemsForTest() { return sync_items_.size(); }
77
78  // syncer::SyncableService
79  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
80      syncer::ModelType type,
81      const syncer::SyncDataList& initial_sync_data,
82      scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
83      scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
84  virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
85  virtual syncer::SyncDataList GetAllSyncData(
86      syncer::ModelType type) const OVERRIDE;
87  virtual syncer::SyncError ProcessSyncChanges(
88      const tracked_objects::Location& from_here,
89      const syncer::SyncChangeList& change_list) OVERRIDE;
90
91 private:
92  class ModelObserver;
93  typedef std::map<std::string, SyncItem*> SyncItemMap;
94
95  // content::NotificationObserver
96  virtual void Observe(int type,
97                       const content::NotificationSource& source,
98                       const content::NotificationDetails& details) OVERRIDE;
99
100  // Builds the model once ExtensionService is ready.
101  void BuildModel();
102
103  // Returns true if sync has restarted, otherwise runs |flare_|.
104  bool SyncStarted();
105
106  // If |app_item| matches an existing sync item, returns it. Otherwise adds
107  // |app_item| to |sync_items_| and returns the new item. If |app_item| is
108  // invalid returns NULL.
109  SyncItem* FindOrAddSyncItem(AppListItem* app_item);
110
111  // Creates a sync item for |app_item| and sends an ADD SyncChange event.
112  SyncItem* CreateSyncItemFromAppItem(AppListItem* app_item);
113
114  // If a sync item for |app_item| already exists, update |app_item| from the
115  // sync item, otherwise create a new sync item from |app_item|.
116  void AddOrUpdateFromSyncItem(AppListItem* app_item);
117
118  // Either uninstalling a default app or remove the REMOVE_DEFAULT sync item.
119  // Returns true if the app is removed. Otherwise deletes the existing sync
120  // item and returns false.
121  bool RemoveDefaultApp(AppListItem* item, SyncItem* sync_item);
122
123  // Deletes a sync item from |sync_items_| and sends a DELETE action.
124  void DeleteSyncItem(SyncItem* sync_item);
125
126  // Updates existing entry in |sync_items_| from |app_item|.
127  void UpdateSyncItem(AppListItem* app_item);
128
129  // Removes sync item matching |id|.
130  void RemoveSyncItem(const std::string& id);
131
132  // Updates folder items that may get created during initial sync.
133  void ResolveFolderPositions();
134
135  // Removes any empty SyncItem folders and deletes them from sync. Called
136  // after a sync item is removed (which may result in an empty folder).
137  void PruneEmptySyncFolders();
138
139  // Creates or updates a SyncItem from |specifics|. Returns true if a new item
140  // was created.
141  bool ProcessSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
142
143  // Handles a newly created sync item (e.g. creates a new AppItem and adds it
144  // to the model or uninstalls a deleted default item.
145  void ProcessNewSyncItem(SyncItem* sync_item);
146
147  // Handles an existing sync item.
148  void ProcessExistingSyncItem(SyncItem* sync_item);
149
150  // Updates |app_item| from |sync_item| (e.g. updates item positions).
151  void UpdateAppItemFromSyncItem(const SyncItem* sync_item,
152                                 AppListItem* app_item);
153
154  // Sends ADD or CHANGED for sync item.
155  void SendSyncChange(SyncItem* sync_item,
156                      syncer::SyncChange::SyncChangeType sync_change_type);
157
158  // Returns an existing SyncItem corresponding to |item_id| or NULL.
159  SyncItem* FindSyncItem(const std::string& item_id);
160
161  // Creates a new sync item for |item_id|.
162  SyncItem* CreateSyncItem(
163      const std::string& item_id,
164      sync_pb::AppListSpecifics::AppListItemType item_type);
165
166  // Deletes a SyncItem matching |specifics|.
167  void DeleteSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
168
169  Profile* profile_;
170  extensions::ExtensionSystem* extension_system_;
171  content::NotificationRegistrar registrar_;
172  scoped_ptr<AppListModel> model_;
173  scoped_ptr<ModelObserver> model_observer_;
174  scoped_ptr<ExtensionAppModelBuilder> apps_builder_;
175  scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
176  scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_;
177  SyncItemMap sync_items_;
178  syncer::SyncableService::StartSyncFlare flare_;
179
180  DISALLOW_COPY_AND_ASSIGN(AppListSyncableService);
181};
182
183}  // namespace app_list
184
185#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
186