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