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