conflict_resolver.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/location.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/drive/drive_api_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/drive/drive_service_interface.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/sync_file_system/logger.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace sync_file_system {
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace drive_backend {
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ConflictResolver::ConflictResolver(SyncEngineContext* sync_context)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : sync_context_(sync_context),
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      weak_ptr_factory_(this) {}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConflictResolver::~ConflictResolver() {}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ConflictResolver::RunExclusive(const SyncStatusCallback& callback) {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsContextReady()) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(SYNC_STATUS_FAILED);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Conflict resolution should be invoked on clean tree.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (metadata_database()->HasDirtyTracker()) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run(SYNC_STATUS_FAILED);
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TrackerIDSet trackers;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (metadata_database()->GetMultiParentFileTrackers(
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &target_file_id_, &trackers)) {
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK_LT(1u, trackers.size());
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!trackers.has_active()) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(SYNC_STATUS_FAILED);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    util::Log(logging::LOG_VERBOSE, FROM_HERE,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "[ConflictResolver] Detected multi-parent trackers "
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              "(active tracker_id=%" PRId64 ")",
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              trackers.active_tracker());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(trackers.has_active());
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (TrackerIDSet::const_iterator itr = trackers.begin();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         itr != trackers.end(); ++itr) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FileTracker tracker;
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (tracker.active())
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      FileTracker parent_tracker;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool should_success = metadata_database()->FindTrackerByTrackerID(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          tracker.parent_tracker_id(), &parent_tracker);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!should_success) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NOTREACHED();
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        callback.Run(SYNC_STATUS_FAILED);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      parents_to_remove_.push_back(parent_tracker.file_id());
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DetachFromNonPrimaryParents(callback);
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (metadata_database()->GetConflictingTrackers(&trackers)) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target_file_id_ = PickPrimaryFile(trackers);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!target_file_id_.empty());
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int64 primary_tracker_id = -1;
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (TrackerIDSet::const_iterator itr = trackers.begin();
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         itr != trackers.end(); ++itr) {
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FileTracker tracker;
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) {
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        NOTREACHED();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (tracker.file_id() != target_file_id_) {
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        non_primary_file_ids_.push_back(
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            std::make_pair(tracker.file_id(), tracker.synced_details().etag()));
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      } else {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        primary_tracker_id = tracker.tracker_id();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    util::Log(logging::LOG_VERBOSE, FROM_HERE,
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              "[ConflictResolver] Detected %" PRIuS " conflicting trackers "
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              "(primary tracker_id=%" PRId64 ")",
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              non_primary_file_ids_.size(), primary_tracker_id);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveNonPrimaryFiles(callback);
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(SYNC_STATUS_NO_CONFLICT);
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConflictResolver::DetachFromNonPrimaryParents(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SyncStatusCallback& callback) {
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(!parents_to_remove_.empty());
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(tzik): Check if ETag match is available for
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // RemoteResourceFromDirectory.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string parent_folder_id = parents_to_remove_.back();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parents_to_remove_.pop_back();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drive_service()->RemoveResourceFromDirectory(
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      parent_folder_id, target_file_id_,
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&ConflictResolver::DidDetachFromParent,
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 weak_ptr_factory_.GetWeakPtr(),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 callback));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  util::Log(logging::LOG_VERBOSE, FROM_HERE,
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            "[ConflictResolver] Detach %s from %s",
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            target_file_id_.c_str(), parent_folder_id.c_str());
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConflictResolver::DidDetachFromParent(const SyncStatusCallback& callback,
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           google_apis::GDataErrorCode error) {
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status != SYNC_STATUS_OK) {
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run(status);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!parents_to_remove_.empty()) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DetachFromNonPrimaryParents(callback);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(SYNC_STATUS_OK);
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstd::string ConflictResolver::PickPrimaryFile(const TrackerIDSet& trackers) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<FileMetadata> primary;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (TrackerIDSet::const_iterator itr = trackers.begin();
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       itr != trackers.end(); ++itr) {
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    FileTracker tracker;
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) {
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NOTREACHED();
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<FileMetadata> file_metadata(new FileMetadata);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!metadata_database()->FindFileByFileID(
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tracker.file_id(), file_metadata.get())) {
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NOTREACHED();
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!primary) {
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      primary = file_metadata.Pass();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(primary->details().file_kind() == FILE_KIND_FILE ||
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           primary->details().file_kind() == FILE_KIND_FOLDER);
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(file_metadata->details().file_kind() == FILE_KIND_FILE ||
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           file_metadata->details().file_kind() == FILE_KIND_FOLDER);
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (primary->details().file_kind() == FILE_KIND_FILE) {
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (file_metadata->details().file_kind() == FILE_KIND_FOLDER) {
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Prioritize folders over regular files.
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary = file_metadata.Pass();
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        continue;
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK(file_metadata->details().file_kind() == FILE_KIND_FILE);
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (primary->details().modification_time() <
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          file_metadata->details().modification_time()) {
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Prioritize last write for regular files.
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary = file_metadata.Pass();
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        continue;
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(primary->details().file_kind() == FILE_KIND_FOLDER);
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (file_metadata->details().file_kind() == FILE_KIND_FILE) {
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Prioritize folders over regular files.
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(file_metadata->details().file_kind() == FILE_KIND_FOLDER);
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (primary->details().creation_time() >
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        file_metadata->details().creation_time()) {
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Prioritize first create for folders.
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      primary = file_metadata.Pass();
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (primary)
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return primary->file_id();
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return std::string();
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ConflictResolver::RemoveNonPrimaryFiles(
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const SyncStatusCallback& callback) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!non_primary_file_ids_.empty());
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string file_id = non_primary_file_ids_.back().first;
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string etag = non_primary_file_ids_.back().second;
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  non_primary_file_ids_.pop_back();
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_NE(target_file_id_, file_id);
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  util::Log(logging::LOG_VERBOSE, FROM_HERE,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "[ConflictResolver] Remove non-primary file %s", file_id.c_str());
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
228  // TODO(tzik): Check if the file is a folder, and merge its contents into
229  // the folder identified by |target_file_id_|.
230  drive_service()->DeleteResource(
231      file_id, etag,
232      base::Bind(&ConflictResolver::DidRemoveFile,
233                 weak_ptr_factory_.GetWeakPtr(),
234                 callback, file_id));
235}
236
237void ConflictResolver::DidRemoveFile(const SyncStatusCallback& callback,
238                                     const std::string& file_id,
239                                     google_apis::GDataErrorCode error) {
240  if (error == google_apis::HTTP_PRECONDITION ||
241      error == google_apis::HTTP_CONFLICT) {
242    UpdateFileMetadata(file_id, callback);
243    return;
244  }
245
246  SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
247  if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) {
248    callback.Run(status);
249    return;
250  }
251
252  deleted_file_ids_.push_back(file_id);
253  if (!non_primary_file_ids_.empty()) {
254    RemoveNonPrimaryFiles(callback);
255    return;
256  }
257
258  metadata_database()->UpdateByDeletedRemoteFileList(
259      deleted_file_ids_, callback);
260}
261
262bool ConflictResolver::IsContextReady() {
263  return sync_context_->GetDriveService() &&
264      sync_context_->GetMetadataDatabase();
265}
266
267void ConflictResolver::UpdateFileMetadata(
268    const std::string& file_id,
269    const SyncStatusCallback& callback) {
270  drive_service()->GetResourceEntry(
271      file_id,
272      base::Bind(&ConflictResolver::DidGetRemoteMetadata,
273                 weak_ptr_factory_.GetWeakPtr(), file_id, callback));
274}
275
276void ConflictResolver::DidGetRemoteMetadata(
277    const std::string& file_id,
278    const SyncStatusCallback& callback,
279    google_apis::GDataErrorCode error,
280    scoped_ptr<google_apis::ResourceEntry> entry) {
281  SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
282  if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) {
283    callback.Run(status);
284    return;
285  }
286
287  if (error != google_apis::HTTP_NOT_FOUND) {
288    metadata_database()->UpdateByDeletedRemoteFile(file_id, callback);
289    return;
290  }
291
292  if (!entry) {
293    NOTREACHED();
294    callback.Run(SYNC_STATUS_FAILED);
295    return;
296  }
297
298  metadata_database()->UpdateByFileResource(
299      *drive::util::ConvertResourceEntryToFileResource(*entry),
300      callback);
301}
302
303drive::DriveServiceInterface* ConflictResolver::drive_service() {
304  set_used_network(true);
305  return sync_context_->GetDriveService();
306}
307
308MetadataDatabase* ConflictResolver::metadata_database() {
309  return sync_context_->GetMetadataDatabase();
310}
311
312}  // namespace drive_backend
313}  // namespace sync_file_system
314