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