#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_
#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_
#include <deque>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/threading/non_thread_safe.h"
#include "chrome/browser/drive/drive_notification_manager_factory.h"
#include "chrome/browser/drive/drive_notification_observer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/sync_file_system/conflict_resolution_resolver.h"
#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
#include "chrome/browser/sync_file_system/drive_backend_v1/api_util_interface.h"
#include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
#include "chrome/browser/sync_file_system/drive_backend_v1/local_sync_operation_resolver.h"
#include "chrome/browser/sync_file_system/drive_backend_v1/origin_operation_queue.h"
#include "chrome/browser/sync_file_system/drive_backend_v1/remote_change_handler.h"
#include "chrome/browser/sync_file_system/file_change.h"
#include "chrome/browser/sync_file_system/local_change_processor.h"
#include "chrome/browser/sync_file_system/remote_file_sync_service.h"
#include "chrome/browser/sync_file_system/sync_action.h"
#include "chrome/browser/sync_file_system/sync_callbacks.h"
#include "chrome/browser/sync_file_system/sync_direction.h"
#include "chrome/browser/sync_file_system/sync_file_system.pb.h"
#include "chrome/browser/sync_file_system/sync_status_code.h"
class ExtensionService;
namespace google_apis {
class ResourceList;
}
namespace tracked_objects {
class Location;
}
namespace sync_file_system {
namespace drive_backend {
class LocalSyncDelegate;
class RemoteSyncDelegate;
class SyncTaskManager;
}
class DriveFileSyncService : public RemoteFileSyncService,
public LocalChangeProcessor,
public drive_backend::APIUtilObserver,
public drive_backend::SyncTaskManager::Client,
public base::NonThreadSafe,
public base::SupportsWeakPtr<DriveFileSyncService>,
public drive::DriveNotificationObserver {
public:
typedef base::Callback<void(const SyncStatusCallback& callback)> Task;
static ConflictResolutionPolicy kDefaultPolicy;
virtual ~DriveFileSyncService();
static scoped_ptr<DriveFileSyncService> Create(Profile* profile);
static void AppendDependsOnFactories(
std::set<BrowserContextKeyedServiceFactory*>* factories);
static scoped_ptr<DriveFileSyncService> CreateForTesting(
Profile* profile,
const base::FilePath& base_dir,
scoped_ptr<drive_backend::APIUtilInterface> api_util,
scoped_ptr<DriveMetadataStore> metadata_store);
virtual void AddServiceObserver(Observer* observer) OVERRIDE;
virtual void AddFileStatusObserver(FileStatusObserver* observer) OVERRIDE;
virtual void RegisterOrigin(const GURL& origin,
const SyncStatusCallback& callback) OVERRIDE;
virtual void EnableOrigin(const GURL& origin,
const SyncStatusCallback& callback) OVERRIDE;
virtual void DisableOrigin(const GURL& origin,
const SyncStatusCallback& callback) OVERRIDE;
virtual void UninstallOrigin(const GURL& origin,
UninstallFlag flag,
const SyncStatusCallback& callback) OVERRIDE;
virtual void ProcessRemoteChange(const SyncFileCallback& callback) OVERRIDE;
virtual void SetRemoteChangeProcessor(
RemoteChangeProcessor* processor) OVERRIDE;
virtual LocalChangeProcessor* GetLocalChangeProcessor() OVERRIDE;
virtual bool IsConflicting(const fileapi::FileSystemURL& url) OVERRIDE;
virtual RemoteServiceState GetCurrentState() const OVERRIDE;
virtual void GetOriginStatusMap(OriginStatusMap* status_map) OVERRIDE;
virtual scoped_ptr<base::ListValue> DumpFiles(const GURL& origin) OVERRIDE;
virtual scoped_ptr<base::ListValue> DumpDatabase() OVERRIDE;
virtual void SetSyncEnabled(bool enabled) OVERRIDE;
virtual SyncStatusCode SetDefaultConflictResolutionPolicy(
ConflictResolutionPolicy policy) OVERRIDE;
virtual SyncStatusCode SetConflictResolutionPolicy(
const GURL& origin,
ConflictResolutionPolicy policy) OVERRIDE;
virtual ConflictResolutionPolicy GetDefaultConflictResolutionPolicy() const
OVERRIDE;
virtual ConflictResolutionPolicy GetConflictResolutionPolicy(
const GURL& origin) const OVERRIDE;
virtual void GetRemoteVersions(const fileapi::FileSystemURL& url,
const RemoteVersionsCallback& callback)
OVERRIDE;
virtual void DownloadRemoteVersion(
const fileapi::FileSystemURL& url,
const std::string& version_id,
const DownloadVersionCallback& callback) OVERRIDE;
virtual void PromoteDemotedChanges() OVERRIDE;
virtual void ApplyLocalChange(
const FileChange& change,
const base::FilePath& local_file_path,
const SyncFileMetadata& local_file_metadata,
const fileapi::FileSystemURL& url,
const SyncStatusCallback& callback) OVERRIDE;
virtual void OnAuthenticated() OVERRIDE;
virtual void OnNetworkConnected() OVERRIDE;
virtual void OnNotificationReceived() OVERRIDE;
virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
virtual void MaybeScheduleNextTask() OVERRIDE;
virtual void NotifyLastOperationStatus(
SyncStatusCode sync_status,
bool used_network) OVERRIDE;
static std::string PathToTitle(const base::FilePath& path);
static base::FilePath TitleToPath(const std::string& title);
static DriveMetadata::ResourceType SyncFileTypeToDriveMetadataResourceType(
SyncFileType file_type);
static SyncFileType DriveMetadataResourceTypeToSyncFileType(
DriveMetadata::ResourceType resource_type);
private:
friend class SyncTaskManager;
friend class drive_backend::LocalSyncDelegate;
friend class drive_backend::RemoteSyncDelegate;
friend class DriveFileSyncServiceFakeTest;
friend class DriveFileSyncServiceSyncTest;
friend class DriveFileSyncServiceTest;
struct ApplyLocalChangeParam;
struct ProcessRemoteChangeParam;
typedef base::Callback<
void(SyncStatusCode status,
const std::string& resource_id)> ResourceIdCallback;
explicit DriveFileSyncService(Profile* profile);
void Initialize(scoped_ptr<drive_backend::SyncTaskManager> task_manager,
const SyncStatusCallback& callback);
void InitializeForTesting(
scoped_ptr<drive_backend::SyncTaskManager> task_manager,
const base::FilePath& base_dir,
scoped_ptr<drive_backend::APIUtilInterface> sync_client,
scoped_ptr<DriveMetadataStore> metadata_store,
const SyncStatusCallback& callback);
void DidInitializeMetadataStore(const SyncStatusCallback& callback,
SyncStatusCode status,
bool created);
void UpdateServiceStateFromLastOperationStatus(
SyncStatusCode sync_status,
google_apis::GDataErrorCode gdata_error);
void UpdateServiceState(RemoteServiceState state,
const std::string& description);
void DoRegisterOrigin(
const GURL& origin,
const SyncStatusCallback& callback);
void DoEnableOrigin(
const GURL& origin,
const SyncStatusCallback& callback);
void DoDisableOrigin(
const GURL& origin,
const SyncStatusCallback& callback);
void DoUninstallOrigin(
const GURL& origin,
UninstallFlag flag,
const SyncStatusCallback& callback);
void DoProcessRemoteChange(
const SyncFileCallback& sync_callback,
const SyncStatusCallback& completion_callback);
void DoApplyLocalChange(
const FileChange& change,
const base::FilePath& local_file_path,
const SyncFileMetadata& local_file_metadata,
const fileapi::FileSystemURL& url,
const SyncStatusCallback& callback);
void DoGetRemoteVersions(
const fileapi::FileSystemURL& url,
const RemoteVersionsCallback& callback,
const SyncStatusCallback& completion_callback);
void DidGetEntryForRemoteVersions(
const RemoteVersionsCallback& callback,
google_apis::GDataErrorCode error,
scoped_ptr<google_apis::ResourceEntry> entry);
void DoDownloadRemoteVersion(
const fileapi::FileSystemURL& url,
const std::string& version_id,
const DownloadVersionCallback& callback,
const SyncStatusCallback& completion_callback);
void DidDownloadVersion(
const DownloadVersionCallback& download_callback,
google_apis::GDataErrorCode error,
const std::string& file_md5,
int64 file_size,
const base::Time& last_updated,
webkit_blob::ScopedFile downloaded);
void UpdateRegisteredOrigins();
void StartBatchSync(const SyncStatusCallback& callback);
void DidGetDriveDirectoryForOrigin(const GURL& origin,
const SyncStatusCallback& callback,
SyncStatusCode status,
const std::string& resource_id);
void DidUninstallOrigin(const GURL& origin,
const SyncStatusCallback& callback,
google_apis::GDataErrorCode error);
void DidGetLargestChangeStampForBatchSync(
const SyncStatusCallback& callback,
const GURL& origin,
const std::string& resource_id,
google_apis::GDataErrorCode error,
int64 largest_changestamp);
void DidGetDirectoryContentForBatchSync(
const SyncStatusCallback& callback,
const GURL& origin,
const std::string& resource_id,
int64 largest_changestamp,
google_apis::GDataErrorCode error,
scoped_ptr<google_apis::ResourceList> feed);
void DidProcessRemoteChange(const SyncFileCallback& sync_callback,
const SyncStatusCallback& completion_callback,
SyncStatusCode status);
void DidApplyLocalChange(const SyncStatusCallback& callback,
SyncStatusCode status);
bool AppendRemoteChange(
const GURL& origin,
const google_apis::ResourceEntry& entry,
int64 changestamp);
bool AppendFetchChange(
const GURL& origin,
const base::FilePath& path,
const std::string& resource_id,
SyncFileType file_type);
bool AppendRemoteChangeInternal(
const GURL& origin,
const base::FilePath& path,
bool is_deleted,
const std::string& resource_id,
int64 changestamp,
const std::string& remote_file_md5,
const base::Time& updated_time,
SyncFileType file_type);
void RemoveRemoteChange(const fileapi::FileSystemURL& url);
void MarkConflict(
const fileapi::FileSystemURL& url,
DriveMetadata* drive_metadata,
const SyncStatusCallback& callback);
void NotifyConflict(
const fileapi::FileSystemURL& url,
const SyncStatusCallback& callback,
SyncStatusCode status);
SyncStatusCode GDataErrorCodeToSyncStatusCodeWrapper(
google_apis::GDataErrorCode error);
base::FilePath temporary_file_dir_;
void MaybeStartFetchChanges();
void FetchChangesForIncrementalSync(const SyncStatusCallback& callback);
void DidFetchChangesForIncrementalSync(
const SyncStatusCallback& callback,
bool has_new_changes,
google_apis::GDataErrorCode error,
scoped_ptr<google_apis::ResourceList> changes);
bool GetOriginForEntry(const google_apis::ResourceEntry& entry, GURL* origin);
void NotifyObserversFileStatusChanged(const fileapi::FileSystemURL& url,
SyncFileStatus sync_status,
SyncAction action_taken,
SyncDirection direction);
void EnsureSyncRootDirectory(const ResourceIdCallback& callback);
void DidEnsureSyncRoot(const ResourceIdCallback& callback,
google_apis::GDataErrorCode error,
const std::string& sync_root_resource_id);
void EnsureOriginRootDirectory(const GURL& origin,
const ResourceIdCallback& callback);
void DidEnsureSyncRootForOriginRoot(const GURL& origin,
const ResourceIdCallback& callback,
SyncStatusCode status,
const std::string& sync_root_resource_id);
void DidEnsureOriginRoot(const GURL& origin,
const ResourceIdCallback& callback,
google_apis::GDataErrorCode error,
const std::string& resource_id);
std::string sync_root_resource_id();
scoped_ptr<DriveMetadataStore> metadata_store_;
scoped_ptr<drive_backend::APIUtilInterface> api_util_;
Profile* profile_;
scoped_ptr<drive_backend::SyncTaskManager> task_manager_;
scoped_ptr<drive_backend::LocalSyncDelegate> running_local_sync_task_;
scoped_ptr<drive_backend::RemoteSyncDelegate> running_remote_sync_task_;
RemoteServiceState state_;
bool sync_enabled_;
int64 largest_fetched_changestamp_;
std::map<GURL, std::string> pending_batch_sync_origins_;
bool may_have_unfetched_changes_;
ObserverList<Observer> service_observers_;
ObserverList<FileStatusObserver> file_status_observers_;
RemoteChangeHandler remote_change_handler_;
RemoteChangeProcessor* remote_change_processor_;
google_apis::GDataErrorCode last_gdata_error_;
ConflictResolutionResolver conflict_resolution_resolver_;
OriginOperationQueue pending_origin_operations_;
DISALLOW_COPY_AND_ASSIGN(DriveFileSyncService);
};
}
#endif