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