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_EXTENSIONS_EXTENSION_SYNC_SERVICE_H_
6#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SYNC_SERVICE_H_
7
8#include <string>
9#include <vector>
10
11#include "base/compiler_specific.h"
12#include "chrome/browser/extensions/app_sync_bundle.h"
13#include "chrome/browser/extensions/extension_sync_bundle.h"
14#include "chrome/browser/extensions/pending_enables.h"
15#include "components/keyed_service/core/keyed_service.h"
16#include "extensions/browser/extension_prefs.h"
17#include "extensions/common/extension.h"
18#include "sync/api/string_ordinal.h"
19#include "sync/api/sync_change.h"
20#include "sync/api/syncable_service.h"
21
22class ExtensionSyncData;
23class Profile;
24
25namespace base {
26class SequencedTaskRunner;
27}
28
29namespace extensions {
30class AppSyncData;
31class ExtensionPrefs;
32class ExtensionSyncData;
33}  // namespace extensions
34
35namespace syncer {
36class SyncErrorFactory;
37}
38
39class ExtensionSyncService : public syncer::SyncableService,
40                             public KeyedService {
41 public:
42  ExtensionSyncService(Profile* profile,
43                       extensions::ExtensionPrefs* extension_prefs,
44                       ExtensionService* extension_service);
45
46  virtual ~ExtensionSyncService();
47
48  // Convenience function to get the ExtensionSyncService for a Profile.
49  static ExtensionSyncService* Get(Profile* profile);
50
51  const extensions::ExtensionPrefs& extension_prefs() const {
52    return *extension_prefs_;
53  }
54
55  // Notifies Sync (if needed) of a newly-installed extension or a change to
56  // an existing extension.
57  virtual void SyncExtensionChangeIfNeeded(
58      const extensions::Extension& extension);
59
60  // syncer::SyncableService implementation.
61  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
62      syncer::ModelType type,
63      const syncer::SyncDataList& initial_sync_data,
64      scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
65      scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) OVERRIDE;
66  virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
67  virtual syncer::SyncDataList GetAllSyncData(
68      syncer::ModelType type) const OVERRIDE;
69  virtual syncer::SyncError ProcessSyncChanges(
70      const tracked_objects::Location& from_here,
71      const syncer::SyncChangeList& change_list) OVERRIDE;
72
73  // Gets the sync data for the given extension, assuming that the extension is
74  // syncable.
75  extensions::ExtensionSyncData GetExtensionSyncData(
76      const extensions::Extension& extension) const;
77
78  // Gets the sync data for the given app, assuming that the app is
79  // syncable.
80  extensions::AppSyncData GetAppSyncData(
81      const extensions::Extension& extension) const;
82
83  // Gets the ExtensionSyncData for all extensions.
84  std::vector<extensions::ExtensionSyncData> GetExtensionSyncDataList() const;
85
86  // Gets the AppSyncData for all extensions.
87  std::vector<extensions::AppSyncData> GetAppSyncDataList() const;
88
89  // Applies the change specified passed in by either ExtensionSyncData or
90  // AppSyncData to the current system.
91  // Returns false if the changes were not completely applied and were added
92  // to the pending list to be tried again.
93  bool ProcessExtensionSyncData(
94      const extensions::ExtensionSyncData& extension_sync_data);
95  bool ProcessAppSyncData(const extensions::AppSyncData& app_sync_data);
96
97  // Processes the bookmark app specific parts of an AppSyncData.
98  void ProcessBookmarkAppSyncData(const extensions::AppSyncData& app_sync_data);
99
100  syncer::SyncChange PrepareToSyncUninstallExtension(
101      const extensions::Extension* extension,
102      bool extensions_ready);
103  void ProcessSyncUninstallExtension(const std::string& extension_id,
104                                     const syncer::SyncChange& sync_change);
105
106  void SyncEnableExtension(const extensions::Extension& extension);
107  void SyncDisableExtension(const extensions::Extension& extension);
108
109  void SyncOrderingChange(const std::string& extension_id);
110
111  // |flare| provides a StartSyncFlare to the SyncableService. See
112  // sync_start_util for more.
113  void SetSyncStartFlare(const syncer::SyncableService::StartSyncFlare& flare);
114
115  Profile* profile() { return profile_; }
116
117 private:
118  // Return true if the sync type of |extension| matches |type|.
119  bool IsCorrectSyncType(const extensions::Extension& extension,
120                         syncer::ModelType type)
121      const;
122
123  // Whether the given extension has been enabled before sync has started.
124  bool IsPendingEnable(const std::string& extension_id) const;
125
126  // Handles setting the extension specific values in |extension_sync_data| to
127  // the current system.
128  // Returns false if the changes were not completely applied and need to be
129  // tried again later.
130  bool ProcessExtensionSyncDataHelper(
131      const extensions::ExtensionSyncData& extension_sync_data,
132      syncer::ModelType type);
133
134  // The normal profile associated with this ExtensionService.
135  Profile* profile_;
136
137  // Preferences for the owning profile.
138  extensions::ExtensionPrefs* extension_prefs_;
139
140  ExtensionService* extension_service_;
141
142  extensions::AppSyncBundle app_sync_bundle_;
143  extensions::ExtensionSyncBundle extension_sync_bundle_;
144
145  // Set of extensions/apps that have been enabled before sync has started.
146  extensions::PendingEnables pending_app_enables_;
147  extensions::PendingEnables pending_extension_enables_;
148
149  // Sequenced task runner for extension related file operations.
150  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
151
152  // Run()ning tells sync to try and start soon, because syncable changes
153  // have started happening. It will cause sync to call us back
154  // asynchronously via MergeDataAndStartSyncing as soon as possible.
155  syncer::SyncableService::StartSyncFlare flare_;
156
157  DISALLOW_COPY_AND_ASSIGN(ExtensionSyncService);
158};
159
160#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_SYNC_SERVICE_H_
161