Upstream version 5.34.104.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   void UpdateChangesForOrigin(const GURL& origin);
194
195   // They must be called on UI thread.
196   void AddOriginChangeObserver(LocalOriginChangeObserver* observer);
197   void RemoveOriginChangeObserver(LocalOriginChangeObserver* observer);
198
199   // OperationRunner is accessible only on IO thread.
200   base::WeakPtr<SyncableFileOperationRunner> operation_runner() const;
201
202   // SyncContext is accessible only on IO thread.
203   LocalFileSyncStatus* sync_status() const;
204
205   // For testing; override the duration to notify changes from the
206   // default value.
207   void set_mock_notify_changes_duration_in_sec(int duration) {
208     mock_notify_changes_duration_in_sec_ = duration;
209   }
210
211  protected:
212   // LocalFileSyncStatus::Observer overrides. They are called on IO thread.
213   virtual void OnSyncEnabled(const fileapi::FileSystemURL& url) OVERRIDE;
214   virtual void OnWriteEnabled(const fileapi::FileSystemURL& url) OVERRIDE;
215
216  private:
217   typedef base::Callback<void(base::File::Error result)> StatusCallback;
218   typedef std::deque<SyncStatusCallback> StatusCallbackQueue;
219   friend class base::RefCountedThreadSafe<LocalFileSyncContext>;
220   friend class CannedSyncableFileSystem;
221
222   virtual ~LocalFileSyncContext();
223
224   void ShutdownOnIOThread();
225
226   // Starts a timer to eventually call NotifyAvailableChangesOnIOThread.
227   // The caller is expected to update origins_with_pending_changes_ before
228   // calling this.
229   void ScheduleNotifyChangesUpdatedOnIOThread();
230
231   // Called by the internal timer on IO thread to notify changes to UI thread.
232   void NotifyAvailableChangesOnIOThread();
233
234   // Called from NotifyAvailableChangesOnIOThread.
235   void NotifyAvailableChanges(const std::set<GURL>& origins);
236
237   // Helper routines for MaybeInitializeFileSystemContext.
238   void InitializeFileSystemContextOnIOThread(
239       const GURL& source_url,
240       fileapi::FileSystemContext* file_system_context,
241       const GURL& /* root */,
242       const std::string& /* name */,
243       base::File::Error error);
244   SyncStatusCode InitializeChangeTrackerOnFileThread(
245       scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
246       fileapi::FileSystemContext* file_system_context,
247       std::set<GURL>* origins_with_changes);
248   void DidInitializeChangeTrackerOnIOThread(
249       scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
250       const GURL& source_url,
251       fileapi::FileSystemContext* file_system_context,
252       std::set<GURL>* origins_with_changes,
253       SyncStatusCode status);
254   void DidInitialize(
255       const GURL& source_url,
256       fileapi::FileSystemContext* file_system_context,
257       SyncStatusCode status);
258
259   // Helper routines for GetFileForLocalSync.
260   void GetNextURLsForSyncOnFileThread(
261       fileapi::FileSystemContext* file_system_context,
262       std::deque<fileapi::FileSystemURL>* urls);
263   void TryPrepareForLocalSync(
264       fileapi::FileSystemContext* file_system_context,
265       std::deque<fileapi::FileSystemURL>* urls,
266       const LocalFileSyncInfoCallback& callback);
267   void DidTryPrepareForLocalSync(
268       fileapi::FileSystemContext* file_system_context,
269       std::deque<fileapi::FileSystemURL>* remaining_urls,
270       const LocalFileSyncInfoCallback& callback,
271       SyncStatusCode status,
272       const LocalFileSyncInfo& sync_file_info,
273       webkit_blob::ScopedFile snapshot);
274
275   // Callback routine for PrepareForSync and GetFileForLocalSync.
276   void DidGetWritingStatusForSync(
277       fileapi::FileSystemContext* file_system_context,
278       SyncStatusCode status,
279       const fileapi::FileSystemURL& url,
280       SyncMode sync_mode,
281       const LocalFileSyncInfoCallback& callback);
282
283   // Helper routine for sync/writing flag handling.
284   //
285   // If |for_snapshot_sync| is true, this increments the writing counter
286   // for |url| (after clearing syncing flag), so that other sync activities
287   // won't step in while snapshot sync is ongoing.
288   // In this case FinalizeSnapshotSyncOnIOThread must be called after the
289   // snapshot sync is finished to decrement the writing counter.
290   void ClearSyncFlagOnIOThread(const fileapi::FileSystemURL& url,
291                                bool for_snapshot_sync);
292   void FinalizeSnapshotSyncOnIOThread(const fileapi::FileSystemURL& url);
293
294   void HandleRemoteDelete(
295       fileapi::FileSystemContext* file_system_context,
296       const fileapi::FileSystemURL& url,
297       const SyncStatusCallback& callback);
298   void HandleRemoteAddOrUpdate(
299       fileapi::FileSystemContext* file_system_context,
300       const FileChange& change,
301       const base::FilePath& local_path,
302       const fileapi::FileSystemURL& url,
303       const SyncStatusCallback& callback);
304   void DidRemoveExistingEntryForRemoteAddOrUpdate(
305       fileapi::FileSystemContext* file_system_context,
306       const FileChange& change,
307       const base::FilePath& local_path,
308       const fileapi::FileSystemURL& url,
309       const SyncStatusCallback& callback,
310       base::File::Error error);
311
312   // Callback routine for ApplyRemoteChange.
313   void DidApplyRemoteChange(
314       const fileapi::FileSystemURL& url,
315       const SyncStatusCallback& callback_on_ui,
316       base::File::Error file_error);
317
318   void DidGetFileMetadata(
319       const SyncFileMetadataCallback& callback,
320       base::File::Error file_error,
321       const base::File::Info& file_info);
322
323   base::TimeDelta NotifyChangesDuration();
324
325   void DidCreateDirectoryForCopyIn(
326       fileapi::FileSystemContext* file_system_context,
327       const base::FilePath& local_file_path,
328       const fileapi::FileSystemURL& dest_url,
329       const StatusCallback& callback,
330       base::File::Error error);
331
332   const base::FilePath local_base_path_;
333   leveldb::Env* env_override_;
334
335   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
336   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
337
338   // Indicates if the sync service is shutdown.
339   bool shutdown_on_ui_;  // Updated and referred only on UI thread.
340   bool shutdown_on_io_;  // Updated and referred only on IO thread.
341
342   // OperationRunner. This must be accessed only on IO thread.
343   scoped_ptr<SyncableFileOperationRunner> operation_runner_;
344
345   // Keeps track of writing/syncing status.
346   // This must be accessed only on IO thread.
347   scoped_ptr<LocalFileSyncStatus> sync_status_;
348
349   // Pointers to file system contexts that have been initialized for
350   // synchronization (i.e. that own this instance).
351   // This must be accessed only on UI thread.
352   std::set<fileapi::FileSystemContext*> file_system_contexts_;
353
354   // Accessed only on UI thread.
355   std::map<fileapi::FileSystemContext*, StatusCallbackQueue>
356       pending_initialize_callbacks_;
357
358   // A URL and associated callback waiting for sync is enabled.
359   // Accessed only on IO thread.
360   fileapi::FileSystemURL url_waiting_sync_on_io_;
361   base::Closure url_syncable_callback_;
362
363   // Used only on IO thread for available changes notifications.
364   base::Time last_notified_changes_;
365   scoped_ptr<base::OneShotTimer<LocalFileSyncContext> > timer_on_io_;
366   std::set<GURL> origins_with_pending_changes_;
367
368   // Populated while root directory deletion is being handled for
369   // ApplyRemoteChange(). Modified only on IO thread.
370   scoped_ptr<RootDeleteHelper> root_delete_helper_;
371
372   ObserverList<LocalOriginChangeObserver> origin_change_observers_;
373
374   int mock_notify_changes_duration_in_sec_;
375
376   DISALLOW_COPY_AND_ASSIGN(LocalFileSyncContext);
377 };
378
379 }  // namespace sync_file_system
380
381 #endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_CONTEXT_H_