190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend_v1/local_sync_delegate.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h"
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/callback.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/sync_file_system/conflict_resolution_resolver.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend_v1/api_util.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/sync_file_system/logger.h"
132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace sync_file_system {
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive_backend {
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochLocalSyncDelegate::LocalSyncDelegate(
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DriveFileSyncService* sync_service,
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const FileChange& local_change,
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::FilePath& local_path,
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncFileMetadata& local_metadata,
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const fileapi::FileSystemURL& url)
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : sync_service_(sync_service),
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      operation_(SYNC_OPERATION_NONE),
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url_(url),
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      local_change_(local_change),
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      local_path_(local_path),
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      local_metadata_(local_metadata),
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      has_drive_metadata_(false),
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      has_remote_change_(false),
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      weak_factory_(this) {}
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochLocalSyncDelegate::~LocalSyncDelegate() {}
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::Run(const SyncStatusCallback& callback) {
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(nhiroki): support directory operations (http://crbug.com/161442).
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(IsSyncFSDirectoryOperationEnabled() || !local_change_.IsDirectory());
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  operation_ = SYNC_OPERATION_NONE;
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  has_drive_metadata_ =
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      metadata_store()->ReadEntry(url_, &drive_metadata_) == SYNC_STATUS_OK;
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!has_drive_metadata_)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    drive_metadata_.set_md5_checksum(std::string());
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  sync_service_->EnsureOriginRootDirectory(
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url_.origin(),
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&LocalSyncDelegate::DidGetOriginRoot,
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr(),
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 callback));
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidGetOriginRoot(
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SyncStatusCode status,
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& origin_resource_id) {
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (status != SYNC_STATUS_OK) {
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(status);
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  origin_resource_id_ = origin_resource_id;
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  has_remote_change_ =
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      remote_change_handler()->GetChangeForURL(url_, &remote_change_);
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (has_remote_change_ && drive_metadata_.resource_id().empty())
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    drive_metadata_.set_resource_id(remote_change_.resource_id);
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SyncFileType remote_file_type =
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      has_remote_change_ ? remote_change_.change.file_type() :
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      has_drive_metadata_ ?
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          DriveFileSyncService::DriveMetadataResourceTypeToSyncFileType(
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              drive_metadata_.type())
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : SYNC_FILE_TYPE_UNKNOWN;
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_EQ(SYNC_OPERATION_NONE, operation_);
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  operation_ = LocalSyncOperationResolver::Resolve(
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      local_change_,
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      has_remote_change_ ? &remote_change_.change : NULL,
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      has_drive_metadata_ ? &drive_metadata_ : NULL);
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  util::Log(logging::LOG_VERBOSE, FROM_HERE,
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            "ApplyLocalChange for %s local_change:%s ===> %s",
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            url_.DebugString().c_str(),
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            local_change_.DebugString().c_str(),
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            SyncOperationTypeToString(operation_));
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  switch (operation_) {
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_ADD_FILE:
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      UploadNewFile(callback);
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_ADD_DIRECTORY:
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateDirectory(callback);
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_UPDATE_FILE:
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      UploadExistingFile(callback);
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_DELETE:
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Delete(callback);
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_NONE:
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback.Run(SYNC_STATUS_OK);
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_CONFLICT:
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      HandleConflict(callback);
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_RESOLVE_TO_LOCAL:
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ResolveToLocal(callback);
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_RESOLVE_TO_REMOTE:
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ResolveToRemote(callback, remote_file_type);
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_DELETE_METADATA:
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      DeleteMetadata(base::Bind(
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &LocalSyncDelegate::DidApplyLocalChange,
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          weak_factory_.GetWeakPtr(), callback, google_apis::HTTP_SUCCESS));
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_OPERATION_FAIL: {
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback.Run(SYNC_STATUS_FAILED);
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NOTREACHED();
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  callback.Run(SYNC_STATUS_FAILED);
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::UploadNewFile(const SyncStatusCallback& callback) {
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  api_util()->UploadNewFile(
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      origin_resource_id_,
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      local_path_,
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      DriveFileSyncService::PathToTitle(url_.path()),
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&LocalSyncDelegate::DidUploadNewFile,
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr(), callback));
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidUploadNewFile(
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    google_apis::GDataErrorCode error,
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& md5) {
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (error) {
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case google_apis::HTTP_CREATED:
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      UpdateMetadata(
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          resource_id, md5, DriveMetadata::RESOURCE_TYPE_FILE,
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&LocalSyncDelegate::DidApplyLocalChange,
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     weak_factory_.GetWeakPtr(), callback, error));
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sync_service_->NotifyObserversFileStatusChanged(
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_,
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_FILE_STATUS_SYNCED,
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_ACTION_ADDED,
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_DIRECTION_LOCAL_TO_REMOTE);
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case google_apis::HTTP_CONFLICT:
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      HandleCreationConflict(resource_id, DriveMetadata::RESOURCE_TYPE_FILE,
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             callback);
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default:
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error));
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::CreateDirectory(const SyncStatusCallback& callback) {
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(IsSyncFSDirectoryOperationEnabled());
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  api_util()->CreateDirectory(
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      origin_resource_id_,
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      DriveFileSyncService::PathToTitle(url_.path()),
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&LocalSyncDelegate::DidCreateDirectory,
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr(), callback));
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidCreateDirectory(
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    google_apis::GDataErrorCode error,
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id) {
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (error) {
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case google_apis::HTTP_SUCCESS:
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case google_apis::HTTP_CREATED: {
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      UpdateMetadata(
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          resource_id, std::string(), DriveMetadata::RESOURCE_TYPE_FOLDER,
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&LocalSyncDelegate::DidApplyLocalChange,
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     weak_factory_.GetWeakPtr(), callback, error));
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sync_service_->NotifyObserversFileStatusChanged(
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_,
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_FILE_STATUS_SYNCED,
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_ACTION_ADDED,
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_DIRECTION_LOCAL_TO_REMOTE);
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case google_apis::HTTP_CONFLICT:
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // There were conflicts and a file was left.
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // TODO(kinuko): Handle the latter case (http://crbug.com/237090).
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // Fall-through
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default:
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error));
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::UploadExistingFile(const SyncStatusCallback& callback) {
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(has_drive_metadata_);
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (drive_metadata_.resource_id().empty()) {
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UploadNewFile(callback);
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  api_util()->UploadExistingFile(
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      drive_metadata_.resource_id(),
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      drive_metadata_.md5_checksum(),
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      local_path_,
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&LocalSyncDelegate::DidUploadExistingFile,
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr(), callback));
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidUploadExistingFile(
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    google_apis::GDataErrorCode error,
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& md5) {
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(has_drive_metadata_);
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (error) {
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case google_apis::HTTP_SUCCESS:
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      UpdateMetadata(
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          resource_id, md5, DriveMetadata::RESOURCE_TYPE_FILE,
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&LocalSyncDelegate::DidApplyLocalChange,
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     weak_factory_.GetWeakPtr(), callback, error));
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sync_service_->NotifyObserversFileStatusChanged(
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_,
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_FILE_STATUS_SYNCED,
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_ACTION_UPDATED,
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_DIRECTION_LOCAL_TO_REMOTE);
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case google_apis::HTTP_CONFLICT:
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      HandleConflict(callback);
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case google_apis::HTTP_NOT_MODIFIED:
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      DidApplyLocalChange(callback,
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          google_apis::HTTP_SUCCESS, SYNC_STATUS_OK);
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case google_apis::HTTP_NOT_FOUND:
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      UploadNewFile(callback);
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default: {
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const SyncStatusCode status =
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          GDataErrorCodeToSyncStatusCodeWrapper(error);
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      DCHECK_NE(SYNC_STATUS_OK, status);
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback.Run(status);
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::Delete(const SyncStatusCallback& callback) {
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!has_drive_metadata_) {
2565e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    callback.Run(SYNC_STATUS_OK);
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (drive_metadata_.resource_id().empty()) {
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DidDelete(callback, google_apis::HTTP_NOT_FOUND);
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  api_util()->DeleteFile(
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      drive_metadata_.resource_id(),
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      drive_metadata_.md5_checksum(),
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&LocalSyncDelegate::DidDelete,
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr(), callback));
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidDelete(
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    google_apis::GDataErrorCode error) {
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(has_drive_metadata_);
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (error) {
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case google_apis::HTTP_SUCCESS:
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case google_apis::HTTP_NOT_FOUND:
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      DeleteMetadata(base::Bind(
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &LocalSyncDelegate::DidApplyLocalChange,
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          weak_factory_.GetWeakPtr(), callback, google_apis::HTTP_SUCCESS));
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sync_service_->NotifyObserversFileStatusChanged(
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_,
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_FILE_STATUS_SYNCED,
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_ACTION_DELETED,
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SYNC_DIRECTION_LOCAL_TO_REMOTE);
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case google_apis::HTTP_PRECONDITION:
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case google_apis::HTTP_CONFLICT:
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Delete |drive_metadata| on the conflict case.
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Conflicted remote change should be applied as a future remote change.
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DeleteMetadata(base::Bind(
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &LocalSyncDelegate::DidDeleteMetadataForDeletionConflict,
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          weak_factory_.GetWeakPtr(), callback));
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      sync_service_->NotifyObserversFileStatusChanged(
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          url_,
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          SYNC_FILE_STATUS_SYNCED,
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          SYNC_ACTION_DELETED,
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          SYNC_DIRECTION_LOCAL_TO_REMOTE);
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default: {
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const SyncStatusCode status =
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          GDataErrorCodeToSyncStatusCodeWrapper(error);
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      DCHECK_NE(SYNC_STATUS_OK, status);
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback.Run(status);
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidDeleteMetadataForDeletionConflict(
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const SyncStatusCallback& callback,
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SyncStatusCode status) {
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  callback.Run(SYNC_STATUS_OK);
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::ResolveToLocal(const SyncStatusCallback& callback) {
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (drive_metadata_.resource_id().empty()) {
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DidDeleteFileToResolveToLocal(callback, google_apis::HTTP_NOT_FOUND);
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  api_util()->DeleteFile(
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      drive_metadata_.resource_id(),
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      drive_metadata_.md5_checksum(),
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &LocalSyncDelegate::DidDeleteFileToResolveToLocal,
32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          weak_factory_.GetWeakPtr(), callback));
33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidDeleteFileToResolveToLocal(
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    google_apis::GDataErrorCode error) {
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (error != google_apis::HTTP_SUCCESS &&
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error != google_apis::HTTP_NOT_FOUND) {
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error));
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_NE(SYNC_FILE_TYPE_UNKNOWN, local_metadata_.file_type);
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (local_metadata_.file_type == SYNC_FILE_TYPE_FILE) {
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UploadNewFile(callback);
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(IsSyncFSDirectoryOperationEnabled());
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(SYNC_FILE_TYPE_DIRECTORY, local_metadata_.file_type);
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CreateDirectory(callback);
35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::ResolveToRemote(
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const SyncStatusCallback& callback,
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SyncFileType remote_file_type) {
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Mark the file as to-be-fetched.
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!drive_metadata_.resource_id().empty());
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SetMetadataToBeFetched(
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DriveFileSyncService::SyncFileTypeToDriveMetadataResourceType(
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          remote_file_type),
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&LocalSyncDelegate::DidResolveToRemote,
36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr(), callback));
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The synced notification will be dispatched when the remote file is
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // downloaded.
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidResolveToRemote(
36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SyncStatusCode status) {
37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(has_drive_metadata_);
37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (status != SYNC_STATUS_OK) {
37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(status);
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SyncFileType file_type = SYNC_FILE_TYPE_FILE;
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (drive_metadata_.type() == DriveMetadata::RESOURCE_TYPE_FOLDER)
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    file_type = SYNC_FILE_TYPE_DIRECTORY;
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  sync_service_->AppendFetchChange(
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url_.origin(), url_.path(), drive_metadata_.resource_id(), file_type);
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  callback.Run(status);
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidApplyLocalChange(
38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const google_apis::GDataErrorCode error,
38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SyncStatusCode status) {
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if ((operation_ == SYNC_OPERATION_DELETE ||
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       operation_ == SYNC_OPERATION_DELETE_METADATA) &&
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      (status == SYNC_FILE_ERROR_NOT_FOUND ||
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       status == SYNC_DATABASE_ERROR_NOT_FOUND)) {
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    status = SYNC_STATUS_OK;
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (status == SYNC_STATUS_OK) {
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    remote_change_handler()->RemoveChangeForURL(url_);
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    status = GDataErrorCodeToSyncStatusCodeWrapper(error);
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  callback.Run(status);
40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::UpdateMetadata(
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& md5,
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DriveMetadata::ResourceType type,
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback) {
4075e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  has_drive_metadata_ = true;
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_resource_id(resource_id);
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_md5_checksum(md5);
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_conflicted(false);
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_to_be_fetched(false);
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_type(type);
41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  metadata_store()->UpdateEntry(url_, drive_metadata_, callback);
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void LocalSyncDelegate::ResetMetadataForStartOver(
417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const SyncStatusCallback& callback) {
4185e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  has_drive_metadata_ = true;
419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!drive_metadata_.resource_id().empty());
42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_md5_checksum(std::string());
421424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  drive_metadata_.set_conflicted(false);
422424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  drive_metadata_.set_to_be_fetched(false);
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  metadata_store()->UpdateEntry(url_, drive_metadata_, callback);
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::SetMetadataToBeFetched(
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DriveMetadata::ResourceType type,
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback) {
4295e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  has_drive_metadata_ = true;
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_md5_checksum(std::string());
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_conflicted(false);
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_to_be_fetched(true);
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_type(type);
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  metadata_store()->UpdateEntry(url_, drive_metadata_, callback);
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DeleteMetadata(const SyncStatusCallback& callback) {
43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  metadata_store()->DeleteEntry(url_, callback);
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::HandleCreationConflict(
44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DriveMetadata::ResourceType type,
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback) {
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // File-file conflict is found.
44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Populates a fake drive_metadata and set has_drive_metadata = true.
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // In HandleConflictLocalSync:
44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // - If conflict_resolution is manual, we'll change conflicted to true
44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //   and save the metadata.
45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // - Otherwise we'll save the metadata with empty md5 and will start
45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //   over local sync as UploadExistingFile.
45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_resource_id(resource_id);
45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_md5_checksum(std::string());
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_conflicted(false);
45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_to_be_fetched(false);
45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  drive_metadata_.set_type(type);
45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  has_drive_metadata_ = true;
45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HandleConflict(callback);
45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::HandleConflict(const SyncStatusCallback& callback) {
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!drive_metadata_.resource_id().empty());
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  api_util()->GetResourceEntry(
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      drive_metadata_.resource_id(),
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(
466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &LocalSyncDelegate::DidGetEntryForConflictResolution,
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          weak_factory_.GetWeakPtr(), callback));
46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::DidGetEntryForConflictResolution(
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback,
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    google_apis::GDataErrorCode error,
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<google_apis::ResourceEntry> entry) {
474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SyncFileType remote_file_type = SYNC_FILE_TYPE_UNKNOWN;
475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ConflictResolution resolution = CONFLICT_RESOLUTION_UNKNOWN;
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (error != google_apis::HTTP_SUCCESS ||
478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      entry->updated_time().is_null()) {
479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    resolution = CONFLICT_RESOLUTION_LOCAL_WIN;
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SyncFileType local_file_type = local_metadata_.file_type;
482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::Time local_modification_time = local_metadata_.last_modified;
483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::Time remote_modification_time = entry->updated_time();
484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (entry->is_file())
485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      remote_file_type = SYNC_FILE_TYPE_FILE;
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    else if (entry->is_folder())
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      remote_file_type = SYNC_FILE_TYPE_DIRECTORY;
488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    else
489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      remote_file_type = SYNC_FILE_TYPE_UNKNOWN;
490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    resolution = conflict_resolution_resolver()->Resolve(
492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        local_file_type, local_modification_time,
493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        remote_file_type, remote_modification_time);
494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (resolution) {
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case CONFLICT_RESOLUTION_MARK_CONFLICT:
49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      HandleManualResolutionCase(callback);
49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case CONFLICT_RESOLUTION_LOCAL_WIN:
50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      HandleLocalWinCase(callback);
50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case CONFLICT_RESOLUTION_REMOTE_WIN:
504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      HandleRemoteWinCase(callback, remote_file_type);
50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case CONFLICT_RESOLUTION_UNKNOWN:
507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      NOTREACHED();
50890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
50990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NOTREACHED();
51090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  callback.Run(SYNC_STATUS_FAILED);
51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
51290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::HandleManualResolutionCase(
51490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback) {
51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (drive_metadata_.conflicted()) {
51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(SYNC_STATUS_HAS_CONFLICT);
51790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
51890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
51990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  has_drive_metadata_ = true;
5217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sync_service_->MarkConflict(
5227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      url_, &drive_metadata_,
5237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&LocalSyncDelegate::DidMarkConflict,
5247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 weak_factory_.GetWeakPtr(), callback));
52590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
52690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid LocalSyncDelegate::DidMarkConflict(
5287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const SyncStatusCallback& callback,
5297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SyncStatusCode status) {
530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DidApplyLocalChange(callback, google_apis::HTTP_CONFLICT, status);
531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::HandleLocalWinCase(
53490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SyncStatusCallback& callback) {
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  util::Log(logging::LOG_VERBOSE, FROM_HERE,
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            "Resolving conflict for local sync: %s: LOCAL WIN",
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            url_.DebugString().c_str());
53890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
53990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!drive_metadata_.resource_id().empty());
54090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!has_drive_metadata_) {
54190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    StartOver(callback, SYNC_STATUS_OK);
54290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
54390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
54490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ResetMetadataForStartOver(base::Bind(&LocalSyncDelegate::StartOver,
546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                       weak_factory_.GetWeakPtr(), callback));
54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::HandleRemoteWinCase(
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const SyncStatusCallback& callback,
551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SyncFileType remote_file_type) {
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  util::Log(logging::LOG_VERBOSE, FROM_HERE,
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            "Resolving conflict for local sync: %s: REMOTE WIN",
5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            url_.DebugString().c_str());
555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ResolveToRemote(callback, remote_file_type);
55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
55790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid LocalSyncDelegate::StartOver(const SyncStatusCallback& callback,
55958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  SyncStatusCode status) {
56090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (status != SYNC_STATUS_OK) {
56190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(status);
56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  remote_change_handler()->RemoveChangeForURL(url_);
56658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
56758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Return the control back to the sync service once.
56858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  callback.Run(SYNC_STATUS_RETRY);
56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
57190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)SyncStatusCode
572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochLocalSyncDelegate::GDataErrorCodeToSyncStatusCodeWrapper(
57390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    google_apis::GDataErrorCode error) {
57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return sync_service_->GDataErrorCodeToSyncStatusCodeWrapper(error);
57590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
57690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDriveMetadataStore* LocalSyncDelegate::metadata_store() {
57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return sync_service_->metadata_store_.get();
57990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
58090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochAPIUtilInterface* LocalSyncDelegate::api_util() {
58290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return sync_service_->api_util_.get();
58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochRemoteChangeHandler* LocalSyncDelegate::remote_change_handler() {
58690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return &sync_service_->remote_change_handler_;
58790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
58890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochConflictResolutionResolver* LocalSyncDelegate::conflict_resolution_resolver() {
590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return &sync_service_->conflict_resolution_resolver_;
591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive_backend
59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace sync_file_system
595