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_SERVICE_H_ 6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 12 #include "base/basictypes.h" 13 #include "base/callback.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/observer_list.h" 17 #include "chrome/browser/sync_file_system/local/local_origin_change_observer.h" 18 #include "chrome/browser/sync_file_system/remote_change_processor.h" 19 #include "chrome/browser/sync_file_system/sync_callbacks.h" 20 #include "chrome/browser/sync_file_system/sync_status_code.h" 21 22 class GURL; 23 class Profile; 24 25 namespace fileapi { 26 class FileSystemContext; 27 } 28 29 namespace webkit_blob { 30 class ScopedFile; 31 } 32 33 namespace sync_file_system { 34 35 class FileChange; 36 class LocalChangeProcessor; 37 class LocalFileSyncContext; 38 struct LocalFileSyncInfo; 39 40 // Maintains local file change tracker and sync status. 41 // Owned by SyncFileSystemService (which is a per-profile object). 42 class LocalFileSyncService 43 : public RemoteChangeProcessor, 44 public LocalOriginChangeObserver, 45 public base::SupportsWeakPtr<LocalFileSyncService> { 46 public: 47 typedef base::Callback<LocalChangeProcessor*(const GURL& origin)> 48 GetLocalChangeProcessorCallback; 49 50 class Observer { 51 public: 52 Observer() {} 53 virtual ~Observer() {} 54 55 // This is called when there're one or more local changes available. 56 // |pending_changes_hint| indicates the pending queue length to help sync 57 // scheduling but the value may not be accurately reflect the real-time 58 // value. 59 virtual void OnLocalChangeAvailable(int64 pending_changes_hint) = 0; 60 61 private: 62 DISALLOW_COPY_AND_ASSIGN(Observer); 63 }; 64 65 typedef base::Callback<void(SyncStatusCode status, 66 bool has_pending_changes)> 67 HasPendingLocalChangeCallback; 68 69 explicit LocalFileSyncService(Profile* profile); 70 virtual ~LocalFileSyncService(); 71 72 void Shutdown(); 73 74 void MaybeInitializeFileSystemContext( 75 const GURL& app_origin, 76 fileapi::FileSystemContext* file_system_context, 77 const SyncStatusCallback& callback); 78 79 void AddChangeObserver(Observer* observer); 80 81 // Registers |url| to wait until sync is enabled for |url|. 82 // |on_syncable_callback| is to be called when |url| becomes syncable 83 // (i.e. when we have no pending writes and the file is successfully locked 84 // for sync). 85 // Calling this method again while this already has another URL waiting 86 // for sync will overwrite the previously registered URL. 87 void RegisterURLForWaitingSync(const fileapi::FileSystemURL& url, 88 const base::Closure& on_syncable_callback); 89 90 // Synchronize one (or a set of) local change(s) to the remote server 91 // using local_change_processor given by SetLocalChangeProcessor(). 92 // |processor| must have same or longer lifetime than this service. 93 // It is invalid to call this method before calling SetLocalChangeProcessor(). 94 void ProcessLocalChange(const SyncFileCallback& callback); 95 96 // Sets a local change processor. The value is ignored if 97 // SetLocalChangeProcessorCallback() is called separately. 98 // Either this or SetLocalChangeProcessorCallback() must be called before 99 // any ProcessLocalChange(). 100 void SetLocalChangeProcessor(LocalChangeProcessor* local_change_processor); 101 102 // Sets a closure which gets a local change processor for the given origin. 103 // Note that once this is called it overrides the direct processor setting 104 // done by SetLocalChangeProcessor(). 105 // Either this or SetLocalChangeProcessor() must be called before any 106 // ProcessLocalChange(). 107 // 108 // TODO(kinuko): Remove this method once we stop using multiple backends 109 // (crbug.com/324215), or deprecate the other if we keep doing so. 110 void SetLocalChangeProcessorCallback( 111 const GetLocalChangeProcessorCallback& get_local_change_processor); 112 113 // Returns true via |callback| if the given file |url| has local pending 114 // changes. 115 void HasPendingLocalChanges( 116 const fileapi::FileSystemURL& url, 117 const HasPendingLocalChangeCallback& callback); 118 119 // Returns the metadata of a remote file pointed by |url|. 120 virtual void GetLocalFileMetadata( 121 const fileapi::FileSystemURL& url, 122 const SyncFileMetadataCallback& callback); 123 124 // RemoteChangeProcessor overrides. 125 virtual void PrepareForProcessRemoteChange( 126 const fileapi::FileSystemURL& url, 127 const PrepareChangeCallback& callback) OVERRIDE; 128 virtual void ApplyRemoteChange( 129 const FileChange& change, 130 const base::FilePath& local_path, 131 const fileapi::FileSystemURL& url, 132 const SyncStatusCallback& callback) OVERRIDE; 133 virtual void FinalizeRemoteSync( 134 const fileapi::FileSystemURL& url, 135 bool clear_local_changes, 136 const base::Closure& completion_callback) OVERRIDE; 137 virtual void RecordFakeLocalChange( 138 const fileapi::FileSystemURL& url, 139 const FileChange& change, 140 const SyncStatusCallback& callback) OVERRIDE; 141 142 // LocalOriginChangeObserver override. 143 virtual void OnChangesAvailableInOrigins( 144 const std::set<GURL>& origins) OVERRIDE; 145 146 // Called when a particular origin (app) is disabled/enabled while 147 // the service is running. This may be called for origins/apps that 148 // are not initialized for the service. 149 void SetOriginEnabled(const GURL& origin, bool enabled); 150 151 private: 152 friend class OriginChangeMapTest; 153 154 class OriginChangeMap { 155 public: 156 typedef std::map<GURL, int64> Map; 157 158 OriginChangeMap(); 159 ~OriginChangeMap(); 160 161 // Sets |origin| to the next origin to process. (For now we simply apply 162 // round-robin to pick the next origin to avoid starvation.) 163 // Returns false if no origins to process. 164 bool NextOriginToProcess(GURL* origin); 165 166 int64 GetTotalChangeCount() const; 167 168 // Update change_count_map_ for |origin|. 169 void SetOriginChangeCount(const GURL& origin, int64 changes); 170 171 void SetOriginEnabled(const GURL& origin, bool enabled); 172 173 private: 174 // Per-origin changes (cached info, could be stale). 175 Map change_count_map_; 176 Map::iterator next_; 177 178 // Holds a set of disabled (but initialized) origins. 179 std::set<GURL> disabled_origins_; 180 }; 181 182 void DidInitializeFileSystemContext( 183 const GURL& app_origin, 184 fileapi::FileSystemContext* file_system_context, 185 const SyncStatusCallback& callback, 186 SyncStatusCode status); 187 void DidInitializeForRemoteSync( 188 const fileapi::FileSystemURL& url, 189 fileapi::FileSystemContext* file_system_context, 190 const PrepareChangeCallback& callback, 191 SyncStatusCode status); 192 193 // Runs local_sync_callback_ and resets it. 194 void RunLocalSyncCallback( 195 SyncStatusCode status, 196 const fileapi::FileSystemURL& url); 197 198 // Callback for ApplyRemoteChange. 199 void DidApplyRemoteChange( 200 const SyncStatusCallback& callback, 201 SyncStatusCode status); 202 203 // Callbacks for ProcessLocalChange. 204 void DidGetFileForLocalSync( 205 SyncStatusCode status, 206 const LocalFileSyncInfo& sync_file_info, 207 webkit_blob::ScopedFile snapshot); 208 void ProcessNextChangeForURL( 209 webkit_blob::ScopedFile snapshot, 210 const LocalFileSyncInfo& sync_file_info, 211 const FileChange& last_change, 212 const FileChangeList& changes, 213 SyncStatusCode status); 214 215 // A thin wrapper of get_local_change_processor_. 216 LocalChangeProcessor* GetLocalChangeProcessor( 217 const fileapi::FileSystemURL& url); 218 219 Profile* profile_; 220 221 scoped_refptr<LocalFileSyncContext> sync_context_; 222 223 // Origin to context map. (Assuming that as far as we're in the same 224 // profile single origin wouldn't belong to multiple FileSystemContexts.) 225 std::map<GURL, fileapi::FileSystemContext*> origin_to_contexts_; 226 227 // Origins which have pending changes but have not been initialized yet. 228 // (Used only for handling dirty files left in the local tracker database 229 // after a restart.) 230 std::set<GURL> pending_origins_with_changes_; 231 232 OriginChangeMap origin_change_map_; 233 234 // This callback is non-null while a local sync is running (i.e. 235 // ProcessLocalChange has been called and has not been returned yet). 236 SyncFileCallback local_sync_callback_; 237 238 LocalChangeProcessor* local_change_processor_; 239 GetLocalChangeProcessorCallback get_local_change_processor_; 240 241 ObserverList<Observer> change_observers_; 242 243 DISALLOW_COPY_AND_ASSIGN(LocalFileSyncService); 244 }; 245 246 } // namespace sync_file_system 247 248 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_ 249