local_file_sync_service.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_
6#define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_
7
8#include <map>
9#include <set>
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/callback.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/weak_ptr.h"
16#include "base/observer_list.h"
17#include "chrome/browser/sync_file_system/local/local_origin_change_observer.h"
18#include "chrome/browser/sync_file_system/remote_change_processor.h"
19#include "chrome/browser/sync_file_system/sync_callbacks.h"
20#include "chrome/browser/sync_file_system/sync_status_code.h"
21
22class GURL;
23class Profile;
24
25namespace fileapi {
26class FileSystemContext;
27}
28
29namespace webkit_blob {
30class ScopedFile;
31}
32
33namespace sync_file_system {
34
35class FileChange;
36class LocalChangeProcessor;
37class LocalFileSyncContext;
38struct LocalFileSyncInfo;
39
40// Maintains local file change tracker and sync status.
41// Owned by SyncFileSystemService (which is a per-profile object).
42class LocalFileSyncService
43    : public RemoteChangeProcessor,
44      public LocalOriginChangeObserver,
45      public base::SupportsWeakPtr<LocalFileSyncService> {
46 public:
47  typedef base::Callback<LocalChangeProcessor*(const GURL& origin)>
48      GetLocalChangeProcessorCallback;
49
50  class Observer {
51   public:
52    Observer() {}
53    virtual ~Observer() {}
54
55    // This is called when there're one or more local changes available.
56    // |pending_changes_hint| indicates the pending queue length to help sync
57    // scheduling but the value may not be accurately reflect the real-time
58    // value.
59    virtual void OnLocalChangeAvailable(int64 pending_changes_hint) = 0;
60
61   private:
62    DISALLOW_COPY_AND_ASSIGN(Observer);
63  };
64
65  typedef base::Callback<void(SyncStatusCode status,
66                              bool has_pending_changes)>
67      HasPendingLocalChangeCallback;
68
69  explicit LocalFileSyncService(Profile* profile);
70  virtual ~LocalFileSyncService();
71
72  void Shutdown();
73
74  void MaybeInitializeFileSystemContext(
75      const GURL& app_origin,
76      fileapi::FileSystemContext* file_system_context,
77      const SyncStatusCallback& callback);
78
79  void AddChangeObserver(Observer* observer);
80
81  // Registers |url| to wait until sync is enabled for |url|.
82  // |on_syncable_callback| is to be called when |url| becomes syncable
83  // (i.e. when we have no pending writes and the file is successfully locked
84  // for sync).
85  // Calling this method again while this already has another URL waiting
86  // for sync will overwrite the previously registered URL.
87  void RegisterURLForWaitingSync(const fileapi::FileSystemURL& url,
88                                 const base::Closure& on_syncable_callback);
89
90  // Synchronize one (or a set of) local change(s) to the remote server
91  // using local_change_processor given by SetLocalChangeProcessor().
92  // |processor| must have same or longer lifetime than this service.
93  // It is invalid to call this method before calling SetLocalChangeProcessor().
94  void ProcessLocalChange(const SyncFileCallback& callback);
95
96  // Sets a local change processor. The value is ignored if
97  // SetLocalChangeProcessorCallback() is called separately.
98  // Either this or SetLocalChangeProcessorCallback() must be called before
99  // any ProcessLocalChange().
100  void SetLocalChangeProcessor(LocalChangeProcessor* local_change_processor);
101
102  // Sets a closure which gets a local change processor for the given origin.
103  // Note that once this is called it overrides the direct processor setting
104  // done by SetLocalChangeProcessor().
105  // Either this or SetLocalChangeProcessor() must be called before any
106  // ProcessLocalChange().
107  //
108  // TODO(kinuko): Remove this method once we stop using multiple backends
109  // (crbug.com/324215), or deprecate the other if we keep doing so.
110  void SetLocalChangeProcessorCallback(
111      const GetLocalChangeProcessorCallback& get_local_change_processor);
112
113  // Returns true via |callback| if the given file |url| has local pending
114  // changes.
115  void HasPendingLocalChanges(
116      const fileapi::FileSystemURL& url,
117      const HasPendingLocalChangeCallback& callback);
118
119  // Returns the metadata of a remote file pointed by |url|.
120  virtual void GetLocalFileMetadata(
121      const fileapi::FileSystemURL& url,
122      const SyncFileMetadataCallback& callback);
123
124  // RemoteChangeProcessor overrides.
125  virtual void PrepareForProcessRemoteChange(
126      const fileapi::FileSystemURL& url,
127      const PrepareChangeCallback& callback) OVERRIDE;
128  virtual void ApplyRemoteChange(
129      const FileChange& change,
130      const base::FilePath& local_path,
131      const fileapi::FileSystemURL& url,
132      const SyncStatusCallback& callback) OVERRIDE;
133  virtual void FinalizeRemoteSync(
134      const fileapi::FileSystemURL& url,
135      bool clear_local_changes,
136      const base::Closure& completion_callback) OVERRIDE;
137  virtual void RecordFakeLocalChange(
138      const fileapi::FileSystemURL& url,
139      const FileChange& change,
140      const SyncStatusCallback& callback) OVERRIDE;
141
142  // LocalOriginChangeObserver override.
143  virtual void OnChangesAvailableInOrigins(
144      const std::set<GURL>& origins) OVERRIDE;
145
146  // Called when a particular origin (app) is disabled/enabled while
147  // the service is running. This may be called for origins/apps that
148  // are not initialized for the service.
149  void SetOriginEnabled(const GURL& origin, bool enabled);
150
151 private:
152  friend class OriginChangeMapTest;
153
154  class OriginChangeMap {
155   public:
156    typedef std::map<GURL, int64> Map;
157
158    OriginChangeMap();
159    ~OriginChangeMap();
160
161    // Sets |origin| to the next origin to process. (For now we simply apply
162    // round-robin to pick the next origin to avoid starvation.)
163    // Returns false if no origins to process.
164    bool NextOriginToProcess(GURL* origin);
165
166    int64 GetTotalChangeCount() const;
167
168    // Update change_count_map_ for |origin|.
169    void SetOriginChangeCount(const GURL& origin, int64 changes);
170
171    void SetOriginEnabled(const GURL& origin, bool enabled);
172
173   private:
174    // Per-origin changes (cached info, could be stale).
175    Map change_count_map_;
176    Map::iterator next_;
177
178    // Holds a set of disabled (but initialized) origins.
179    std::set<GURL> disabled_origins_;
180  };
181
182  void DidInitializeFileSystemContext(
183      const GURL& app_origin,
184      fileapi::FileSystemContext* file_system_context,
185      const SyncStatusCallback& callback,
186      SyncStatusCode status);
187  void DidInitializeForRemoteSync(
188      const fileapi::FileSystemURL& url,
189      fileapi::FileSystemContext* file_system_context,
190      const PrepareChangeCallback& callback,
191      SyncStatusCode status);
192
193  // Runs local_sync_callback_ and resets it.
194  void RunLocalSyncCallback(
195      SyncStatusCode status,
196      const fileapi::FileSystemURL& url);
197
198  // Callback for ApplyRemoteChange.
199  void DidApplyRemoteChange(
200      const SyncStatusCallback& callback,
201      SyncStatusCode status);
202
203  // Callbacks for ProcessLocalChange.
204  void DidGetFileForLocalSync(
205      SyncStatusCode status,
206      const LocalFileSyncInfo& sync_file_info,
207      webkit_blob::ScopedFile snapshot);
208  void ProcessNextChangeForURL(
209      webkit_blob::ScopedFile snapshot,
210      const LocalFileSyncInfo& sync_file_info,
211      const FileChange& last_change,
212      const FileChangeList& changes,
213      SyncStatusCode status);
214
215  // A thin wrapper of get_local_change_processor_.
216  LocalChangeProcessor* GetLocalChangeProcessor(
217      const fileapi::FileSystemURL& url);
218
219  Profile* profile_;
220
221  scoped_refptr<LocalFileSyncContext> sync_context_;
222
223  // Origin to context map. (Assuming that as far as we're in the same
224  // profile single origin wouldn't belong to multiple FileSystemContexts.)
225  std::map<GURL, fileapi::FileSystemContext*> origin_to_contexts_;
226
227  // Origins which have pending changes but have not been initialized yet.
228  // (Used only for handling dirty files left in the local tracker database
229  // after a restart.)
230  std::set<GURL> pending_origins_with_changes_;
231
232  OriginChangeMap origin_change_map_;
233
234  // This callback is non-null while a local sync is running (i.e.
235  // ProcessLocalChange has been called and has not been returned yet).
236  SyncFileCallback local_sync_callback_;
237
238  LocalChangeProcessor* local_change_processor_;
239  GetLocalChangeProcessorCallback get_local_change_processor_;
240
241  ObserverList<Observer> change_observers_;
242
243  DISALLOW_COPY_AND_ASSIGN(LocalFileSyncService);
244};
245
246}  // namespace sync_file_system
247
248#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_
249