OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_ | |
6 #define WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_ | |
7 | |
8 #include <deque> | |
9 #include <map> | |
10 #include <set> | |
11 #include <string> | |
12 | |
13 #include "base/basictypes.h" | |
14 #include "base/callback.h" | |
15 #include "base/files/file_path.h" | |
16 #include "base/logging.h" | |
17 #include "base/memory/ref_counted.h" | |
18 #include "base/memory/scoped_ptr.h" | |
19 #include "base/memory/weak_ptr.h" | |
20 #include "base/observer_list.h" | |
21 #include "base/timer.h" | |
22 #include "googleurl/src/gurl.h" | |
23 #include "webkit/fileapi/syncable/local_file_sync_status.h" | |
24 #include "webkit/fileapi/syncable/sync_callbacks.h" | |
25 #include "webkit/fileapi/syncable/sync_status_code.h" | |
26 #include "webkit/storage/webkit_storage_export.h" | |
27 | |
28 namespace base { | |
29 class SingleThreadTaskRunner; | |
30 } | |
31 | |
32 namespace fileapi { | |
33 class FileSystemContext; | |
34 class FileSystemURL; | |
35 } | |
36 | |
37 namespace sync_file_system { | |
38 | |
39 class FileChange; | |
40 class LocalFileChangeTracker; | |
41 struct LocalFileSyncInfo; | |
42 class LocalOriginChangeObserver; | |
43 class SyncableFileOperationRunner; | |
44 | |
45 // This class works as a bridge between LocalFileSyncService (which is a | |
46 // per-profile object) and FileSystemContext's (which is a per-storage-partition | |
47 // object and may exist multiple in a profile). | |
48 // An instance of this class is shared by FileSystemContexts and outlives | |
49 // LocalFileSyncService. | |
50 class WEBKIT_STORAGE_EXPORT LocalFileSyncContext | |
51 : public base::RefCountedThreadSafe<LocalFileSyncContext>, | |
52 public LocalFileSyncStatus::Observer { | |
53 public: | |
54 typedef base::Callback<void( | |
55 SyncStatusCode status, const LocalFileSyncInfo& sync_file_info)> | |
56 LocalFileSyncInfoCallback; | |
57 | |
58 typedef base::Callback<void(SyncStatusCode status, | |
59 bool has_pending_changes)> | |
60 HasPendingLocalChangeCallback; | |
61 | |
62 LocalFileSyncContext(base::SingleThreadTaskRunner* ui_task_runner, | |
63 base::SingleThreadTaskRunner* io_task_runner); | |
64 | |
65 // Initializes |file_system_context| for syncable file operations for | |
66 // |service_name| and registers the it into the internal map. | |
67 // Calling this multiple times for the same file_system_context is valid. | |
68 // This method must be called on UI thread. | |
69 void MaybeInitializeFileSystemContext( | |
70 const GURL& source_url, | |
71 const std::string& service_name, | |
72 fileapi::FileSystemContext* file_system_context, | |
73 const SyncStatusCallback& callback); | |
74 | |
75 // Called when the corresponding LocalFileSyncService exits. | |
76 // This method must be called on UI thread. | |
77 void ShutdownOnUIThread(); | |
78 | |
79 // Picks a file for next local sync and returns it after disabling writes | |
80 // for the file. | |
81 // This method must be called on UI thread. | |
82 void GetFileForLocalSync(fileapi::FileSystemContext* file_system_context, | |
83 const LocalFileSyncInfoCallback& callback); | |
84 | |
85 // Clears all pending local changes for |url|. |done_callback| is called | |
86 // when the changes are cleared. | |
87 // This method must be called on UI thread. | |
88 void ClearChangesForURL(fileapi::FileSystemContext* file_system_context, | |
89 const fileapi::FileSystemURL& url, | |
90 const base::Closure& done_callback); | |
91 | |
92 // A local or remote sync has been finished (either successfully or | |
93 // with an error). Clears the internal sync flag and enable writing for |url|. | |
94 // This method must be called on UI thread. | |
95 void ClearSyncFlagForURL(const fileapi::FileSystemURL& url); | |
96 | |
97 // Prepares for sync |url| by disabling writes on |url|. | |
98 // If the target |url| is being written and cannot start sync it | |
99 // returns SYNC_STATUS_WRITING status code via |callback|. | |
100 // Otherwise it disables writes, marks the |url| syncing and returns | |
101 // the current change set made on |url|. | |
102 // This method must be called on UI thread. | |
103 void PrepareForSync(fileapi::FileSystemContext* file_system_context, | |
104 const fileapi::FileSystemURL& url, | |
105 const LocalFileSyncInfoCallback& callback); | |
106 | |
107 // Registers |url| to wait until sync is enabled for |url|. | |
108 // |on_syncable_callback| is to be called when |url| becomes syncable | |
109 // (i.e. when we have no pending writes and the file is successfully locked | |
110 // for sync). | |
111 // | |
112 // Calling this method again while this already has another URL waiting | |
113 // for sync will overwrite the previously registered URL. | |
114 // | |
115 // This method must be called on UI thread. | |
116 void RegisterURLForWaitingSync(const fileapi::FileSystemURL& url, | |
117 const base::Closure& on_syncable_callback); | |
118 | |
119 // Applies a remote change. | |
120 // This method must be called on UI thread. | |
121 void ApplyRemoteChange( | |
122 fileapi::FileSystemContext* file_system_context, | |
123 const FileChange& change, | |
124 const base::FilePath& local_path, | |
125 const fileapi::FileSystemURL& url, | |
126 const SyncStatusCallback& callback); | |
127 | |
128 // Records a fake local change in the local change tracker. | |
129 void RecordFakeLocalChange( | |
130 fileapi::FileSystemContext* file_system_context, | |
131 const fileapi::FileSystemURL& url, | |
132 const FileChange& change, | |
133 const SyncStatusCallback& callback); | |
134 | |
135 // This must be called on UI thread. | |
136 void GetFileMetadata( | |
137 fileapi::FileSystemContext* file_system_context, | |
138 const fileapi::FileSystemURL& url, | |
139 const SyncFileMetadataCallback& callback); | |
140 | |
141 // Returns true via |callback| if the given file |url| has local pending | |
142 // changes. | |
143 void HasPendingLocalChanges( | |
144 fileapi::FileSystemContext* file_system_context, | |
145 const fileapi::FileSystemURL& url, | |
146 const HasPendingLocalChangeCallback& callback); | |
147 | |
148 // They must be called on UI thread. | |
149 void AddOriginChangeObserver(LocalOriginChangeObserver* observer); | |
150 void RemoveOriginChangeObserver(LocalOriginChangeObserver* observer); | |
151 | |
152 // OperationRunner is accessible only on IO thread. | |
153 base::WeakPtr<SyncableFileOperationRunner> operation_runner() const; | |
154 | |
155 // SyncContext is accessible only on IO thread. | |
156 LocalFileSyncStatus* sync_status() const; | |
157 | |
158 // For testing; override the duration to notify changes from the | |
159 // default value. | |
160 void set_mock_notify_changes_duration_in_sec(int duration) { | |
161 mock_notify_changes_duration_in_sec_ = duration; | |
162 } | |
163 | |
164 protected: | |
165 // LocalFileSyncStatus::Observer overrides. They are called on IO thread. | |
166 virtual void OnSyncEnabled(const fileapi::FileSystemURL& url) OVERRIDE; | |
167 virtual void OnWriteEnabled(const fileapi::FileSystemURL& url) OVERRIDE; | |
168 | |
169 private: | |
170 typedef base::Callback<void(base::PlatformFileError result)> StatusCallback; | |
171 typedef std::deque<SyncStatusCallback> StatusCallbackQueue; | |
172 friend class base::RefCountedThreadSafe<LocalFileSyncContext>; | |
173 friend class CannedSyncableFileSystem; | |
174 | |
175 virtual ~LocalFileSyncContext(); | |
176 | |
177 void ShutdownOnIOThread(); | |
178 | |
179 // Starts a timer to eventually call NotifyAvailableChangesOnIOThread. | |
180 // The caller is expected to update origins_with_pending_changes_ before | |
181 // calling this. | |
182 void ScheduleNotifyChangesUpdatedOnIOThread(); | |
183 | |
184 // Called by the internal timer on IO thread to notify changes to UI thread. | |
185 void NotifyAvailableChangesOnIOThread(); | |
186 | |
187 // Called from NotifyAvailableChangesOnIOThread. | |
188 void NotifyAvailableChanges(const std::set<GURL>& origins); | |
189 | |
190 // Helper routines for MaybeInitializeFileSystemContext. | |
191 void InitializeFileSystemContextOnIOThread( | |
192 const GURL& source_url, | |
193 const std::string& service_name, | |
194 fileapi::FileSystemContext* file_system_context); | |
195 SyncStatusCode InitializeChangeTrackerOnFileThread( | |
196 scoped_ptr<LocalFileChangeTracker>* tracker_ptr, | |
197 fileapi::FileSystemContext* file_system_context, | |
198 std::set<GURL>* origins_with_changes); | |
199 void DidInitializeChangeTrackerOnIOThread( | |
200 scoped_ptr<LocalFileChangeTracker>* tracker_ptr, | |
201 const GURL& source_url, | |
202 const std::string& service_name, | |
203 fileapi::FileSystemContext* file_system_context, | |
204 std::set<GURL>* origins_with_changes, | |
205 SyncStatusCode status); | |
206 void DidInitialize( | |
207 const GURL& source_url, | |
208 fileapi::FileSystemContext* file_system_context, | |
209 SyncStatusCode status); | |
210 | |
211 // Helper routines for GetFileForLocalSync. | |
212 void GetNextURLsForSyncOnFileThread( | |
213 fileapi::FileSystemContext* file_system_context, | |
214 std::deque<fileapi::FileSystemURL>* urls); | |
215 void TryPrepareForLocalSync( | |
216 fileapi::FileSystemContext* file_system_context, | |
217 std::deque<fileapi::FileSystemURL>* urls, | |
218 const LocalFileSyncInfoCallback& callback); | |
219 void DidTryPrepareForLocalSync( | |
220 fileapi::FileSystemContext* file_system_context, | |
221 std::deque<fileapi::FileSystemURL>* remaining_urls, | |
222 const LocalFileSyncInfoCallback& callback, | |
223 SyncStatusCode status, | |
224 const LocalFileSyncInfo& sync_file_info); | |
225 | |
226 // Callback routine for PrepareForSync and GetFileForLocalSync. | |
227 void DidGetWritingStatusForSync( | |
228 fileapi::FileSystemContext* file_system_context, | |
229 SyncStatusCode status, | |
230 const fileapi::FileSystemURL& url, | |
231 const LocalFileSyncInfoCallback& callback); | |
232 | |
233 // Helper routine for ClearSyncFlagForURL. | |
234 void EnableWritingOnIOThread(const fileapi::FileSystemURL& url); | |
235 | |
236 void DidRemoveExistingEntryForApplyRemoteChange( | |
237 fileapi::FileSystemContext* file_system_context, | |
238 const FileChange& change, | |
239 const base::FilePath& local_path, | |
240 const fileapi::FileSystemURL& url, | |
241 const SyncStatusCallback& callback, | |
242 base::PlatformFileError error); | |
243 | |
244 // Callback routine for ApplyRemoteChange. | |
245 void DidApplyRemoteChange( | |
246 const fileapi::FileSystemURL& url, | |
247 const SyncStatusCallback& callback_on_ui, | |
248 base::PlatformFileError file_error); | |
249 | |
250 void DidGetFileMetadata( | |
251 const SyncFileMetadataCallback& callback, | |
252 base::PlatformFileError file_error, | |
253 const base::PlatformFileInfo& file_info, | |
254 const base::FilePath& platform_path); | |
255 | |
256 base::TimeDelta NotifyChangesDuration(); | |
257 | |
258 void DidCreateDirectoryForCopyIn( | |
259 fileapi::FileSystemContext* file_system_context, | |
260 const base::FilePath& local_file_path, | |
261 const fileapi::FileSystemURL& dest_url, | |
262 const StatusCallback& callback, | |
263 base::PlatformFileError error); | |
264 | |
265 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | |
266 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; | |
267 | |
268 // Indicates if the sync service is shutdown on UI thread. | |
269 bool shutdown_on_ui_; | |
270 | |
271 // OperationRunner. This must be accessed only on IO thread. | |
272 scoped_ptr<SyncableFileOperationRunner> operation_runner_; | |
273 | |
274 // Keeps track of writing/syncing status. | |
275 // This must be accessed only on IO thread. | |
276 scoped_ptr<LocalFileSyncStatus> sync_status_; | |
277 | |
278 // Pointers to file system contexts that have been initialized for | |
279 // synchronization (i.e. that own this instance). | |
280 // This must be accessed only on UI thread. | |
281 std::set<fileapi::FileSystemContext*> file_system_contexts_; | |
282 | |
283 // Accessed only on UI thread. | |
284 std::map<fileapi::FileSystemContext*, StatusCallbackQueue> | |
285 pending_initialize_callbacks_; | |
286 | |
287 // A URL and associated callback waiting for sync is enabled. | |
288 // Accessed only on IO thread. | |
289 fileapi::FileSystemURL url_waiting_sync_on_io_; | |
290 base::Closure url_syncable_callback_; | |
291 | |
292 // Used only on IO thread for available changes notifications. | |
293 base::Time last_notified_changes_; | |
294 scoped_ptr<base::OneShotTimer<LocalFileSyncContext> > timer_on_io_; | |
295 std::set<GURL> origins_with_pending_changes_; | |
296 | |
297 ObserverList<LocalOriginChangeObserver> origin_change_observers_; | |
298 | |
299 int mock_notify_changes_duration_in_sec_; | |
300 | |
301 DISALLOW_COPY_AND_ASSIGN(LocalFileSyncContext); | |
302 }; | |
303 | |
304 } // namespace sync_file_system | |
305 | |
306 #endif // WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_ | |
OLD | NEW |