conflict_resolver.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/callback.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/format_macros.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/location.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/drive_api_util.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/drive_service_interface.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync_file_system/logger.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace sync_file_system {
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace drive_backend {
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ConflictResolver::ConflictResolver(SyncEngineContext* sync_context)
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : sync_context_(sync_context),
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      weak_ptr_factory_(this) {
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ConflictResolver::~ConflictResolver() {
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ConflictResolver::RunSequential(const SyncStatusCallback& callback) {
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!IsContextReady()) {
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED();
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback.Run(SYNC_STATUS_FAILED);
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Conflict resolution should be invoked on clean tree.
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (metadata_database()->HasDirtyTracker()) {
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED();
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback.Run(SYNC_STATUS_FAILED);
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TrackerIDSet trackers;
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (metadata_database()->GetMultiParentFileTrackers(
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          &target_file_id_, &trackers)) {
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK_LT(1u, trackers.size());
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!trackers.has_active()) {
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NOTREACHED();
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      callback.Run(SYNC_STATUS_FAILED);
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util::Log(logging::LOG_VERBOSE, FROM_HERE,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              "[ConflictResolver] Detected multi-parent trackers "
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              "(active tracker_id=%" PRId64 ")",
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              trackers.active_tracker());
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(trackers.has_active());
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (TrackerIDSet::const_iterator itr = trackers.begin();
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         itr != trackers.end(); ++itr) {
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FileTracker tracker;
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) {
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        NOTREACHED();
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        continue;
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (tracker.active())
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        continue;
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileTracker parent_tracker;
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      bool should_success = metadata_database()->FindTrackerByTrackerID(
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          tracker.parent_tracker_id(), &parent_tracker);
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (!should_success) {
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        NOTREACHED();
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        callback.Run(SYNC_STATUS_FAILED);
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        return;
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      parents_to_remove_.push_back(parent_tracker.file_id());
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DetachFromNonPrimaryParents(callback);
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (metadata_database()->GetConflictingTrackers(&trackers)) {
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    target_file_id_ = PickPrimaryFile(trackers);
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(!target_file_id_.empty());
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 primary_tracker_id = -1;
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (TrackerIDSet::const_iterator itr = trackers.begin();
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         itr != trackers.end(); ++itr) {
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FileTracker tracker;
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) {
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        NOTREACHED();
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        continue;
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (tracker.file_id() != target_file_id_) {
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        non_primary_file_ids_.push_back(
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            std::make_pair(tracker.file_id(), tracker.synced_details().etag()));
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      } else {
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        primary_tracker_id = tracker.tracker_id();
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util::Log(logging::LOG_VERBOSE, FROM_HERE,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              "[ConflictResolver] Detected %" PRIuS " conflicting trackers "
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              "(primary tracker_id=%" PRId64 ")",
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              non_primary_file_ids_.size(), primary_tracker_id);
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RemoveNonPrimaryFiles(callback);
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run(SYNC_STATUS_NO_CONFLICT);
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ConflictResolver::DetachFromNonPrimaryParents(
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SyncStatusCallback& callback) {
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(!parents_to_remove_.empty());
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(tzik): Check if ETag match is available for
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // RemoteResourceFromDirectory.
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string parent_folder_id = parents_to_remove_.back();
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  parents_to_remove_.pop_back();
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  drive_service()->RemoveResourceFromDirectory(
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      parent_folder_id, target_file_id_,
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&ConflictResolver::DidDetachFromParent,
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 callback));
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  util::Log(logging::LOG_VERBOSE, FROM_HERE,
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "[ConflictResolver] Detach %s from %s",
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            target_file_id_.c_str(), parent_folder_id.c_str());
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ConflictResolver::DidDetachFromParent(const SyncStatusCallback& callback,
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                           google_apis::GDataErrorCode error) {
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (status != SYNC_STATUS_OK) {
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback.Run(status);
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!parents_to_remove_.empty()) {
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DetachFromNonPrimaryParents(callback);
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run(SYNC_STATUS_OK);
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string ConflictResolver::PickPrimaryFile(const TrackerIDSet& trackers) {
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<FileMetadata> primary;
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (TrackerIDSet::const_iterator itr = trackers.begin();
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       itr != trackers.end(); ++itr) {
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FileTracker tracker;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) {
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NOTREACHED();
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<FileMetadata> file_metadata(new FileMetadata);
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!metadata_database()->FindFileByFileID(
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            tracker.file_id(), file_metadata.get())) {
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NOTREACHED();
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      continue;
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!primary) {
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      primary = file_metadata.Pass();
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      continue;
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(primary->details().file_kind() == FILE_KIND_FILE ||
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           primary->details().file_kind() == FILE_KIND_FOLDER);
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(file_metadata->details().file_kind() == FILE_KIND_FILE ||
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           file_metadata->details().file_kind() == FILE_KIND_FOLDER);
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (primary->details().file_kind() == FILE_KIND_FILE) {
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (file_metadata->details().file_kind() == FILE_KIND_FOLDER) {
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Prioritize folders over regular files.
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        primary = file_metadata.Pass();
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        continue;
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DCHECK(file_metadata->details().file_kind() == FILE_KIND_FILE);
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (primary->details().modification_time() <
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          file_metadata->details().modification_time()) {
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Prioritize last write for regular files.
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        primary = file_metadata.Pass();
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        continue;
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      continue;
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(primary->details().file_kind() == FILE_KIND_FOLDER);
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (file_metadata->details().file_kind() == FILE_KIND_FILE) {
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Prioritize folders over regular files.
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      continue;
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(file_metadata->details().file_kind() == FILE_KIND_FOLDER);
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (primary->details().creation_time() >
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        file_metadata->details().creation_time()) {
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Prioritize first create for folders.
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      primary = file_metadata.Pass();
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      continue;
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (primary)
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return primary->file_id();
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return std::string();
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ConflictResolver::RemoveNonPrimaryFiles(
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SyncStatusCallback& callback) {
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(!non_primary_file_ids_.empty());
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string file_id = non_primary_file_ids_.back().first;
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string etag = non_primary_file_ids_.back().second;
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  non_primary_file_ids_.pop_back();
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_NE(target_file_id_, file_id);
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  util::Log(logging::LOG_VERBOSE, FROM_HERE,
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "[ConflictResolver] Remove non-primary file %s", file_id.c_str());
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(tzik): Check if the file is a folder, and merge its contents into
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the folder identified by |target_file_id_|.
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  drive_service()->DeleteResource(
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      file_id, etag,
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&ConflictResolver::DidRemoveFile,
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 callback, file_id));
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ConflictResolver::DidRemoveFile(const SyncStatusCallback& callback,
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     const std::string& file_id,
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     google_apis::GDataErrorCode error) {
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (error == google_apis::HTTP_PRECONDITION ||
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      error == google_apis::HTTP_CONFLICT) {
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UpdateFileMetadata(file_id, callback);
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) {
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback.Run(status);
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  deleted_file_ids_.push_back(file_id);
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!non_primary_file_ids_.empty()) {
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RemoveNonPrimaryFiles(callback);
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  metadata_database()->UpdateByDeletedRemoteFileList(
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      deleted_file_ids_, callback);
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ConflictResolver::IsContextReady() {
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return sync_context_->GetDriveService() &&
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      sync_context_->GetMetadataDatabase();
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ConflictResolver::UpdateFileMetadata(
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& file_id,
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SyncStatusCallback& callback) {
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  drive_service()->GetResourceEntry(
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      file_id,
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&ConflictResolver::DidGetRemoteMetadata,
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(), file_id, callback));
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ConflictResolver::DidGetRemoteMetadata(
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& file_id,
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SyncStatusCallback& callback,
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    google_apis::GDataErrorCode error,
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<google_apis::ResourceEntry> entry) {
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) {
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(status);
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != google_apis::HTTP_NOT_FOUND) {
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    metadata_database()->UpdateByDeletedRemoteFile(file_id, callback);
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!entry) {
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(SYNC_STATUS_FAILED);
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  metadata_database()->UpdateByFileResource(
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *drive::util::ConvertResourceEntryToFileResource(*entry),
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callback);
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)drive::DriveServiceInterface* ConflictResolver::drive_service() {
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  set_used_network(true);
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return sync_context_->GetDriveService();
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MetadataDatabase* ConflictResolver::metadata_database() {
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return sync_context_->GetMetadataDatabase();
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace drive_backend
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace sync_file_system
316