- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / local / local_file_sync_context.h
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_CONTEXT_H_
6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_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/timer.h"
22 #include "chrome/browser/sync_file_system/local/local_file_sync_status.h"
23 #include "chrome/browser/sync_file_system/sync_callbacks.h"
24 #include "chrome/browser/sync_file_system/sync_status_code.h"
25 #include "url/gurl.h"
26
27 namespace base {
28 class SingleThreadTaskRunner;
29 }
30
31 namespace fileapi {
32 class FileSystemContext;
33 class FileSystemURL;
34 }
35
36 namespace webkit_blob {
37 class ScopedFile;
38 }
39
40 namespace sync_file_system {
41
42 class FileChange;
43 class LocalFileChangeTracker;
44 struct LocalFileSyncInfo;
45 class LocalOriginChangeObserver;
46 class SyncableFileOperationRunner;
47
48 // This class works as a bridge between LocalFileSyncService (which is a
49 // per-profile object) and FileSystemContext's (which is a per-storage-partition
50 // object and may exist multiple in a profile).
51 // An instance of this class is shared by FileSystemContexts and outlives
52 // LocalFileSyncService.
53 class LocalFileSyncContext
54     : public base::RefCountedThreadSafe<LocalFileSyncContext>,
55       public LocalFileSyncStatus::Observer {
56  public:
57   enum SyncMode {
58     SYNC_EXCLUSIVE,
59     SYNC_SNAPSHOT,
60   };
61
62   typedef base::Callback<void(
63       SyncStatusCode status,
64       const LocalFileSyncInfo& sync_file_info,
65       webkit_blob::ScopedFile snapshot)>
66           LocalFileSyncInfoCallback;
67
68   typedef base::Callback<void(SyncStatusCode status,
69                               bool has_pending_changes)>
70       HasPendingLocalChangeCallback;
71
72   LocalFileSyncContext(const base::FilePath& base_path,
73                        base::SingleThreadTaskRunner* ui_task_runner,
74                        base::SingleThreadTaskRunner* io_task_runner);
75
76   // Initializes |file_system_context| for syncable file operations
77   // and registers the it into the internal map.
78   // Calling this multiple times for the same file_system_context is valid.
79   // This method must be called on UI thread.
80   void MaybeInitializeFileSystemContext(
81       const GURL& source_url,
82       fileapi::FileSystemContext* file_system_context,
83       const SyncStatusCallback& callback);
84
85   // Called when the corresponding LocalFileSyncService exits.
86   // This method must be called on UI thread.
87   void ShutdownOnUIThread();
88
89   // Picks a file for next local sync and returns it after disabling writes
90   // for the file.
91   // This method must be called on UI thread.
92   void GetFileForLocalSync(fileapi::FileSystemContext* file_system_context,
93                            const LocalFileSyncInfoCallback& callback);
94
95   // TODO(kinuko): Make this private.
96   // Clears all pending local changes for |url|. |done_callback| is called
97   // when the changes are cleared.
98   // This method must be called on UI thread.
99   void ClearChangesForURL(fileapi::FileSystemContext* file_system_context,
100                           const fileapi::FileSystemURL& url,
101                           const base::Closure& done_callback);
102
103   // Finalizes SnapshotSync, which must have been started by
104   // PrepareForSync with SYNC_SNAPSHOT.
105   // Updates the on-disk dirty flag for |url| in the tracker DB.
106   // This will clear the dirty flag if |sync_finish_status| is SYNC_STATUS_OK
107   // or SYNC_STATUS_HAS_CONFLICT.
108   // |done_callback| is called when the changes are committed.
109   void FinalizeSnapshotSync(
110       fileapi::FileSystemContext* file_system_context,
111       const fileapi::FileSystemURL& url,
112       SyncStatusCode sync_finish_status,
113       const base::Closure& done_callback);
114
115   // Finalizes ExclusiveSync, which must have been started by
116   // PrepareForSync with SYNC_EXCLUSIVE.
117   void FinalizeExclusiveSync(
118       fileapi::FileSystemContext* file_system_context,
119       const fileapi::FileSystemURL& url,
120       bool clear_local_changes,
121       const base::Closure& done_callback);
122
123   // Prepares for sync |url| by disabling writes on |url|.
124   // If the target |url| is being written and cannot start sync it
125   // returns SYNC_STATUS_WRITING status code via |callback|.
126   // Otherwise returns the current change sets made on |url|.
127   //
128   // If |sync_mode| is SYNC_EXCLUSIVE this leaves the target file locked.
129   // If |sync_mode| is SYNC_SNAPSHOT this creates a snapshot (if the
130   // target file is not deleted) and unlocks the file before returning.
131   //
132   // For SYNC_EXCLUSIVE, caller must call FinalizeExclusiveSync() to finalize
133   // sync and unlock the file.
134   // For SYNC_SNAPSHOT, caller must call FinalizeSnapshotSync() to finalize
135   // sync to reset the mirrored change status and decrement writing count.
136   //
137   // This method must be called on UI thread.
138   void PrepareForSync(fileapi::FileSystemContext* file_system_context,
139                       const fileapi::FileSystemURL& url,
140                       SyncMode sync_mode,
141                       const LocalFileSyncInfoCallback& callback);
142
143   // Registers |url| to wait until sync is enabled for |url|.
144   // |on_syncable_callback| is to be called when |url| becomes syncable
145   // (i.e. when we have no pending writes and the file is successfully locked
146   // for sync).
147   //
148   // Calling this method again while this already has another URL waiting
149   // for sync will overwrite the previously registered URL.
150   //
151   // This method must be called on UI thread.
152   void RegisterURLForWaitingSync(const fileapi::FileSystemURL& url,
153                                  const base::Closure& on_syncable_callback);
154
155   // Applies a remote change.
156   // This method must be called on UI thread.
157   void ApplyRemoteChange(
158       fileapi::FileSystemContext* file_system_context,
159       const FileChange& change,
160       const base::FilePath& local_path,
161       const fileapi::FileSystemURL& url,
162       const SyncStatusCallback& callback);
163
164   // Records a fake local change in the local change tracker.
165   void RecordFakeLocalChange(
166       fileapi::FileSystemContext* file_system_context,
167       const fileapi::FileSystemURL& url,
168       const FileChange& change,
169       const SyncStatusCallback& callback);
170
171   // This must be called on UI thread.
172   void GetFileMetadata(
173       fileapi::FileSystemContext* file_system_context,
174       const fileapi::FileSystemURL& url,
175       const SyncFileMetadataCallback& callback);
176
177   // Returns true via |callback| if the given file |url| has local pending
178   // changes.
179   void HasPendingLocalChanges(
180       fileapi::FileSystemContext* file_system_context,
181       const fileapi::FileSystemURL& url,
182       const HasPendingLocalChangeCallback& callback);
183
184   // They must be called on UI thread.
185   void AddOriginChangeObserver(LocalOriginChangeObserver* observer);
186   void RemoveOriginChangeObserver(LocalOriginChangeObserver* observer);
187
188   // OperationRunner is accessible only on IO thread.
189   base::WeakPtr<SyncableFileOperationRunner> operation_runner() const;
190
191   // SyncContext is accessible only on IO thread.
192   LocalFileSyncStatus* sync_status() const;
193
194   // For testing; override the duration to notify changes from the
195   // default value.
196   void set_mock_notify_changes_duration_in_sec(int duration) {
197     mock_notify_changes_duration_in_sec_ = duration;
198   }
199
200  protected:
201   // LocalFileSyncStatus::Observer overrides. They are called on IO thread.
202   virtual void OnSyncEnabled(const fileapi::FileSystemURL& url) OVERRIDE;
203   virtual void OnWriteEnabled(const fileapi::FileSystemURL& url) OVERRIDE;
204
205  private:
206   typedef base::Callback<void(base::PlatformFileError result)> StatusCallback;
207   typedef std::deque<SyncStatusCallback> StatusCallbackQueue;
208   friend class base::RefCountedThreadSafe<LocalFileSyncContext>;
209   friend class CannedSyncableFileSystem;
210
211   virtual ~LocalFileSyncContext();
212
213   void ShutdownOnIOThread();
214
215   // Starts a timer to eventually call NotifyAvailableChangesOnIOThread.
216   // The caller is expected to update origins_with_pending_changes_ before
217   // calling this.
218   void ScheduleNotifyChangesUpdatedOnIOThread();
219
220   // Called by the internal timer on IO thread to notify changes to UI thread.
221   void NotifyAvailableChangesOnIOThread();
222
223   // Called from NotifyAvailableChangesOnIOThread.
224   void NotifyAvailableChanges(const std::set<GURL>& origins);
225
226   // Helper routines for MaybeInitializeFileSystemContext.
227   void InitializeFileSystemContextOnIOThread(
228       const GURL& source_url,
229       fileapi::FileSystemContext* file_system_context);
230   SyncStatusCode InitializeChangeTrackerOnFileThread(
231       scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
232       fileapi::FileSystemContext* file_system_context,
233       std::set<GURL>* origins_with_changes);
234   void DidInitializeChangeTrackerOnIOThread(
235       scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
236       const GURL& source_url,
237       fileapi::FileSystemContext* file_system_context,
238       std::set<GURL>* origins_with_changes,
239       SyncStatusCode status);
240   void DidInitialize(
241       const GURL& source_url,
242       fileapi::FileSystemContext* file_system_context,
243       SyncStatusCode status);
244
245   // Helper routines for GetFileForLocalSync.
246   void GetNextURLsForSyncOnFileThread(
247       fileapi::FileSystemContext* file_system_context,
248       std::deque<fileapi::FileSystemURL>* urls);
249   void TryPrepareForLocalSync(
250       fileapi::FileSystemContext* file_system_context,
251       std::deque<fileapi::FileSystemURL>* urls,
252       const LocalFileSyncInfoCallback& callback);
253   void DidTryPrepareForLocalSync(
254       fileapi::FileSystemContext* file_system_context,
255       std::deque<fileapi::FileSystemURL>* remaining_urls,
256       const LocalFileSyncInfoCallback& callback,
257       SyncStatusCode status,
258       const LocalFileSyncInfo& sync_file_info,
259       webkit_blob::ScopedFile snapshot);
260
261   // Callback routine for PrepareForSync and GetFileForLocalSync.
262   void DidGetWritingStatusForSync(
263       fileapi::FileSystemContext* file_system_context,
264       SyncStatusCode status,
265       const fileapi::FileSystemURL& url,
266       SyncMode sync_mode,
267       const LocalFileSyncInfoCallback& callback);
268
269   // Helper routine for sync/writing flag handling.
270   //
271   // If |for_snapshot_sync| is true, this increments the writing counter
272   // for |url| (after clearing syncing flag), so that other sync activities
273   // won't step in while snapshot sync is ongoing.
274   // In this case FinalizeSnapshotSyncOnIOThread must be called after the
275   // snapshot sync is finished to decrement the writing counter.
276   void ClearSyncFlagOnIOThread(const fileapi::FileSystemURL& url,
277                                bool for_snapshot_sync);
278   void FinalizeSnapshotSyncOnIOThread(const fileapi::FileSystemURL& url);
279
280   void DidRemoveExistingEntryForApplyRemoteChange(
281       fileapi::FileSystemContext* file_system_context,
282       const FileChange& change,
283       const base::FilePath& local_path,
284       const fileapi::FileSystemURL& url,
285       const SyncStatusCallback& callback,
286       base::PlatformFileError error);
287
288   // Callback routine for ApplyRemoteChange.
289   void DidApplyRemoteChange(
290       const fileapi::FileSystemURL& url,
291       const SyncStatusCallback& callback_on_ui,
292       base::PlatformFileError file_error);
293
294   void DidGetFileMetadata(
295       const SyncFileMetadataCallback& callback,
296       base::PlatformFileError file_error,
297       const base::PlatformFileInfo& file_info);
298
299   base::TimeDelta NotifyChangesDuration();
300
301   void DidCreateDirectoryForCopyIn(
302       fileapi::FileSystemContext* file_system_context,
303       const base::FilePath& local_file_path,
304       const fileapi::FileSystemURL& dest_url,
305       const StatusCallback& callback,
306       base::PlatformFileError error);
307
308   const base::FilePath local_base_path_;
309
310   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
311   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
312
313   // Indicates if the sync service is shutdown on UI thread.
314   bool shutdown_on_ui_;
315
316   // OperationRunner. This must be accessed only on IO thread.
317   scoped_ptr<SyncableFileOperationRunner> operation_runner_;
318
319   // Keeps track of writing/syncing status.
320   // This must be accessed only on IO thread.
321   scoped_ptr<LocalFileSyncStatus> sync_status_;
322
323   // Pointers to file system contexts that have been initialized for
324   // synchronization (i.e. that own this instance).
325   // This must be accessed only on UI thread.
326   std::set<fileapi::FileSystemContext*> file_system_contexts_;
327
328   // Accessed only on UI thread.
329   std::map<fileapi::FileSystemContext*, StatusCallbackQueue>
330       pending_initialize_callbacks_;
331
332   // A URL and associated callback waiting for sync is enabled.
333   // Accessed only on IO thread.
334   fileapi::FileSystemURL url_waiting_sync_on_io_;
335   base::Closure url_syncable_callback_;
336
337   // Used only on IO thread for available changes notifications.
338   base::Time last_notified_changes_;
339   scoped_ptr<base::OneShotTimer<LocalFileSyncContext> > timer_on_io_;
340   std::set<GURL> origins_with_pending_changes_;
341
342   ObserverList<LocalOriginChangeObserver> origin_change_observers_;
343
344   int mock_notify_changes_duration_in_sec_;
345
346   DISALLOW_COPY_AND_ASSIGN(LocalFileSyncContext);
347 };
348
349 }  // namespace sync_file_system
350
351 #endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_CONTEXT_H_