Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/sync_file_system/drive/local_change_processor_delegate. h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/callback.h" | |
| 9 #include "chrome/browser/sync_file_system/drive/api_util.h" | |
| 10 #include "chrome/browser/sync_file_system/drive_file_sync_service.h" | |
| 11 #include "chrome/browser/sync_file_system/drive_metadata_store.h" | |
| 12 #include "webkit/fileapi/syncable/syncable_file_system_util.h" | |
| 13 | |
| 14 namespace sync_file_system { | |
| 15 namespace drive { | |
| 16 | |
| 17 LocalChangeProcessorDelegate::LocalChangeProcessorDelegate( | |
| 18 base::WeakPtr<DriveFileSyncService> sync_service, | |
| 19 const FileChange& local_change, | |
| 20 const base::FilePath& local_path, | |
| 21 const SyncFileMetadata& local_metadata, | |
| 22 const fileapi::FileSystemURL& url) | |
| 23 : sync_service_(sync_service), | |
| 24 url_(url), | |
| 25 local_change_(local_change), | |
| 26 local_path_(local_path), | |
| 27 local_metadata_(local_metadata), | |
| 28 has_drive_metadata_(false), | |
| 29 has_remote_change_(false), | |
| 30 weak_factory_(this) {} | |
| 31 | |
| 32 LocalChangeProcessorDelegate::~LocalChangeProcessorDelegate() {} | |
| 33 | |
| 34 void LocalChangeProcessorDelegate::Run(const SyncStatusCallback& callback) { | |
| 35 if (!sync_service_) | |
| 36 return; | |
| 37 | |
| 38 // TODO(nhiroki): support directory operations (http://crbug.com/161442). | |
| 39 DCHECK(IsSyncDirectoryOperationEnabled() || !local_change_.IsDirectory()); | |
| 40 | |
| 41 has_drive_metadata_ = | |
| 42 metadata_store()->ReadEntry(url_, &drive_metadata_) == SYNC_STATUS_OK; | |
| 43 | |
| 44 if (!has_drive_metadata_) | |
| 45 drive_metadata_.set_md5_checksum(std::string()); | |
| 46 | |
| 47 sync_service_->EnsureOriginRootDirectory( | |
| 48 url_.origin(), | |
| 49 base::Bind(&LocalChangeProcessorDelegate::DidGetOriginRoot, | |
| 50 weak_factory_.GetWeakPtr(), | |
| 51 callback)); | |
| 52 } | |
| 53 | |
| 54 void LocalChangeProcessorDelegate::DidGetOriginRoot( | |
| 55 const SyncStatusCallback& callback, | |
| 56 SyncStatusCode status, | |
| 57 const std::string& origin_resource_id) { | |
| 58 if (!sync_service_) | |
| 59 return; | |
| 60 | |
| 61 if (status != SYNC_STATUS_OK) { | |
| 62 callback.Run(status); | |
| 63 return; | |
| 64 } | |
| 65 | |
| 66 origin_resource_id_ = origin_resource_id; | |
| 67 | |
| 68 has_remote_change_ = | |
| 69 remote_change_handler()->GetChangeForURL(url_, &remote_change_); | |
| 70 if (has_remote_change_ && drive_metadata_.resource_id().empty()) | |
| 71 drive_metadata_.set_resource_id(remote_change_.resource_id); | |
| 72 | |
| 73 LocalSyncOperationType operation = LocalSyncOperationResolver::Resolve( | |
| 74 local_change_, | |
| 75 has_remote_change_ ? &remote_change_.change : NULL, | |
| 76 has_drive_metadata_ ? &drive_metadata_ : NULL); | |
| 77 | |
| 78 DVLOG(1) << "ApplyLocalChange for " << url_.DebugString() | |
| 79 << " local_change:" << local_change_.DebugString() | |
| 80 << " ==> operation:" << operation; | |
| 81 | |
| 82 switch (operation) { | |
| 83 case LOCAL_SYNC_OPERATION_ADD_FILE: | |
| 84 UploadNewFile(callback); | |
| 85 return; | |
| 86 case LOCAL_SYNC_OPERATION_ADD_DIRECTORY: | |
| 87 CreateDirectory(callback); | |
| 88 return; | |
| 89 case LOCAL_SYNC_OPERATION_UPDATE_FILE: | |
| 90 UploadExistingFile(callback); | |
| 91 return; | |
| 92 case LOCAL_SYNC_OPERATION_DELETE_FILE: | |
| 93 DeleteFile(callback); | |
| 94 return; | |
| 95 case LOCAL_SYNC_OPERATION_DELETE_DIRECTORY: | |
| 96 DeleteDirectory(callback); | |
| 97 return; | |
| 98 case LOCAL_SYNC_OPERATION_NONE: | |
| 99 callback.Run(SYNC_STATUS_OK); | |
| 100 return; | |
| 101 case LOCAL_SYNC_OPERATION_CONFLICT: | |
| 102 HandleConflict(callback); | |
| 103 return; | |
| 104 case LOCAL_SYNC_OPERATION_RESOLVE_TO_LOCAL: | |
| 105 ResolveToLocal(callback); | |
| 106 return; | |
| 107 case LOCAL_SYNC_OPERATION_RESOLVE_TO_REMOTE: | |
| 108 ResolveToRemote(callback); | |
| 109 return; | |
| 110 case LOCAL_SYNC_OPERATION_DELETE_METADATA: | |
| 111 DeleteMetadata(base::Bind( | |
| 112 &LocalChangeProcessorDelegate::DidApplyLocalChange, | |
| 113 weak_factory_.GetWeakPtr(), callback, google_apis::HTTP_SUCCESS)); | |
| 114 return; | |
| 115 case LOCAL_SYNC_OPERATION_FAIL: { | |
| 116 callback.Run(SYNC_STATUS_FAILED); | |
| 117 return; | |
| 118 } | |
| 119 } | |
| 120 NOTREACHED(); | |
| 121 callback.Run(SYNC_STATUS_FAILED); | |
| 122 } | |
| 123 | |
| 124 void LocalChangeProcessorDelegate::UploadNewFile( | |
| 125 const SyncStatusCallback& callback) { | |
| 126 if (!sync_service_) | |
| 127 return; | |
| 128 | |
| 129 api_util()->UploadNewFile( | |
| 130 origin_resource_id_, | |
| 131 local_path_, | |
| 132 DriveFileSyncService::PathToTitle(url_.path()), | |
| 133 base::Bind(&LocalChangeProcessorDelegate::DidUploadNewFile, | |
| 134 weak_factory_.GetWeakPtr(), callback)); | |
| 135 } | |
| 136 | |
| 137 void LocalChangeProcessorDelegate::DidUploadNewFile( | |
| 138 const SyncStatusCallback& callback, | |
| 139 google_apis::GDataErrorCode error, | |
| 140 const std::string& resource_id, | |
| 141 const std::string& md5) { | |
| 142 if (!sync_service_) | |
| 143 return; | |
| 144 | |
| 145 switch (error) { | |
| 146 case google_apis::HTTP_CREATED: | |
| 147 UpdateMetadata( | |
| 148 resource_id, md5, DriveMetadata::RESOURCE_TYPE_FILE, | |
| 149 base::Bind(&LocalChangeProcessorDelegate::DidApplyLocalChange, | |
| 150 weak_factory_.GetWeakPtr(), callback, error)); | |
| 151 sync_service_->NotifyObserversFileStatusChanged( | |
| 152 url_, | |
| 153 SYNC_FILE_STATUS_SYNCED, | |
| 154 SYNC_ACTION_ADDED, | |
| 155 SYNC_DIRECTION_LOCAL_TO_REMOTE); | |
| 156 return; | |
| 157 case google_apis::HTTP_CONFLICT: | |
| 158 HandleCreationConflict(resource_id, DriveMetadata::RESOURCE_TYPE_FILE, | |
| 159 callback); | |
| 160 return; | |
| 161 default: | |
| 162 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 void LocalChangeProcessorDelegate::CreateDirectory( | |
| 167 const SyncStatusCallback& callback) { | |
| 168 if (!sync_service_) | |
| 169 return; | |
| 170 | |
| 171 DCHECK(IsSyncDirectoryOperationEnabled()); | |
| 172 api_util()->CreateDirectory( | |
| 173 origin_resource_id_, | |
| 174 DriveFileSyncService::PathToTitle(url_.path()), | |
| 175 base::Bind(&LocalChangeProcessorDelegate::DidCreateDirectory, | |
| 176 weak_factory_.GetWeakPtr(), callback)); | |
| 177 } | |
| 178 | |
| 179 void LocalChangeProcessorDelegate::DidCreateDirectory( | |
| 180 const SyncStatusCallback& callback, | |
| 181 google_apis::GDataErrorCode error, | |
| 182 const std::string& resource_id) { | |
| 183 if (!sync_service_) | |
| 184 return; | |
| 185 | |
| 186 switch (error) { | |
| 187 case google_apis::HTTP_SUCCESS: | |
| 188 case google_apis::HTTP_CREATED: { | |
| 189 UpdateMetadata( | |
| 190 resource_id, std::string(), DriveMetadata::RESOURCE_TYPE_FOLDER, | |
| 191 base::Bind(&LocalChangeProcessorDelegate::DidApplyLocalChange, | |
| 192 weak_factory_.GetWeakPtr(), callback, error)); | |
| 193 sync_service_->NotifyObserversFileStatusChanged( | |
| 194 url_, | |
| 195 SYNC_FILE_STATUS_SYNCED, | |
| 196 SYNC_ACTION_ADDED, | |
| 197 SYNC_DIRECTION_LOCAL_TO_REMOTE); | |
| 198 return; | |
| 199 } | |
| 200 | |
| 201 case google_apis::HTTP_CONFLICT: | |
| 202 // There were conflicts and a file was left. | |
| 203 // TODO(kinuko): Handle the latter case (http://crbug.com/237090). | |
| 204 // Fall-through | |
| 205 | |
| 206 default: | |
| 207 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 void LocalChangeProcessorDelegate::UploadExistingFile( | |
| 212 const SyncStatusCallback& callback) { | |
| 213 if (!sync_service_) | |
| 214 return; | |
| 215 | |
| 216 DCHECK(has_drive_metadata_); | |
| 217 api_util()->UploadExistingFile( | |
| 218 drive_metadata_.resource_id(), | |
| 219 drive_metadata_.md5_checksum(), | |
| 220 local_path_, | |
| 221 base::Bind(&LocalChangeProcessorDelegate::DidUploadExistingFile, | |
| 222 weak_factory_.GetWeakPtr(), callback)); | |
| 223 } | |
| 224 | |
| 225 void LocalChangeProcessorDelegate::DidUploadExistingFile( | |
| 226 const SyncStatusCallback& callback, | |
| 227 google_apis::GDataErrorCode error, | |
| 228 const std::string& resource_id, | |
| 229 const std::string& md5) { | |
| 230 if (!sync_service_) | |
| 231 return; | |
| 232 | |
| 233 DCHECK(has_drive_metadata_); | |
| 234 switch (error) { | |
| 235 case google_apis::HTTP_SUCCESS: | |
| 236 UpdateMetadata( | |
| 237 resource_id, md5, DriveMetadata::RESOURCE_TYPE_FILE, | |
| 238 base::Bind(&LocalChangeProcessorDelegate::DidApplyLocalChange, | |
| 239 weak_factory_.GetWeakPtr(), callback, error)); | |
| 240 sync_service_->NotifyObserversFileStatusChanged( | |
| 241 url_, | |
| 242 SYNC_FILE_STATUS_SYNCED, | |
| 243 SYNC_ACTION_UPDATED, | |
| 244 SYNC_DIRECTION_LOCAL_TO_REMOTE); | |
| 245 return; | |
| 246 case google_apis::HTTP_CONFLICT: { | |
| 247 HandleConflict(callback); | |
| 248 return; | |
| 249 } | |
| 250 case google_apis::HTTP_NOT_MODIFIED: { | |
| 251 DidApplyLocalChange(callback, | |
| 252 google_apis::HTTP_SUCCESS, SYNC_STATUS_OK); | |
| 253 return; | |
| 254 } | |
| 255 case google_apis::HTTP_NOT_FOUND: { | |
| 256 UploadNewFile(callback); | |
| 257 return; | |
| 258 } | |
| 259 default: { | |
| 260 const SyncStatusCode status = | |
| 261 GDataErrorCodeToSyncStatusCodeWrapper(error); | |
| 262 DCHECK_NE(SYNC_STATUS_OK, status); | |
| 263 callback.Run(status); | |
| 264 return; | |
| 265 } | |
| 266 } | |
| 267 } | |
| 268 | |
| 269 void LocalChangeProcessorDelegate::DeleteFile( | |
| 270 const SyncStatusCallback& callback) { | |
| 271 if (!sync_service_) | |
| 272 return; | |
| 273 | |
| 274 DCHECK(has_drive_metadata_); | |
| 275 api_util()->DeleteFile( | |
| 276 drive_metadata_.resource_id(), | |
| 277 drive_metadata_.md5_checksum(), | |
| 278 base::Bind(&LocalChangeProcessorDelegate::DidDeleteFile, | |
| 279 weak_factory_.GetWeakPtr(), callback)); | |
| 280 } | |
| 281 | |
| 282 void LocalChangeProcessorDelegate::DeleteDirectory( | |
| 283 const SyncStatusCallback& callback) { | |
| 284 if (!sync_service_) | |
| 285 return; | |
| 286 | |
| 287 DCHECK(IsSyncDirectoryOperationEnabled()); | |
| 288 DCHECK(has_drive_metadata_); | |
| 289 // This does not handle recursive directory deletion | |
| 290 // (which should not happen other than after a restart). | |
| 291 api_util()->DeleteFile( | |
| 292 drive_metadata_.resource_id(), | |
| 293 std::string(), // empty md5 | |
| 294 base::Bind(&LocalChangeProcessorDelegate::DidDeleteFile, | |
| 295 weak_factory_.GetWeakPtr(), callback)); | |
| 296 } | |
| 297 | |
| 298 void LocalChangeProcessorDelegate::DidDeleteFile( | |
| 299 const SyncStatusCallback& callback, | |
| 300 google_apis::GDataErrorCode error) { | |
| 301 if (!sync_service_) | |
| 302 return; | |
| 303 | |
| 304 DCHECK(has_drive_metadata_); | |
| 305 | |
| 306 switch (error) { | |
| 307 // Regardless of whether the deletion has succeeded (HTTP_SUCCESS) or | |
| 308 // has failed with ETag conflict error (HTTP_PRECONDITION or HTTP_CONFLICT) | |
| 309 // we should just delete the drive_metadata. | |
| 310 // In the former case the file should be just gone now, and | |
| 311 // in the latter case the remote change will be applied in a future | |
| 312 // remote sync. | |
| 313 case google_apis::HTTP_SUCCESS: | |
| 314 case google_apis::HTTP_PRECONDITION: | |
| 315 case google_apis::HTTP_CONFLICT: | |
| 316 DeleteMetadata(base::Bind( | |
| 317 &LocalChangeProcessorDelegate::DidApplyLocalChange, | |
| 318 weak_factory_.GetWeakPtr(), callback, error)); | |
| 319 sync_service_->NotifyObserversFileStatusChanged( | |
| 320 url_, | |
| 321 SYNC_FILE_STATUS_SYNCED, | |
| 322 SYNC_ACTION_DELETED, | |
| 323 SYNC_DIRECTION_LOCAL_TO_REMOTE); | |
| 324 return; | |
| 325 case google_apis::HTTP_NOT_FOUND: | |
| 326 DidApplyLocalChange(callback, | |
| 327 google_apis::HTTP_SUCCESS, SYNC_STATUS_OK); | |
| 328 return; | |
| 329 default: { | |
| 330 const SyncStatusCode status = | |
| 331 GDataErrorCodeToSyncStatusCodeWrapper(error); | |
| 332 DCHECK_NE(SYNC_STATUS_OK, status); | |
| 333 callback.Run(status); | |
| 334 return; | |
| 335 } | |
| 336 } | |
| 337 } | |
| 338 | |
| 339 void LocalChangeProcessorDelegate::ResolveToLocal( | |
| 340 const SyncStatusCallback& callback) { | |
| 341 if (!sync_service_) | |
| 342 return; | |
| 343 | |
| 344 api_util()->DeleteFile( | |
| 345 drive_metadata_.resource_id(), | |
| 346 drive_metadata_.md5_checksum(), | |
| 347 base::Bind( | |
| 348 &LocalChangeProcessorDelegate::DidDeleteFileToResolveToLocal, | |
| 349 weak_factory_.GetWeakPtr(), callback)); | |
| 350 } | |
| 351 | |
| 352 void LocalChangeProcessorDelegate::DidDeleteFileToResolveToLocal( | |
| 353 const SyncStatusCallback& callback, | |
| 354 google_apis::GDataErrorCode error) { | |
| 355 if (!sync_service_) | |
| 356 return; | |
| 357 | |
| 358 if (error != google_apis::HTTP_SUCCESS && | |
| 359 error != google_apis::HTTP_NOT_FOUND) { | |
| 360 remote_change_handler()->RemoveChangeForURL(url_); | |
| 361 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); | |
| 362 return; | |
| 363 } | |
| 364 | |
| 365 DCHECK_NE(SYNC_FILE_TYPE_UNKNOWN, local_metadata_.file_type); | |
| 366 if (local_metadata_.file_type == SYNC_FILE_TYPE_FILE) { | |
| 367 UploadNewFile(callback); | |
| 368 return; | |
| 369 } | |
| 370 | |
| 371 DCHECK(IsSyncDirectoryOperationEnabled()); | |
| 372 DCHECK_EQ(SYNC_FILE_TYPE_DIRECTORY, local_metadata_.file_type); | |
| 373 CreateDirectory(callback); | |
| 374 } | |
| 375 | |
| 376 void LocalChangeProcessorDelegate::ResolveToRemote( | |
| 377 const SyncStatusCallback& callback) { | |
| 378 if (!sync_service_) | |
| 379 return; | |
| 380 | |
| 381 // Mark the file as to-be-fetched. | |
| 382 DCHECK(!drive_metadata_.resource_id().empty()); | |
| 383 | |
| 384 SyncFileType type = remote_change_.change.file_type(); | |
| 385 SetToBeFetched( | |
| 386 drive_metadata_.resource_id(), | |
| 387 DriveFileSyncService::SyncFileTypeToDriveMetadataResourceType(type), | |
| 388 base::Bind(&LocalChangeProcessorDelegate::DidResolveToRemote, | |
| 389 weak_factory_.GetWeakPtr(), callback)); | |
| 390 // The synced notification will be dispatched when the remote file is | |
| 391 // downloaded. | |
| 392 } | |
| 393 | |
| 394 void LocalChangeProcessorDelegate::DidResolveToRemote( | |
| 395 const SyncStatusCallback& callback, | |
| 396 SyncStatusCode status) { | |
| 397 if (!sync_service_) | |
| 398 return; | |
| 399 | |
| 400 DCHECK(has_drive_metadata_); | |
| 401 if (status != SYNC_STATUS_OK) { | |
| 402 callback.Run(status); | |
| 403 return; | |
| 404 } | |
| 405 | |
| 406 SyncFileType file_type = SYNC_FILE_TYPE_FILE; | |
| 407 if (drive_metadata_.type() == DriveMetadata::RESOURCE_TYPE_FOLDER) | |
| 408 file_type = SYNC_FILE_TYPE_DIRECTORY; | |
| 409 sync_service_->AppendFetchChange( | |
| 410 url_.origin(), url_.path(), drive_metadata_.resource_id(), file_type); | |
| 411 callback.Run(status); | |
| 412 } | |
| 413 | |
| 414 void LocalChangeProcessorDelegate::DidApplyLocalChange( | |
| 415 const SyncStatusCallback& callback, | |
| 416 const google_apis::GDataErrorCode error, | |
| 417 SyncStatusCode status) { | |
| 418 if (!sync_service_) | |
| 419 return; | |
| 420 | |
| 421 if (status == SYNC_STATUS_OK) { | |
| 422 remote_change_handler()->RemoveChangeForURL(url_); | |
| 423 status = GDataErrorCodeToSyncStatusCodeWrapper(error); | |
| 424 } | |
| 425 callback.Run(status); | |
| 426 } | |
| 427 | |
| 428 void LocalChangeProcessorDelegate::UpdateMetadata( | |
| 429 const std::string& resource_id, | |
| 430 const std::string& md5, | |
| 431 DriveMetadata::ResourceType type, | |
| 432 const SyncStatusCallback& callback) { | |
| 433 if (!sync_service_) | |
| 434 return; | |
| 435 | |
| 436 drive_metadata_.set_resource_id(resource_id); | |
| 437 drive_metadata_.set_md5_checksum(md5); | |
| 438 drive_metadata_.set_conflicted(false); | |
| 439 drive_metadata_.set_to_be_fetched(false); | |
| 440 drive_metadata_.set_type(type); | |
| 441 metadata_store()->UpdateEntry(url_, drive_metadata_, callback); | |
| 442 } | |
| 443 | |
| 444 void LocalChangeProcessorDelegate::ResetMD5( | |
| 445 const std::string& resource_id, | |
| 446 DriveMetadata::ResourceType type, | |
| 447 const SyncStatusCallback& callback) { | |
|
kinuko
2013/05/16 13:37:37
This could do more than resetting MD5 if the given
tzik
2013/05/17 05:14:10
Done.
| |
| 448 UpdateMetadata(resource_id, std::string(), type, callback); | |
| 449 } | |
| 450 | |
| 451 void LocalChangeProcessorDelegate::SetToBeFetched( | |
| 452 const std::string& resource_id, | |
| 453 DriveMetadata::ResourceType type, | |
| 454 const SyncStatusCallback& callback) { | |
| 455 if (!sync_service_) | |
| 456 return; | |
| 457 | |
| 458 drive_metadata_.set_resource_id(resource_id); | |
| 459 drive_metadata_.set_md5_checksum(std::string()); | |
| 460 drive_metadata_.set_conflicted(false); | |
| 461 drive_metadata_.set_to_be_fetched(true); | |
| 462 drive_metadata_.set_type(type); | |
| 463 metadata_store()->UpdateEntry(url_, drive_metadata_, callback); | |
| 464 } | |
| 465 | |
| 466 void LocalChangeProcessorDelegate::SetConflict( | |
| 467 const std::string& resource_id, | |
| 468 const std::string& md5, | |
| 469 DriveMetadata::ResourceType type, | |
| 470 const SyncStatusCallback& callback) { | |
| 471 if (!sync_service_) | |
| 472 return; | |
| 473 | |
| 474 drive_metadata_.set_resource_id(resource_id); | |
| 475 drive_metadata_.set_md5_checksum(md5); | |
| 476 drive_metadata_.set_conflicted(true); | |
| 477 drive_metadata_.set_to_be_fetched(false); | |
| 478 drive_metadata_.set_type(type); | |
| 479 metadata_store()->UpdateEntry(url_, drive_metadata_, callback); | |
| 480 } | |
| 481 | |
| 482 void LocalChangeProcessorDelegate::DeleteMetadata( | |
| 483 const SyncStatusCallback& callback) { | |
| 484 metadata_store()->DeleteEntry(url_, callback); | |
| 485 } | |
| 486 | |
| 487 void LocalChangeProcessorDelegate::HandleCreationConflict( | |
| 488 const std::string& resource_id, | |
| 489 DriveMetadata::ResourceType type, | |
| 490 const SyncStatusCallback& callback) { | |
| 491 if (!sync_service_) | |
| 492 return; | |
| 493 | |
| 494 // File-file conflict is found. | |
| 495 // Populates a fake drive_metadata and set has_drive_metadata = true. | |
| 496 // In HandleConflictLocalSync: | |
| 497 // - If conflict_resolution is manual, we'll change conflicted to true | |
| 498 // and save the metadata. | |
| 499 // - Otherwise we'll save the metadata with empty md5 and will start | |
| 500 // over local sync as UploadExistingFile. | |
| 501 drive_metadata_.set_resource_id(resource_id); | |
| 502 drive_metadata_.set_md5_checksum(std::string()); | |
| 503 drive_metadata_.set_conflicted(false); | |
| 504 drive_metadata_.set_to_be_fetched(false); | |
| 505 drive_metadata_.set_type(type); | |
| 506 has_drive_metadata_ = true; | |
| 507 HandleConflict(callback); | |
| 508 } | |
| 509 | |
| 510 void LocalChangeProcessorDelegate::HandleConflict( | |
| 511 const SyncStatusCallback& callback) { | |
| 512 if (!sync_service_) | |
| 513 return; | |
| 514 | |
| 515 DCHECK(!drive_metadata_.resource_id().empty()); | |
| 516 api_util()->GetResourceEntry( | |
| 517 drive_metadata_.resource_id(), | |
| 518 base::Bind( | |
| 519 &LocalChangeProcessorDelegate::DidGetEntryForConflictResolution, | |
| 520 weak_factory_.GetWeakPtr(), callback)); | |
| 521 } | |
| 522 | |
| 523 void LocalChangeProcessorDelegate::DidGetEntryForConflictResolution( | |
| 524 const SyncStatusCallback& callback, | |
| 525 google_apis::GDataErrorCode error, | |
| 526 scoped_ptr<google_apis::ResourceEntry> entry) { | |
| 527 if (!sync_service_) | |
| 528 return; | |
| 529 | |
| 530 SyncFileType local_file_type = local_metadata_.file_type; | |
| 531 base::Time local_modification_time = local_metadata_.last_modified; | |
| 532 | |
| 533 SyncFileType remote_file_type; | |
| 534 base::Time remote_modification_time = entry->updated_time(); | |
| 535 if (entry->is_file()) | |
| 536 remote_file_type = SYNC_FILE_TYPE_FILE; | |
| 537 else if (entry->is_folder()) | |
| 538 remote_file_type = SYNC_FILE_TYPE_DIRECTORY; | |
| 539 else | |
| 540 remote_file_type = SYNC_FILE_TYPE_UNKNOWN; | |
| 541 | |
| 542 switch (sync_service_->ResolveConflictForLocalSync( | |
| 543 local_file_type, local_modification_time, | |
| 544 remote_file_type, remote_modification_time)) { | |
|
kinuko
2013/05/16 13:37:37
nit: can you move this method calling before switc
tzik
2013/05/17 05:14:10
Done.
| |
| 545 case DriveFileSyncService::CONFLICT_RESOLUTION_MARK_CONFLICT: | |
| 546 HandleManualResolutionCase(callback); | |
| 547 return; | |
| 548 case DriveFileSyncService::CONFLICT_RESOLUTION_LOCAL_WIN: | |
| 549 HandleLocalWinCase(callback); | |
| 550 return; | |
| 551 case DriveFileSyncService::CONFLICT_RESOLUTION_REMOTE_WIN: | |
| 552 HandleRemoteWinCase(callback); | |
| 553 return; | |
| 554 } | |
| 555 NOTREACHED(); | |
| 556 callback.Run(SYNC_STATUS_FAILED); | |
| 557 } | |
| 558 | |
| 559 void LocalChangeProcessorDelegate::HandleManualResolutionCase( | |
| 560 const SyncStatusCallback& callback) { | |
| 561 if (drive_metadata_.conflicted()) { | |
| 562 callback.Run(SYNC_STATUS_HAS_CONFLICT); | |
| 563 return; | |
| 564 } | |
| 565 | |
| 566 SetConflict(drive_metadata_.resource_id(), | |
| 567 drive_metadata_.md5_checksum(), | |
| 568 DriveFileSyncService::SyncFileTypeToDriveMetadataResourceType( | |
| 569 local_metadata_.file_type), | |
| 570 base::Bind(&LocalChangeProcessorDelegate::DidApplyLocalChange, | |
| 571 weak_factory_.GetWeakPtr(), callback, | |
| 572 google_apis::HTTP_CONFLICT)); | |
| 573 } | |
| 574 | |
| 575 void LocalChangeProcessorDelegate::HandleLocalWinCase( | |
| 576 const SyncStatusCallback& callback) { | |
| 577 DVLOG(1) << "Resolving conflict for local sync:" | |
| 578 << url_.DebugString() << ": LOCAL WIN"; | |
| 579 | |
| 580 DCHECK(!drive_metadata_.resource_id().empty()); | |
| 581 if (!has_drive_metadata_) { | |
| 582 StartOver(callback, SYNC_STATUS_OK); | |
| 583 return; | |
| 584 } | |
| 585 | |
| 586 ResetMD5(drive_metadata_.resource_id(), | |
| 587 drive_metadata_.type(), | |
| 588 base::Bind(&LocalChangeProcessorDelegate::StartOver, | |
| 589 weak_factory_.GetWeakPtr(), callback)); | |
| 590 } | |
| 591 | |
| 592 void LocalChangeProcessorDelegate::HandleRemoteWinCase( | |
| 593 const SyncStatusCallback& callback) { | |
| 594 DVLOG(1) << "Resolving conflict for local sync:" | |
| 595 << url_.DebugString() << ": REMOTE WIN"; | |
| 596 ResolveToRemote(callback); | |
| 597 } | |
| 598 | |
| 599 void LocalChangeProcessorDelegate::StartOver(const SyncStatusCallback& callback, | |
| 600 SyncStatusCode status) { | |
| 601 if (status != SYNC_STATUS_OK) { | |
| 602 callback.Run(status); | |
| 603 return; | |
| 604 } | |
| 605 | |
| 606 remote_change_handler()->RemoveChangeForURL(url_); | |
| 607 Run(callback); | |
| 608 } | |
| 609 | |
| 610 SyncStatusCode | |
| 611 LocalChangeProcessorDelegate::GDataErrorCodeToSyncStatusCodeWrapper( | |
| 612 google_apis::GDataErrorCode error) { | |
| 613 return sync_service_->GDataErrorCodeToSyncStatusCodeWrapper(error); | |
| 614 } | |
| 615 | |
| 616 DriveMetadataStore* LocalChangeProcessorDelegate::metadata_store() { | |
| 617 return sync_service_->metadata_store_.get(); | |
| 618 } | |
| 619 | |
| 620 APIUtilInterface* LocalChangeProcessorDelegate::api_util() { | |
| 621 return sync_service_->api_util_.get(); | |
| 622 } | |
| 623 | |
| 624 RemoteChangeHandler* LocalChangeProcessorDelegate::remote_change_handler() { | |
| 625 return &sync_service_->remote_change_handler_; | |
| 626 } | |
| 627 | |
| 628 } // drive | |
| 629 } // namespace sync_file_system | |
| OLD | NEW |