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.
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_
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"
26 class FileSystemContext;
33 namespace webkit_blob {
37 namespace sync_file_system {
40 class LocalChangeProcessor;
41 class LocalFileSyncContext;
42 struct LocalFileSyncInfo;
44 // Maintains local file change tracker and sync status.
45 // Owned by SyncFileSystemService (which is a per-profile object).
46 class LocalFileSyncService
47 : public RemoteChangeProcessor,
48 public LocalOriginChangeObserver,
49 public base::SupportsWeakPtr<LocalFileSyncService> {
51 typedef base::Callback<LocalChangeProcessor*(const GURL& origin)>
52 GetLocalChangeProcessorCallback;
57 virtual ~Observer() {}
59 // This is called when there're one or more local changes available.
60 // |pending_changes_hint| indicates the pending queue length to help sync
61 // scheduling but the value may not be accurately reflect the real-time
63 virtual void OnLocalChangeAvailable(int64 pending_changes_hint) = 0;
66 DISALLOW_COPY_AND_ASSIGN(Observer);
69 typedef base::Callback<void(SyncStatusCode status,
70 bool has_pending_changes)>
71 HasPendingLocalChangeCallback;
73 static scoped_ptr<LocalFileSyncService> Create(Profile* profile);
74 static scoped_ptr<LocalFileSyncService> CreateForTesting(
76 leveldb::Env* env_override);
77 virtual ~LocalFileSyncService();
81 void MaybeInitializeFileSystemContext(
82 const GURL& app_origin,
83 fileapi::FileSystemContext* file_system_context,
84 const SyncStatusCallback& callback);
86 void AddChangeObserver(Observer* observer);
88 // Registers |url| to wait until sync is enabled for |url|.
89 // |on_syncable_callback| is to be called when |url| becomes syncable
90 // (i.e. when we have no pending writes and the file is successfully locked
92 // Calling this method again while this already has another URL waiting
93 // for sync will overwrite the previously registered URL.
94 void RegisterURLForWaitingSync(const fileapi::FileSystemURL& url,
95 const base::Closure& on_syncable_callback);
97 // Synchronize one (or a set of) local change(s) to the remote server
98 // using local_change_processor given by SetLocalChangeProcessor().
99 // |processor| must have same or longer lifetime than this service.
100 // It is invalid to call this method before calling SetLocalChangeProcessor().
101 void ProcessLocalChange(const SyncFileCallback& callback);
103 // Sets a local change processor. The value is ignored if
104 // SetLocalChangeProcessorCallback() is called separately.
105 // Either this or SetLocalChangeProcessorCallback() must be called before
106 // any ProcessLocalChange().
107 void SetLocalChangeProcessor(LocalChangeProcessor* local_change_processor);
109 // Sets a closure which gets a local change processor for the given origin.
110 // Note that once this is called it overrides the direct processor setting
111 // done by SetLocalChangeProcessor().
112 // Either this or SetLocalChangeProcessor() must be called before any
113 // ProcessLocalChange().
115 // TODO(kinuko): Remove this method once we stop using multiple backends
116 // (crbug.com/324215), or deprecate the other if we keep doing so.
117 void SetLocalChangeProcessorCallback(
118 const GetLocalChangeProcessorCallback& get_local_change_processor);
120 // Returns true via |callback| if the given file |url| has local pending
122 void HasPendingLocalChanges(
123 const fileapi::FileSystemURL& url,
124 const HasPendingLocalChangeCallback& callback);
126 void PromoteDemotedChanges();
128 // Returns the metadata of a remote file pointed by |url|.
129 virtual void GetLocalFileMetadata(
130 const fileapi::FileSystemURL& url,
131 const SyncFileMetadataCallback& callback);
133 // RemoteChangeProcessor overrides.
134 virtual void PrepareForProcessRemoteChange(
135 const fileapi::FileSystemURL& url,
136 const PrepareChangeCallback& callback) OVERRIDE;
137 virtual void ApplyRemoteChange(
138 const FileChange& change,
139 const base::FilePath& local_path,
140 const fileapi::FileSystemURL& url,
141 const SyncStatusCallback& callback) OVERRIDE;
142 virtual void FinalizeRemoteSync(
143 const fileapi::FileSystemURL& url,
144 bool clear_local_changes,
145 const base::Closure& completion_callback) OVERRIDE;
146 virtual void RecordFakeLocalChange(
147 const fileapi::FileSystemURL& url,
148 const FileChange& change,
149 const SyncStatusCallback& callback) OVERRIDE;
151 // LocalOriginChangeObserver override.
152 virtual void OnChangesAvailableInOrigins(
153 const std::set<GURL>& origins) OVERRIDE;
155 // Called when a particular origin (app) is disabled/enabled while
156 // the service is running. This may be called for origins/apps that
157 // are not initialized for the service.
158 void SetOriginEnabled(const GURL& origin, bool enabled);
161 typedef std::map<GURL, fileapi::FileSystemContext*> OriginToContext;
162 friend class OriginChangeMapTest;
164 class OriginChangeMap {
166 typedef std::map<GURL, int64> Map;
171 // Sets |origin| to the next origin to process. (For now we simply apply
172 // round-robin to pick the next origin to avoid starvation.)
173 // Returns false if no origins to process.
174 bool NextOriginToProcess(GURL* origin);
176 int64 GetTotalChangeCount() const;
178 // Update change_count_map_ for |origin|.
179 void SetOriginChangeCount(const GURL& origin, int64 changes);
181 void SetOriginEnabled(const GURL& origin, bool enabled);
184 // Per-origin changes (cached info, could be stale).
185 Map change_count_map_;
188 // Holds a set of disabled (but initialized) origins.
189 std::set<GURL> disabled_origins_;
192 LocalFileSyncService(Profile* profile, leveldb::Env* env_override);
194 void DidInitializeFileSystemContext(
195 const GURL& app_origin,
196 fileapi::FileSystemContext* file_system_context,
197 const SyncStatusCallback& callback,
198 SyncStatusCode status);
199 void DidInitializeForRemoteSync(
200 const fileapi::FileSystemURL& url,
201 fileapi::FileSystemContext* file_system_context,
202 const PrepareChangeCallback& callback,
203 SyncStatusCode status);
205 // Runs local_sync_callback_ and resets it.
206 void RunLocalSyncCallback(
207 SyncStatusCode status,
208 const fileapi::FileSystemURL& url);
210 // Callback for ApplyRemoteChange.
211 void DidApplyRemoteChange(
212 const SyncStatusCallback& callback,
213 SyncStatusCode status);
215 // Callbacks for ProcessLocalChange.
216 void DidGetFileForLocalSync(
217 SyncStatusCode status,
218 const LocalFileSyncInfo& sync_file_info,
219 webkit_blob::ScopedFile snapshot);
220 void ProcessNextChangeForURL(
221 webkit_blob::ScopedFile snapshot,
222 const LocalFileSyncInfo& sync_file_info,
223 const FileChange& last_change,
224 const FileChangeList& changes,
225 SyncStatusCode status);
227 // A thin wrapper of get_local_change_processor_.
228 LocalChangeProcessor* GetLocalChangeProcessor(
229 const fileapi::FileSystemURL& url);
233 scoped_refptr<LocalFileSyncContext> sync_context_;
235 // Origin to context map. (Assuming that as far as we're in the same
236 // profile single origin wouldn't belong to multiple FileSystemContexts.)
237 OriginToContext origin_to_contexts_;
239 // Origins which have pending changes but have not been initialized yet.
240 // (Used only for handling dirty files left in the local tracker database
242 std::set<GURL> pending_origins_with_changes_;
244 OriginChangeMap origin_change_map_;
246 // This callback is non-null while a local sync is running (i.e.
247 // ProcessLocalChange has been called and has not been returned yet).
248 SyncFileCallback local_sync_callback_;
250 LocalChangeProcessor* local_change_processor_;
251 GetLocalChangeProcessorCallback get_local_change_processor_;
253 ObserverList<Observer> change_observers_;
255 DISALLOW_COPY_AND_ASSIGN(LocalFileSyncService);
258 } // namespace sync_file_system
260 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_