| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h" | 5 #include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 namespace sync_file_system { | 27 namespace sync_file_system { |
| 28 namespace drive_backend { | 28 namespace drive_backend { |
| 29 | 29 |
| 30 ConflictResolver::ConflictResolver(SyncEngineContext* sync_context) | 30 ConflictResolver::ConflictResolver(SyncEngineContext* sync_context) |
| 31 : sync_context_(sync_context), | 31 : sync_context_(sync_context), |
| 32 weak_ptr_factory_(this) {} | 32 weak_ptr_factory_(this) {} |
| 33 | 33 |
| 34 ConflictResolver::~ConflictResolver() {} | 34 ConflictResolver::~ConflictResolver() {} |
| 35 | 35 |
| 36 void ConflictResolver::RunPreflight(scoped_ptr<SyncTaskToken> token) { | 36 void ConflictResolver::RunPreflight(std::unique_ptr<SyncTaskToken> token) { |
| 37 token->InitializeTaskLog("Conflict Resolution"); | 37 token->InitializeTaskLog("Conflict Resolution"); |
| 38 | 38 |
| 39 scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker); | 39 std::unique_ptr<TaskBlocker> task_blocker(new TaskBlocker); |
| 40 task_blocker->exclusive = true; | 40 task_blocker->exclusive = true; |
| 41 SyncTaskManager::UpdateTaskBlocker( | 41 SyncTaskManager::UpdateTaskBlocker( |
| 42 std::move(token), std::move(task_blocker), | 42 std::move(token), std::move(task_blocker), |
| 43 base::Bind(&ConflictResolver::RunExclusive, | 43 base::Bind(&ConflictResolver::RunExclusive, |
| 44 weak_ptr_factory_.GetWeakPtr())); | 44 weak_ptr_factory_.GetWeakPtr())); |
| 45 } | 45 } |
| 46 | 46 |
| 47 void ConflictResolver::RunExclusive(scoped_ptr<SyncTaskToken> token) { | 47 void ConflictResolver::RunExclusive(std::unique_ptr<SyncTaskToken> token) { |
| 48 if (!IsContextReady()) { | 48 if (!IsContextReady()) { |
| 49 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_FAILED); | 49 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_FAILED); |
| 50 return; | 50 return; |
| 51 } | 51 } |
| 52 | 52 |
| 53 // Conflict resolution should be invoked on clean tree. | 53 // Conflict resolution should be invoked on clean tree. |
| 54 if (metadata_database()->HasDirtyTracker()) { | 54 if (metadata_database()->HasDirtyTracker()) { |
| 55 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_RETRY); | 55 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_RETRY); |
| 56 return; | 56 return; |
| 57 } | 57 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 non_primary_file_ids_.size(), primary_tracker_id)); | 121 non_primary_file_ids_.size(), primary_tracker_id)); |
| 122 | 122 |
| 123 RemoveNonPrimaryFiles(std::move(token)); | 123 RemoveNonPrimaryFiles(std::move(token)); |
| 124 return; | 124 return; |
| 125 } | 125 } |
| 126 | 126 |
| 127 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_NO_CONFLICT); | 127 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_NO_CONFLICT); |
| 128 } | 128 } |
| 129 | 129 |
| 130 void ConflictResolver::DetachFromNonPrimaryParents( | 130 void ConflictResolver::DetachFromNonPrimaryParents( |
| 131 scoped_ptr<SyncTaskToken> token) { | 131 std::unique_ptr<SyncTaskToken> token) { |
| 132 DCHECK(!parents_to_remove_.empty()); | 132 DCHECK(!parents_to_remove_.empty()); |
| 133 | 133 |
| 134 // TODO(tzik): Check if ETag match is available for | 134 // TODO(tzik): Check if ETag match is available for |
| 135 // RemoteResourceFromDirectory. | 135 // RemoteResourceFromDirectory. |
| 136 std::string parent_folder_id = parents_to_remove_.back(); | 136 std::string parent_folder_id = parents_to_remove_.back(); |
| 137 parents_to_remove_.pop_back(); | 137 parents_to_remove_.pop_back(); |
| 138 | 138 |
| 139 token->RecordLog(base::StringPrintf( | 139 token->RecordLog(base::StringPrintf( |
| 140 "Detach %s from %s", | 140 "Detach %s from %s", |
| 141 target_file_id_.c_str(), parent_folder_id.c_str())); | 141 target_file_id_.c_str(), parent_folder_id.c_str())); |
| 142 | 142 |
| 143 drive_service()->RemoveResourceFromDirectory( | 143 drive_service()->RemoveResourceFromDirectory( |
| 144 parent_folder_id, target_file_id_, | 144 parent_folder_id, target_file_id_, |
| 145 base::Bind(&ConflictResolver::DidDetachFromParent, | 145 base::Bind(&ConflictResolver::DidDetachFromParent, |
| 146 weak_ptr_factory_.GetWeakPtr(), | 146 weak_ptr_factory_.GetWeakPtr(), |
| 147 base::Passed(&token))); | 147 base::Passed(&token))); |
| 148 } | 148 } |
| 149 | 149 |
| 150 void ConflictResolver::DidDetachFromParent( | 150 void ConflictResolver::DidDetachFromParent( |
| 151 scoped_ptr<SyncTaskToken> token, | 151 std::unique_ptr<SyncTaskToken> token, |
| 152 google_apis::DriveApiErrorCode error) { | 152 google_apis::DriveApiErrorCode error) { |
| 153 SyncStatusCode status = DriveApiErrorCodeToSyncStatusCode(error); | 153 SyncStatusCode status = DriveApiErrorCodeToSyncStatusCode(error); |
| 154 if (status != SYNC_STATUS_OK) { | 154 if (status != SYNC_STATUS_OK) { |
| 155 SyncTaskManager::NotifyTaskDone(std::move(token), status); | 155 SyncTaskManager::NotifyTaskDone(std::move(token), status); |
| 156 return; | 156 return; |
| 157 } | 157 } |
| 158 | 158 |
| 159 if (!parents_to_remove_.empty()) { | 159 if (!parents_to_remove_.empty()) { |
| 160 DetachFromNonPrimaryParents(std::move(token)); | 160 DetachFromNonPrimaryParents(std::move(token)); |
| 161 return; | 161 return; |
| 162 } | 162 } |
| 163 | 163 |
| 164 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_OK); | 164 SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_OK); |
| 165 } | 165 } |
| 166 | 166 |
| 167 std::string ConflictResolver::PickPrimaryFile(const TrackerIDSet& trackers) { | 167 std::string ConflictResolver::PickPrimaryFile(const TrackerIDSet& trackers) { |
| 168 scoped_ptr<FileMetadata> primary; | 168 std::unique_ptr<FileMetadata> primary; |
| 169 for (TrackerIDSet::const_iterator itr = trackers.begin(); | 169 for (TrackerIDSet::const_iterator itr = trackers.begin(); |
| 170 itr != trackers.end(); ++itr) { | 170 itr != trackers.end(); ++itr) { |
| 171 FileTracker tracker; | 171 FileTracker tracker; |
| 172 if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) { | 172 if (!metadata_database()->FindTrackerByTrackerID(*itr, &tracker)) { |
| 173 NOTREACHED(); | 173 NOTREACHED(); |
| 174 continue; | 174 continue; |
| 175 } | 175 } |
| 176 | 176 |
| 177 scoped_ptr<FileMetadata> file_metadata(new FileMetadata); | 177 std::unique_ptr<FileMetadata> file_metadata(new FileMetadata); |
| 178 if (!metadata_database()->FindFileByFileID( | 178 if (!metadata_database()->FindFileByFileID( |
| 179 tracker.file_id(), file_metadata.get())) { | 179 tracker.file_id(), file_metadata.get())) { |
| 180 NOTREACHED(); | 180 NOTREACHED(); |
| 181 continue; | 181 continue; |
| 182 } | 182 } |
| 183 | 183 |
| 184 if (!primary) { | 184 if (!primary) { |
| 185 primary = std::move(file_metadata); | 185 primary = std::move(file_metadata); |
| 186 continue; | 186 continue; |
| 187 } | 187 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 primary = std::move(file_metadata); | 222 primary = std::move(file_metadata); |
| 223 continue; | 223 continue; |
| 224 } | 224 } |
| 225 } | 225 } |
| 226 | 226 |
| 227 if (primary) | 227 if (primary) |
| 228 return primary->file_id(); | 228 return primary->file_id(); |
| 229 return std::string(); | 229 return std::string(); |
| 230 } | 230 } |
| 231 | 231 |
| 232 void ConflictResolver::RemoveNonPrimaryFiles(scoped_ptr<SyncTaskToken> token) { | 232 void ConflictResolver::RemoveNonPrimaryFiles( |
| 233 std::unique_ptr<SyncTaskToken> token) { |
| 233 DCHECK(!non_primary_file_ids_.empty()); | 234 DCHECK(!non_primary_file_ids_.empty()); |
| 234 | 235 |
| 235 std::string file_id = non_primary_file_ids_.back().first; | 236 std::string file_id = non_primary_file_ids_.back().first; |
| 236 std::string etag = non_primary_file_ids_.back().second; | 237 std::string etag = non_primary_file_ids_.back().second; |
| 237 non_primary_file_ids_.pop_back(); | 238 non_primary_file_ids_.pop_back(); |
| 238 | 239 |
| 239 DCHECK_NE(target_file_id_, file_id); | 240 DCHECK_NE(target_file_id_, file_id); |
| 240 | 241 |
| 241 token->RecordLog(base::StringPrintf( | 242 token->RecordLog(base::StringPrintf( |
| 242 "Remove non-primary file %s", file_id.c_str())); | 243 "Remove non-primary file %s", file_id.c_str())); |
| 243 | 244 |
| 244 // TODO(tzik): Check if the file is a folder, and merge its contents into | 245 // TODO(tzik): Check if the file is a folder, and merge its contents into |
| 245 // the folder identified by |target_file_id_|. | 246 // the folder identified by |target_file_id_|. |
| 246 drive_service()->DeleteResource( | 247 drive_service()->DeleteResource( |
| 247 file_id, etag, | 248 file_id, etag, |
| 248 base::Bind(&ConflictResolver::DidRemoveFile, | 249 base::Bind(&ConflictResolver::DidRemoveFile, |
| 249 weak_ptr_factory_.GetWeakPtr(), | 250 weak_ptr_factory_.GetWeakPtr(), |
| 250 base::Passed(&token), file_id)); | 251 base::Passed(&token), file_id)); |
| 251 } | 252 } |
| 252 | 253 |
| 253 void ConflictResolver::DidRemoveFile(scoped_ptr<SyncTaskToken> token, | 254 void ConflictResolver::DidRemoveFile(std::unique_ptr<SyncTaskToken> token, |
| 254 const std::string& file_id, | 255 const std::string& file_id, |
| 255 google_apis::DriveApiErrorCode error) { | 256 google_apis::DriveApiErrorCode error) { |
| 256 if (error == google_apis::HTTP_PRECONDITION || | 257 if (error == google_apis::HTTP_PRECONDITION || |
| 257 error == google_apis::HTTP_CONFLICT) { | 258 error == google_apis::HTTP_CONFLICT) { |
| 258 UpdateFileMetadata(file_id, std::move(token)); | 259 UpdateFileMetadata(file_id, std::move(token)); |
| 259 return; | 260 return; |
| 260 } | 261 } |
| 261 | 262 |
| 262 SyncStatusCode status = DriveApiErrorCodeToSyncStatusCode(error); | 263 SyncStatusCode status = DriveApiErrorCodeToSyncStatusCode(error); |
| 263 if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) { | 264 if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 276 SyncTaskManager::NotifyTaskDone(std::move(token), status); | 277 SyncTaskManager::NotifyTaskDone(std::move(token), status); |
| 277 } | 278 } |
| 278 | 279 |
| 279 bool ConflictResolver::IsContextReady() { | 280 bool ConflictResolver::IsContextReady() { |
| 280 return sync_context_->GetDriveService() && | 281 return sync_context_->GetDriveService() && |
| 281 sync_context_->GetMetadataDatabase(); | 282 sync_context_->GetMetadataDatabase(); |
| 282 } | 283 } |
| 283 | 284 |
| 284 void ConflictResolver::UpdateFileMetadata( | 285 void ConflictResolver::UpdateFileMetadata( |
| 285 const std::string& file_id, | 286 const std::string& file_id, |
| 286 scoped_ptr<SyncTaskToken> token) { | 287 std::unique_ptr<SyncTaskToken> token) { |
| 287 drive_service()->GetFileResource( | 288 drive_service()->GetFileResource( |
| 288 file_id, | 289 file_id, |
| 289 base::Bind(&ConflictResolver::DidGetRemoteMetadata, | 290 base::Bind(&ConflictResolver::DidGetRemoteMetadata, |
| 290 weak_ptr_factory_.GetWeakPtr(), file_id, | 291 weak_ptr_factory_.GetWeakPtr(), file_id, |
| 291 base::Passed(&token))); | 292 base::Passed(&token))); |
| 292 } | 293 } |
| 293 | 294 |
| 294 void ConflictResolver::DidGetRemoteMetadata( | 295 void ConflictResolver::DidGetRemoteMetadata( |
| 295 const std::string& file_id, | 296 const std::string& file_id, |
| 296 scoped_ptr<SyncTaskToken> token, | 297 std::unique_ptr<SyncTaskToken> token, |
| 297 google_apis::DriveApiErrorCode error, | 298 google_apis::DriveApiErrorCode error, |
| 298 scoped_ptr<google_apis::FileResource> entry) { | 299 std::unique_ptr<google_apis::FileResource> entry) { |
| 299 SyncStatusCode status = DriveApiErrorCodeToSyncStatusCode(error); | 300 SyncStatusCode status = DriveApiErrorCodeToSyncStatusCode(error); |
| 300 if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) { | 301 if (status != SYNC_STATUS_OK && error != google_apis::HTTP_NOT_FOUND) { |
| 301 SyncTaskManager::NotifyTaskDone(std::move(token), status); | 302 SyncTaskManager::NotifyTaskDone(std::move(token), status); |
| 302 return; | 303 return; |
| 303 } | 304 } |
| 304 | 305 |
| 305 if (error != google_apis::HTTP_NOT_FOUND) { | 306 if (error != google_apis::HTTP_NOT_FOUND) { |
| 306 status = metadata_database()->UpdateByDeletedRemoteFile(file_id); | 307 status = metadata_database()->UpdateByDeletedRemoteFile(file_id); |
| 307 SyncTaskManager::NotifyTaskDone(std::move(token), status); | 308 SyncTaskManager::NotifyTaskDone(std::move(token), status); |
| 308 return; | 309 return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 322 set_used_network(true); | 323 set_used_network(true); |
| 323 return sync_context_->GetDriveService(); | 324 return sync_context_->GetDriveService(); |
| 324 } | 325 } |
| 325 | 326 |
| 326 MetadataDatabase* ConflictResolver::metadata_database() { | 327 MetadataDatabase* ConflictResolver::metadata_database() { |
| 327 return sync_context_->GetMetadataDatabase(); | 328 return sync_context_->GetMetadataDatabase(); |
| 328 } | 329 } |
| 329 | 330 |
| 330 } // namespace drive_backend | 331 } // namespace drive_backend |
| 331 } // namespace sync_file_system | 332 } // namespace sync_file_system |
| OLD | NEW |