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;
29 namespace webkit_blob {
33 namespace sync_file_system {
36 class LocalChangeProcessor;
37 class LocalFileSyncContext;
38 struct LocalFileSyncInfo;
40 // Maintains local file change tracker and sync status.
41 // Owned by SyncFileSystemService (which is a per-profile object).
42 class LocalFileSyncService
43 : public RemoteChangeProcessor,
44 public LocalOriginChangeObserver,
45 public base::SupportsWeakPtr<LocalFileSyncService> {
50 virtual ~Observer() {}
52 // This is called when there're one or more local changes available.
53 // |pending_changes_hint| indicates the pending queue length to help sync
54 // scheduling but the value may not be accurately reflect the real-time
56 virtual void OnLocalChangeAvailable(int64 pending_changes_hint) = 0;
59 DISALLOW_COPY_AND_ASSIGN(Observer);
62 typedef base::Callback<void(SyncStatusCode status,
63 bool has_pending_changes)>
64 HasPendingLocalChangeCallback;
66 explicit LocalFileSyncService(Profile* profile);
67 virtual ~LocalFileSyncService();
71 void MaybeInitializeFileSystemContext(
72 const GURL& app_origin,
73 fileapi::FileSystemContext* file_system_context,
74 const SyncStatusCallback& callback);
76 void AddChangeObserver(Observer* observer);
78 // Registers |url| to wait until sync is enabled for |url|.
79 // |on_syncable_callback| is to be called when |url| becomes syncable
80 // (i.e. when we have no pending writes and the file is successfully locked
82 // Calling this method again while this already has another URL waiting
83 // for sync will overwrite the previously registered URL.
84 void RegisterURLForWaitingSync(const fileapi::FileSystemURL& url,
85 const base::Closure& on_syncable_callback);
87 // Synchronize one (or a set of) local change(s) to the remote server
88 // using local_change_processor given by SetLocalChangeProcessor().
89 // |processor| must have same or longer lifetime than this service.
90 // It is invalid to call this method before calling SetLocalChangeProcessor().
91 void ProcessLocalChange(const SyncFileCallback& callback);
93 // Sets a local change processor. This must be called before any
94 // ProcessLocalChange().
95 void SetLocalChangeProcessor(LocalChangeProcessor* processor);
97 // Returns true via |callback| if the given file |url| has local pending
99 void HasPendingLocalChanges(
100 const fileapi::FileSystemURL& url,
101 const HasPendingLocalChangeCallback& callback);
103 // Returns the metadata of a remote file pointed by |url|.
104 virtual void GetLocalFileMetadata(
105 const fileapi::FileSystemURL& url,
106 const SyncFileMetadataCallback& callback);
108 // RemoteChangeProcessor overrides.
109 virtual void PrepareForProcessRemoteChange(
110 const fileapi::FileSystemURL& url,
111 const PrepareChangeCallback& callback) OVERRIDE;
112 virtual void ApplyRemoteChange(
113 const FileChange& change,
114 const base::FilePath& local_path,
115 const fileapi::FileSystemURL& url,
116 const SyncStatusCallback& callback) OVERRIDE;
117 virtual void FinalizeRemoteSync(
118 const fileapi::FileSystemURL& url,
119 bool clear_local_changes,
120 const base::Closure& completion_callback) OVERRIDE;
121 virtual void RecordFakeLocalChange(
122 const fileapi::FileSystemURL& url,
123 const FileChange& change,
124 const SyncStatusCallback& callback) OVERRIDE;
126 // LocalOriginChangeObserver override.
127 virtual void OnChangesAvailableInOrigins(
128 const std::set<GURL>& origins) OVERRIDE;
130 // Called when a particular origin (app) is disabled/enabled while
131 // the service is running. This may be called for origins/apps that
132 // are not initialized for the service.
133 void SetOriginEnabled(const GURL& origin, bool enabled);
136 friend class OriginChangeMapTest;
138 class OriginChangeMap {
140 typedef std::map<GURL, int64> Map;
145 // Sets |origin| to the next origin to process. (For now we simply apply
146 // round-robin to pick the next origin to avoid starvation.)
147 // Returns false if no origins to process.
148 bool NextOriginToProcess(GURL* origin);
150 int64 GetTotalChangeCount() const;
152 // Update change_count_map_ for |origin|.
153 void SetOriginChangeCount(const GURL& origin, int64 changes);
155 void SetOriginEnabled(const GURL& origin, bool enabled);
158 // Per-origin changes (cached info, could be stale).
159 Map change_count_map_;
162 // Holds a set of disabled (but initialized) origins.
163 std::set<GURL> disabled_origins_;
166 void DidInitializeFileSystemContext(
167 const GURL& app_origin,
168 fileapi::FileSystemContext* file_system_context,
169 const SyncStatusCallback& callback,
170 SyncStatusCode status);
171 void DidInitializeForRemoteSync(
172 const fileapi::FileSystemURL& url,
173 fileapi::FileSystemContext* file_system_context,
174 const PrepareChangeCallback& callback,
175 SyncStatusCode status);
177 // Runs local_sync_callback_ and resets it.
178 void RunLocalSyncCallback(
179 SyncStatusCode status,
180 const fileapi::FileSystemURL& url);
182 // Callbacks for ProcessLocalChange.
183 void DidGetFileForLocalSync(
184 SyncStatusCode status,
185 const LocalFileSyncInfo& sync_file_info,
186 webkit_blob::ScopedFile snapshot);
187 void ProcessNextChangeForURL(
188 webkit_blob::ScopedFile snapshot,
189 const LocalFileSyncInfo& sync_file_info,
190 const FileChange& last_change,
191 const FileChangeList& changes,
192 SyncStatusCode status);
196 scoped_refptr<LocalFileSyncContext> sync_context_;
198 // Origin to context map. (Assuming that as far as we're in the same
199 // profile single origin wouldn't belong to multiple FileSystemContexts.)
200 std::map<GURL, fileapi::FileSystemContext*> origin_to_contexts_;
202 // Origins which have pending changes but have not been initialized yet.
203 // (Used only for handling dirty files left in the local tracker database
205 std::set<GURL> pending_origins_with_changes_;
207 OriginChangeMap origin_change_map_;
209 // This callback is non-null while a local sync is running (i.e.
210 // ProcessLocalChange has been called and has not been returned yet).
211 SyncFileCallback local_sync_callback_;
213 LocalChangeProcessor* local_change_processor_;
215 ObserverList<Observer> change_observers_;
217 DISALLOW_COPY_AND_ASSIGN(LocalFileSyncService);
220 } // namespace sync_file_system
222 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_