| 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 |