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.
5 #ifndef WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_
6 #define WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_
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"
29 class SingleThreadTaskRunner
;
33 class FileSystemContext
;
37 namespace sync_file_system
{
40 class LocalFileChangeTracker
;
41 struct LocalFileSyncInfo
;
42 class LocalOriginChangeObserver
;
43 class SyncableFileOperationRunner
;
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
{
54 typedef base::Callback
<void(
55 SyncStatusCode status
, const LocalFileSyncInfo
& sync_file_info
)>
56 LocalFileSyncInfoCallback
;
58 typedef base::Callback
<void(SyncStatusCode status
,
59 bool has_pending_changes
)>
60 HasPendingLocalChangeCallback
;
62 LocalFileSyncContext(base::SingleThreadTaskRunner
* ui_task_runner
,
63 base::SingleThreadTaskRunner
* io_task_runner
);
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
);
75 // Called when the corresponding LocalFileSyncService exits.
76 // This method must be called on UI thread.
77 void ShutdownOnUIThread();
79 // Picks a file for next local sync and returns it after disabling writes
81 // This method must be called on UI thread.
82 void GetFileForLocalSync(fileapi::FileSystemContext
* file_system_context
,
83 const LocalFileSyncInfoCallback
& callback
);
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
);
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
);
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
);
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
112 // Calling this method again while this already has another URL waiting
113 // for sync will overwrite the previously registered URL.
115 // This method must be called on UI thread.
116 void RegisterURLForWaitingSync(const fileapi::FileSystemURL
& url
,
117 const base::Closure
& on_syncable_callback
);
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
);
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
);
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
);
141 // Returns true via |callback| if the given file |url| has local pending
143 void HasPendingLocalChanges(
144 fileapi::FileSystemContext
* file_system_context
,
145 const fileapi::FileSystemURL
& url
,
146 const HasPendingLocalChangeCallback
& callback
);
148 // They must be called on UI thread.
149 void AddOriginChangeObserver(LocalOriginChangeObserver
* observer
);
150 void RemoveOriginChangeObserver(LocalOriginChangeObserver
* observer
);
152 // OperationRunner is accessible only on IO thread.
153 base::WeakPtr
<SyncableFileOperationRunner
> operation_runner() const;
155 // SyncContext is accessible only on IO thread.
156 LocalFileSyncStatus
* sync_status() const;
158 // For testing; override the duration to notify changes from the
160 void set_mock_notify_changes_duration_in_sec(int duration
) {
161 mock_notify_changes_duration_in_sec_
= duration
;
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
;
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
;
175 virtual ~LocalFileSyncContext();
177 void ShutdownOnIOThread();
179 // Starts a timer to eventually call NotifyAvailableChangesOnIOThread.
180 // The caller is expected to update origins_with_pending_changes_ before
182 void ScheduleNotifyChangesUpdatedOnIOThread();
184 // Called by the internal timer on IO thread to notify changes to UI thread.
185 void NotifyAvailableChangesOnIOThread();
187 // Called from NotifyAvailableChangesOnIOThread.
188 void NotifyAvailableChanges(const std::set
<GURL
>& origins
);
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
);
207 const GURL
& source_url
,
208 fileapi::FileSystemContext
* file_system_context
,
209 SyncStatusCode status
);
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
);
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
);
233 // Helper routine for ClearSyncFlagForURL.
234 void EnableWritingOnIOThread(const fileapi::FileSystemURL
& url
);
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
);
244 // Callback routine for ApplyRemoteChange.
245 void DidApplyRemoteChange(
246 const fileapi::FileSystemURL
& url
,
247 const SyncStatusCallback
& callback_on_ui
,
248 base::PlatformFileError file_error
);
250 void DidGetFileMetadata(
251 const SyncFileMetadataCallback
& callback
,
252 base::PlatformFileError file_error
,
253 const base::PlatformFileInfo
& file_info
,
254 const base::FilePath
& platform_path
);
256 base::TimeDelta
NotifyChangesDuration();
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
);
265 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner_
;
266 scoped_refptr
<base::SingleThreadTaskRunner
> io_task_runner_
;
268 // Indicates if the sync service is shutdown on UI thread.
269 bool shutdown_on_ui_
;
271 // OperationRunner. This must be accessed only on IO thread.
272 scoped_ptr
<SyncableFileOperationRunner
> operation_runner_
;
274 // Keeps track of writing/syncing status.
275 // This must be accessed only on IO thread.
276 scoped_ptr
<LocalFileSyncStatus
> sync_status_
;
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_
;
283 // Accessed only on UI thread.
284 std::map
<fileapi::FileSystemContext
*, StatusCallbackQueue
>
285 pending_initialize_callbacks_
;
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_
;
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_
;
297 ObserverList
<LocalOriginChangeObserver
> origin_change_observers_
;
299 int mock_notify_changes_duration_in_sec_
;
301 DISALLOW_COPY_AND_ASSIGN(LocalFileSyncContext
);
304 } // namespace sync_file_system
306 #endif // WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_