Home | History | Annotate | Download | only in drive_backend_v1
      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_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_
      6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_
      7 
      8 #include <deque>
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "base/callback.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "base/observer_list.h"
     18 #include "base/threading/non_thread_safe.h"
     19 #include "chrome/browser/drive/drive_notification_manager_factory.h"
     20 #include "chrome/browser/drive/drive_notification_observer.h"
     21 #include "chrome/browser/extensions/extension_system_factory.h"
     22 #include "chrome/browser/profiles/profile.h"
     23 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     24 #include "chrome/browser/sync_file_system/conflict_resolution_resolver.h"
     25 #include "chrome/browser/sync_file_system/drive_backend_v1/api_util_interface.h"
     26 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
     27 #include "chrome/browser/sync_file_system/drive_backend_v1/local_sync_operation_resolver.h"
     28 #include "chrome/browser/sync_file_system/drive_backend_v1/origin_operation_queue.h"
     29 #include "chrome/browser/sync_file_system/drive_backend_v1/remote_change_handler.h"
     30 #include "chrome/browser/sync_file_system/file_change.h"
     31 #include "chrome/browser/sync_file_system/local_change_processor.h"
     32 #include "chrome/browser/sync_file_system/remote_file_sync_service.h"
     33 #include "chrome/browser/sync_file_system/sync_action.h"
     34 #include "chrome/browser/sync_file_system/sync_callbacks.h"
     35 #include "chrome/browser/sync_file_system/sync_direction.h"
     36 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
     37 #include "chrome/browser/sync_file_system/sync_status_code.h"
     38 #include "chrome/browser/sync_file_system/sync_task_manager.h"
     39 
     40 class ExtensionService;
     41 
     42 namespace google_apis {
     43 class ResourceList;
     44 }
     45 
     46 namespace tracked_objects {
     47 class Location;
     48 }
     49 
     50 namespace sync_file_system {
     51 
     52 namespace drive_backend {
     53 class LocalSyncDelegate;
     54 class RemoteSyncDelegate;
     55 }
     56 
     57 class SyncTaskManager;
     58 
     59 // Maintains remote file changes.
     60 // Owned by SyncFileSystemService (which is a per-profile object).
     61 class DriveFileSyncService : public RemoteFileSyncService,
     62                              public LocalChangeProcessor,
     63                              public drive_backend::APIUtilObserver,
     64                              public SyncTaskManager::Client,
     65                              public base::NonThreadSafe,
     66                              public base::SupportsWeakPtr<DriveFileSyncService>,
     67                              public drive::DriveNotificationObserver {
     68  public:
     69   typedef base::Callback<void(const SyncStatusCallback& callback)> Task;
     70 
     71   static ConflictResolutionPolicy kDefaultPolicy;
     72 
     73   virtual ~DriveFileSyncService();
     74 
     75   // Creates DriveFileSyncService.
     76   static scoped_ptr<DriveFileSyncService> Create(Profile* profile);
     77   static void AppendDependsOnFactories(
     78       std::set<BrowserContextKeyedServiceFactory*>* factories);
     79 
     80   // Creates DriveFileSyncService instance for testing.
     81   // |metadata_store| must be initialized beforehand.
     82   static scoped_ptr<DriveFileSyncService> CreateForTesting(
     83       Profile* profile,
     84       const base::FilePath& base_dir,
     85       scoped_ptr<drive_backend::APIUtilInterface> api_util,
     86       scoped_ptr<DriveMetadataStore> metadata_store);
     87 
     88   // RemoteFileSyncService overrides.
     89   virtual void AddServiceObserver(Observer* observer) OVERRIDE;
     90   virtual void AddFileStatusObserver(FileStatusObserver* observer) OVERRIDE;
     91   virtual void RegisterOrigin(const GURL& origin,
     92                               const SyncStatusCallback& callback) OVERRIDE;
     93   virtual void EnableOrigin(const GURL& origin,
     94                             const SyncStatusCallback& callback) OVERRIDE;
     95   virtual void DisableOrigin(const GURL& origin,
     96                              const SyncStatusCallback& callback) OVERRIDE;
     97   virtual void UninstallOrigin(const GURL& origin,
     98                                UninstallFlag flag,
     99                                const SyncStatusCallback& callback) OVERRIDE;
    100   virtual void ProcessRemoteChange(const SyncFileCallback& callback) OVERRIDE;
    101   virtual void SetRemoteChangeProcessor(
    102       RemoteChangeProcessor* processor) OVERRIDE;
    103   virtual LocalChangeProcessor* GetLocalChangeProcessor() OVERRIDE;
    104   virtual bool IsConflicting(const fileapi::FileSystemURL& url) OVERRIDE;
    105   virtual RemoteServiceState GetCurrentState() const OVERRIDE;
    106   virtual void GetOriginStatusMap(OriginStatusMap* status_map) OVERRIDE;
    107   virtual scoped_ptr<base::ListValue> DumpFiles(const GURL& origin) OVERRIDE;
    108   virtual scoped_ptr<base::ListValue> DumpDatabase() OVERRIDE;
    109   virtual void SetSyncEnabled(bool enabled) OVERRIDE;
    110   virtual SyncStatusCode SetConflictResolutionPolicy(
    111       ConflictResolutionPolicy policy) OVERRIDE;
    112   virtual ConflictResolutionPolicy GetConflictResolutionPolicy() const OVERRIDE;
    113   virtual void GetRemoteVersions(
    114       const fileapi::FileSystemURL& url,
    115       const RemoteVersionsCallback& callback) OVERRIDE;
    116   virtual void DownloadRemoteVersion(
    117       const fileapi::FileSystemURL& url,
    118       const std::string& version_id,
    119       const DownloadVersionCallback& callback) OVERRIDE;
    120 
    121   // LocalChangeProcessor overrides.
    122   virtual void ApplyLocalChange(
    123       const FileChange& change,
    124       const base::FilePath& local_file_path,
    125       const SyncFileMetadata& local_file_metadata,
    126       const fileapi::FileSystemURL& url,
    127       const SyncStatusCallback& callback) OVERRIDE;
    128 
    129   // DriveFileSyncClientObserver overrides.
    130   virtual void OnAuthenticated() OVERRIDE;
    131   virtual void OnNetworkConnected() OVERRIDE;
    132 
    133   // drive::DriveNotificationObserver implementation.
    134   virtual void OnNotificationReceived() OVERRIDE;
    135   virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
    136 
    137   // SyncTaskManager::Client overrides.
    138   virtual void MaybeScheduleNextTask() OVERRIDE;
    139   virtual void NotifyLastOperationStatus(
    140       SyncStatusCode sync_status,
    141       bool used_network) OVERRIDE;
    142 
    143   static std::string PathToTitle(const base::FilePath& path);
    144   static base::FilePath TitleToPath(const std::string& title);
    145   static DriveMetadata::ResourceType SyncFileTypeToDriveMetadataResourceType(
    146       SyncFileType file_type);
    147   static SyncFileType DriveMetadataResourceTypeToSyncFileType(
    148       DriveMetadata::ResourceType resource_type);
    149 
    150  private:
    151   friend class SyncTaskManager;
    152   friend class drive_backend::LocalSyncDelegate;
    153   friend class drive_backend::RemoteSyncDelegate;
    154 
    155   friend class DriveFileSyncServiceFakeTest;
    156   friend class DriveFileSyncServiceSyncTest;
    157   friend class DriveFileSyncServiceTest;
    158   struct ApplyLocalChangeParam;
    159   struct ProcessRemoteChangeParam;
    160 
    161   typedef base::Callback<
    162       void(SyncStatusCode status,
    163            const std::string& resource_id)> ResourceIdCallback;
    164 
    165   explicit DriveFileSyncService(Profile* profile);
    166 
    167   void Initialize(scoped_ptr<SyncTaskManager> task_manager,
    168                   const SyncStatusCallback& callback);
    169   void InitializeForTesting(
    170       scoped_ptr<SyncTaskManager> task_manager,
    171       const base::FilePath& base_dir,
    172       scoped_ptr<drive_backend::APIUtilInterface> sync_client,
    173       scoped_ptr<DriveMetadataStore> metadata_store,
    174       const SyncStatusCallback& callback);
    175 
    176   void DidInitializeMetadataStore(const SyncStatusCallback& callback,
    177                                   SyncStatusCode status,
    178                                   bool created);
    179 
    180   void UpdateServiceStateFromLastOperationStatus(
    181       SyncStatusCode sync_status,
    182       google_apis::GDataErrorCode gdata_error);
    183 
    184   // Updates the service state. Also this may notify observers if the
    185   // service state has been changed from the original value.
    186   void UpdateServiceState(RemoteServiceState state,
    187                           const std::string& description);
    188 
    189   void DoRegisterOrigin(
    190       const GURL& origin,
    191       const SyncStatusCallback& callback);
    192   void DoEnableOrigin(
    193       const GURL& origin,
    194       const SyncStatusCallback& callback);
    195   void DoDisableOrigin(
    196       const GURL& origin,
    197       const SyncStatusCallback& callback);
    198   void DoUninstallOrigin(
    199       const GURL& origin,
    200       UninstallFlag flag,
    201       const SyncStatusCallback& callback);
    202   void DoProcessRemoteChange(
    203       const SyncFileCallback& sync_callback,
    204       const SyncStatusCallback& completion_callback);
    205   void DoApplyLocalChange(
    206       const FileChange& change,
    207       const base::FilePath& local_file_path,
    208       const SyncFileMetadata& local_file_metadata,
    209       const fileapi::FileSystemURL& url,
    210       const SyncStatusCallback& callback);
    211 
    212   void DoGetRemoteVersions(
    213       const fileapi::FileSystemURL& url,
    214       const RemoteVersionsCallback& callback,
    215       const SyncStatusCallback& completion_callback);
    216   void DidGetEntryForRemoteVersions(
    217       const RemoteVersionsCallback& callback,
    218       google_apis::GDataErrorCode error,
    219       scoped_ptr<google_apis::ResourceEntry> entry);
    220 
    221   void DoDownloadRemoteVersion(
    222       const fileapi::FileSystemURL& url,
    223       const std::string& version_id,
    224       const DownloadVersionCallback& callback,
    225       const SyncStatusCallback& completion_callback);
    226   void DidDownloadVersion(
    227       const DownloadVersionCallback& download_callback,
    228       google_apis::GDataErrorCode error,
    229       const std::string& file_md5,
    230       int64 file_size,
    231       const base::Time& last_updated,
    232       webkit_blob::ScopedFile downloaded);
    233 
    234   void UpdateRegisteredOrigins();
    235 
    236   void StartBatchSync(const SyncStatusCallback& callback);
    237   void DidGetDriveDirectoryForOrigin(const GURL& origin,
    238                                      const SyncStatusCallback& callback,
    239                                      SyncStatusCode status,
    240                                      const std::string& resource_id);
    241   void DidUninstallOrigin(const GURL& origin,
    242                           const SyncStatusCallback& callback,
    243                           google_apis::GDataErrorCode error);
    244   void DidGetLargestChangeStampForBatchSync(
    245       const SyncStatusCallback& callback,
    246       const GURL& origin,
    247       const std::string& resource_id,
    248       google_apis::GDataErrorCode error,
    249       int64 largest_changestamp);
    250   void DidGetDirectoryContentForBatchSync(
    251       const SyncStatusCallback& callback,
    252       const GURL& origin,
    253       const std::string& resource_id,
    254       int64 largest_changestamp,
    255       google_apis::GDataErrorCode error,
    256       scoped_ptr<google_apis::ResourceList> feed);
    257 
    258   void DidProcessRemoteChange(const SyncFileCallback& sync_callback,
    259                               const SyncStatusCallback& completion_callback,
    260                               SyncStatusCode status);
    261   void DidApplyLocalChange(const SyncStatusCallback& callback,
    262                            SyncStatusCode status);
    263 
    264   // Returns true if |pending_changes_| was updated.
    265   bool AppendRemoteChange(
    266       const GURL& origin,
    267       const google_apis::ResourceEntry& entry,
    268       int64 changestamp);
    269   bool AppendFetchChange(
    270       const GURL& origin,
    271       const base::FilePath& path,
    272       const std::string& resource_id,
    273       SyncFileType file_type);
    274   bool AppendRemoteChangeInternal(
    275       const GURL& origin,
    276       const base::FilePath& path,
    277       bool is_deleted,
    278       const std::string& resource_id,
    279       int64 changestamp,
    280       const std::string& remote_file_md5,
    281       const base::Time& updated_time,
    282       SyncFileType file_type);
    283   void RemoveRemoteChange(const fileapi::FileSystemURL& url);
    284 
    285   // TODO(kinuko,tzik): Move this out of DriveFileSyncService.
    286   void MarkConflict(
    287       const fileapi::FileSystemURL& url,
    288       DriveMetadata* drive_metadata,
    289       const SyncStatusCallback& callback);
    290   void NotifyConflict(
    291       const fileapi::FileSystemURL& url,
    292       const SyncStatusCallback& callback,
    293       SyncStatusCode status);
    294 
    295   // A wrapper implementation to GDataErrorCodeToSyncStatusCode which returns
    296   // authentication error if the user is not signed in.
    297   SyncStatusCode GDataErrorCodeToSyncStatusCodeWrapper(
    298       google_apis::GDataErrorCode error);
    299 
    300   base::FilePath temporary_file_dir_;
    301 
    302   // May start batch sync or incremental sync.
    303   // This posts either one of following tasks:
    304   // - StartBatchSyncForOrigin() if it has any pending batch sync origins, or
    305   // - FetchChangesForIncrementalSync() otherwise.
    306   //
    307   // These two methods are called only from this method.
    308   void MaybeStartFetchChanges();
    309 
    310   void FetchChangesForIncrementalSync(const SyncStatusCallback& callback);
    311   void DidFetchChangesForIncrementalSync(
    312       const SyncStatusCallback& callback,
    313       bool has_new_changes,
    314       google_apis::GDataErrorCode error,
    315       scoped_ptr<google_apis::ResourceList> changes);
    316   bool GetOriginForEntry(const google_apis::ResourceEntry& entry, GURL* origin);
    317   void NotifyObserversFileStatusChanged(const fileapi::FileSystemURL& url,
    318                                         SyncFileStatus sync_status,
    319                                         SyncAction action_taken,
    320                                         SyncDirection direction);
    321 
    322   void EnsureSyncRootDirectory(const ResourceIdCallback& callback);
    323   void DidEnsureSyncRoot(const ResourceIdCallback& callback,
    324                          google_apis::GDataErrorCode error,
    325                          const std::string& sync_root_resource_id);
    326   void EnsureOriginRootDirectory(const GURL& origin,
    327                                  const ResourceIdCallback& callback);
    328   void DidEnsureSyncRootForOriginRoot(const GURL& origin,
    329                                       const ResourceIdCallback& callback,
    330                                       SyncStatusCode status,
    331                                       const std::string& sync_root_resource_id);
    332   void DidEnsureOriginRoot(const GURL& origin,
    333                            const ResourceIdCallback& callback,
    334                            google_apis::GDataErrorCode error,
    335                            const std::string& resource_id);
    336 
    337   // This function returns Resouce ID for the sync root directory if available.
    338   // Returns an empty string 1) when the resource ID has not been initialized
    339   // yet, and 2) after the service has detected the remote sync root folder was
    340   // removed.
    341   std::string sync_root_resource_id();
    342 
    343   scoped_ptr<DriveMetadataStore> metadata_store_;
    344   scoped_ptr<drive_backend::APIUtilInterface> api_util_;
    345 
    346   Profile* profile_;
    347 
    348   scoped_ptr<SyncTaskManager> task_manager_;
    349 
    350   scoped_ptr<drive_backend::LocalSyncDelegate> running_local_sync_task_;
    351   scoped_ptr<drive_backend::RemoteSyncDelegate> running_remote_sync_task_;
    352 
    353   // The current remote service state. This does NOT reflect the
    354   // sync_enabled_ flag, while GetCurrentState() DOES reflect the flag
    355   // value (i.e. it returns REMOTE_SERVICE_DISABLED when sync_enabled_
    356   // is false even if state_ is REMOTE_SERVICE_OK).
    357   RemoteServiceState state_;
    358 
    359   // Indicates if sync is enabled or not. This flag can be turned on or
    360   // off by SetSyncEnabled() method.  To start synchronization
    361   // this needs to be true and state_ needs to be REMOTE_SERVICE_OK.
    362   bool sync_enabled_;
    363 
    364   int64 largest_fetched_changestamp_;
    365 
    366   std::map<GURL, std::string> pending_batch_sync_origins_;
    367 
    368   // Is set to true when there's a fair possibility that we have some
    369   // remote changes that haven't been fetched yet.
    370   //
    371   // This flag is set when:
    372   // - This gets invalidation notification,
    373   // - The service is authenticated or becomes online, and
    374   // - The polling timer is fired.
    375   //
    376   // This flag is cleared when:
    377   // - A batch or incremental sync has been started, and
    378   // - When all pending batch sync tasks have been finished.
    379   bool may_have_unfetched_changes_;
    380 
    381   ObserverList<Observer> service_observers_;
    382   ObserverList<FileStatusObserver> file_status_observers_;
    383 
    384   RemoteChangeHandler remote_change_handler_;
    385   RemoteChangeProcessor* remote_change_processor_;
    386 
    387   google_apis::GDataErrorCode last_gdata_error_;
    388 
    389   ConflictResolutionResolver conflict_resolution_resolver_;
    390 
    391   OriginOperationQueue pending_origin_operations_;
    392 
    393   DISALLOW_COPY_AND_ASSIGN(DriveFileSyncService);
    394 };
    395 
    396 }  // namespace sync_file_system
    397 
    398 #endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_
    399