Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_file_sync_service.h" | 5 #include "chrome/browser/sync_file_system/drive_file_sync_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include "webkit/fileapi/syncable/sync_file_type.h" | 29 #include "webkit/fileapi/syncable/sync_file_type.h" |
| 30 #include "webkit/fileapi/syncable/syncable_file_system_util.h" | 30 #include "webkit/fileapi/syncable/syncable_file_system_util.h" |
| 31 | 31 |
| 32 namespace sync_file_system { | 32 namespace sync_file_system { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); | 36 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); |
| 37 const FilePath::CharType kSyncFileSystemDir[] = | 37 const FilePath::CharType kSyncFileSystemDir[] = |
| 38 FILE_PATH_LITERAL("Sync FileSystem"); | 38 FILE_PATH_LITERAL("Sync FileSystem"); |
| 39 const int64 kMinimumPollingDelaySeconds = 10; | |
| 40 const int64 kMaximumPollingDelaySeconds = 60 * 60; // 1 hour | |
| 41 const double kDelayMultiplier = 2; | |
| 39 | 42 |
| 40 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { | 43 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { |
| 41 return file_util::CreateDirectory(dir_path) && | 44 return file_util::CreateDirectory(dir_path) && |
| 42 file_util::CreateTemporaryFileInDir(dir_path, temp_file); | 45 file_util::CreateTemporaryFileInDir(dir_path, temp_file); |
| 43 } | 46 } |
| 44 | 47 |
| 45 void DeleteTemporaryFile(const FilePath& file_path) { | 48 void DeleteTemporaryFile(const FilePath& file_path) { |
| 46 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { | 49 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { |
| 47 content::BrowserThread::PostTask( | 50 content::BrowserThread::PostTask( |
| 48 content::BrowserThread::FILE, FROM_HERE, | 51 content::BrowserThread::FILE, FROM_HERE, |
| 49 base::Bind(&DeleteTemporaryFile, file_path)); | 52 base::Bind(&DeleteTemporaryFile, file_path)); |
| 50 return; | 53 return; |
| 51 } | 54 } |
| 52 | 55 |
| 53 if (!file_util::Delete(file_path, true)) | 56 if (!file_util::Delete(file_path, true)) |
| 54 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: " | 57 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: " |
| 55 << file_path.value(); | 58 << file_path.value(); |
| 56 } | 59 } |
| 57 | 60 |
| 58 void DidUpdateConflictState(fileapi::SyncStatusCode status) { | 61 void DidUpdateConflictState(fileapi::SyncStatusCode status) { |
| 59 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); | 62 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); |
| 60 } | 63 } |
| 61 | 64 |
| 62 void EmptyStatusCallback(fileapi::SyncStatusCode code) {} | 65 void EmptyStatusCallback(fileapi::SyncStatusCode code) {} |
| 63 | 66 |
| 67 void EnablePolling(bool* polling_enabled) { | |
| 68 *polling_enabled = true; | |
| 69 } | |
| 70 | |
| 64 } // namespace | 71 } // namespace |
| 65 | 72 |
| 66 const char DriveFileSyncService::kServiceName[] = "drive"; | 73 const char DriveFileSyncService::kServiceName[] = "drive"; |
| 67 | 74 |
| 68 class DriveFileSyncService::TaskToken { | 75 class DriveFileSyncService::TaskToken { |
| 69 public: | 76 public: |
| 70 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service) | 77 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service) |
| 71 : sync_service_(sync_service), | 78 : sync_service_(sync_service), |
| 72 task_type_(TASK_TYPE_NONE) { | 79 task_type_(TASK_TYPE_NONE) { |
| 73 } | 80 } |
| 74 | 81 |
| 75 void ResetTask(const tracked_objects::Location& location) { | 82 void ResetTask(const tracked_objects::Location& location) { |
| 76 location_ = location; | 83 location_ = location; |
| 77 task_type_ = TASK_TYPE_NONE; | 84 task_type_ = TASK_TYPE_NONE; |
| 78 description_.clear(); | 85 description_.clear(); |
| 86 callback_.Reset(); | |
| 79 } | 87 } |
| 80 | 88 |
| 81 void UpdateTask(const tracked_objects::Location& location, | 89 void UpdateTask(const tracked_objects::Location& location, |
| 82 TaskType task_type, | 90 TaskType task_type, |
| 83 const std::string& description) { | 91 const std::string& description) { |
| 84 location_ = location; | 92 location_ = location; |
| 85 task_type_ = task_type; | 93 task_type_ = task_type; |
| 86 description_ = description; | 94 description_ = description; |
| 87 | 95 |
| 88 DVLOG(1) << "Token updated: " << description_ | 96 DVLOG(1) << "Token updated: " << description_ |
| 89 << " " << location_.ToString(); | 97 << " " << location_.ToString(); |
| 90 } | 98 } |
| 91 | 99 |
| 92 const tracked_objects::Location& location() const { return location_; } | 100 const tracked_objects::Location& location() const { return location_; } |
| 93 TaskType task_type() const { return task_type_; } | 101 TaskType task_type() const { return task_type_; } |
| 94 const std::string& description() const { return description_; } | 102 const std::string& description() const { return description_; } |
| 95 std::string done_description() const { return description_ + " done"; } | 103 std::string done_description() const { return description_ + " done"; } |
| 96 | 104 |
| 105 void set_callback(const base::Closure& callback) { | |
|
kinuko
2012/12/04 06:59:17
nit: set_completion_callback(), completion_callbac
tzik
2012/12/04 07:06:09
Done.
| |
| 106 callback_ = callback; | |
| 107 } | |
| 108 | |
| 109 const base::Closure& callback() { | |
| 110 return callback_; | |
| 111 } | |
| 112 | |
| 97 ~TaskToken() { | 113 ~TaskToken() { |
| 98 // All task on DriveFileSyncService must hold TaskToken instance to ensure | 114 // All task on DriveFileSyncService must hold TaskToken instance to ensure |
| 99 // no other tasks are running. Also, as soon as a task finishes to work, | 115 // no other tasks are running. Also, as soon as a task finishes to work, |
| 100 // it must return the token to DriveFileSyncService. | 116 // it must return the token to DriveFileSyncService. |
| 101 // Destroying a token with valid |sync_service_| indicates the token was | 117 // Destroying a token with valid |sync_service_| indicates the token was |
| 102 // dropped by a task without returning. | 118 // dropped by a task without returning. |
| 103 DCHECK(!sync_service_); | |
| 104 if (sync_service_) { | 119 if (sync_service_) { |
| 105 LOG(ERROR) << "Unexpected TaskToken deletion from: " | 120 LOG(ERROR) << "Unexpected TaskToken deletion from: " |
| 106 << location_.ToString() << " while: " << description_; | 121 << location_.ToString() << " while: " << description_; |
| 107 } | 122 } |
| 123 DCHECK(!sync_service_); | |
| 108 } | 124 } |
| 109 | 125 |
| 110 private: | 126 private: |
| 111 base::WeakPtr<DriveFileSyncService> sync_service_; | 127 base::WeakPtr<DriveFileSyncService> sync_service_; |
| 112 tracked_objects::Location location_; | 128 tracked_objects::Location location_; |
| 113 TaskType task_type_; | 129 TaskType task_type_; |
| 114 std::string description_; | 130 std::string description_; |
| 131 base::Closure callback_; | |
| 115 | 132 |
| 116 DISALLOW_COPY_AND_ASSIGN(TaskToken); | 133 DISALLOW_COPY_AND_ASSIGN(TaskToken); |
| 117 }; | 134 }; |
| 118 | 135 |
| 119 struct DriveFileSyncService::ProcessRemoteChangeParam { | 136 struct DriveFileSyncService::ProcessRemoteChangeParam { |
| 120 scoped_ptr<TaskToken> token; | 137 scoped_ptr<TaskToken> token; |
| 121 RemoteChangeProcessor* processor; | 138 RemoteChangeProcessor* processor; |
| 122 RemoteChange remote_change; | 139 RemoteChange remote_change; |
| 123 fileapi::SyncOperationCallback callback; | 140 fileapi::SyncOperationCallback callback; |
| 124 | 141 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 // Smaller changestamps have higher priorities (i.e. need to be processed | 213 // Smaller changestamps have higher priorities (i.e. need to be processed |
| 197 // earlier). | 214 // earlier). |
| 198 if (left.changestamp != right.changestamp) | 215 if (left.changestamp != right.changestamp) |
| 199 return left.changestamp > right.changestamp; | 216 return left.changestamp > right.changestamp; |
| 200 return false; | 217 return false; |
| 201 } | 218 } |
| 202 | 219 |
| 203 DriveFileSyncService::DriveFileSyncService(Profile* profile) | 220 DriveFileSyncService::DriveFileSyncService(Profile* profile) |
| 204 : last_operation_status_(fileapi::SYNC_STATUS_OK), | 221 : last_operation_status_(fileapi::SYNC_STATUS_OK), |
| 205 state_(REMOTE_SERVICE_OK), | 222 state_(REMOTE_SERVICE_OK), |
| 206 largest_changestamp_(0), | 223 largest_fetched_changestamp_(0), |
| 224 polling_delay_seconds_(kMinimumPollingDelaySeconds), | |
| 225 polling_enabled_(true), | |
| 207 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 226 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 208 temporary_file_dir_ = | 227 temporary_file_dir_ = |
| 209 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); | 228 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); |
| 210 token_.reset(new TaskToken(AsWeakPtr())); | 229 token_.reset(new TaskToken(AsWeakPtr())); |
| 211 | 230 |
| 212 sync_client_.reset(new DriveFileSyncClient(profile)); | 231 sync_client_.reset(new DriveFileSyncClient(profile)); |
| 213 | 232 |
| 214 metadata_store_.reset(new DriveMetadataStore( | 233 metadata_store_.reset(new DriveMetadataStore( |
| 215 profile->GetPath().Append(kSyncFileSystemDir), | 234 profile->GetPath().Append(kSyncFileSystemDir), |
| 216 content::BrowserThread::GetMessageLoopProxyForThread( | 235 content::BrowserThread::GetMessageLoopProxyForThread( |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 509 callback, fileapi::SYNC_STATUS_FAILED); | 528 callback, fileapi::SYNC_STATUS_FAILED); |
| 510 } | 529 } |
| 511 | 530 |
| 512 // Called by CreateForTesting. | 531 // Called by CreateForTesting. |
| 513 DriveFileSyncService::DriveFileSyncService( | 532 DriveFileSyncService::DriveFileSyncService( |
| 514 const FilePath& base_dir, | 533 const FilePath& base_dir, |
| 515 scoped_ptr<DriveFileSyncClient> sync_client, | 534 scoped_ptr<DriveFileSyncClient> sync_client, |
| 516 scoped_ptr<DriveMetadataStore> metadata_store) | 535 scoped_ptr<DriveMetadataStore> metadata_store) |
| 517 : last_operation_status_(fileapi::SYNC_STATUS_OK), | 536 : last_operation_status_(fileapi::SYNC_STATUS_OK), |
| 518 state_(REMOTE_SERVICE_OK), | 537 state_(REMOTE_SERVICE_OK), |
| 519 largest_changestamp_(0), | 538 largest_fetched_changestamp_(0), |
| 539 polling_enabled_(false), | |
| 520 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 540 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 521 temporary_file_dir_ = base_dir.Append(kTempDirName); | 541 temporary_file_dir_ = base_dir.Append(kTempDirName); |
| 522 | 542 |
| 523 token_.reset(new TaskToken(AsWeakPtr())); | 543 token_.reset(new TaskToken(AsWeakPtr())); |
| 524 sync_client_ = sync_client.Pass(); | 544 sync_client_ = sync_client.Pass(); |
| 525 metadata_store_ = metadata_store.Pass(); | 545 metadata_store_ = metadata_store.Pass(); |
| 526 | 546 |
| 527 DidInitializeMetadataStore( | 547 DidInitializeMetadataStore( |
| 528 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"), | 548 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"), |
| 529 fileapi::SYNC_STATUS_OK, false); | 549 fileapi::SYNC_STATUS_OK, false); |
| 530 } | 550 } |
| 531 | 551 |
| 532 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken( | 552 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken( |
| 533 const tracked_objects::Location& from_here, | 553 const tracked_objects::Location& from_here, |
| 534 TaskType task_type, | 554 TaskType task_type, |
| 535 const std::string& description) { | 555 const std::string& description) { |
| 536 if (!token_) | 556 if (!token_) |
| 537 return scoped_ptr<TaskToken>(); | 557 return scoped_ptr<TaskToken>(); |
| 538 token_->UpdateTask(from_here, task_type, description); | 558 token_->UpdateTask(from_here, task_type, description); |
| 539 return token_.Pass(); | 559 return token_.Pass(); |
| 540 } | 560 } |
| 541 | 561 |
| 542 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, | 562 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, |
| 543 scoped_ptr<TaskToken> token) { | 563 scoped_ptr<TaskToken> token) { |
| 544 DCHECK(token); | 564 DCHECK(token); |
| 545 last_operation_status_ = status; | 565 last_operation_status_ = status; |
| 546 token_ = token.Pass(); | 566 token_ = token.Pass(); |
| 547 | 567 |
| 548 RemoteServiceState old_state = state_; | |
| 549 if (token_->task_type() != TASK_TYPE_NONE) { | 568 if (token_->task_type() != TASK_TYPE_NONE) { |
| 550 DVLOG(1) << "NotifyTaskDone: " << token_->description() | 569 DVLOG(1) << "NotifyTaskDone: " << token_->description() |
| 551 << ": finished with status=" << status | 570 << ": finished with status=" << status |
| 552 << " " << token_->location().ToString(); | 571 << " " << token_->location().ToString(); |
| 553 | 572 |
| 554 RemoteServiceState old_state = state_; | 573 RemoteServiceState old_state = state_; |
| 555 UpdateServiceState(); | 574 UpdateServiceState(); |
| 556 | 575 |
| 557 // Notify remote sync service state if the state has been changed. | 576 // Notify remote sync service state if the state has been changed. |
| 558 if (!token_->description().empty() || old_state != state_) { | 577 if (!token_->description().empty() || old_state != state_) { |
| 559 FOR_EACH_OBSERVER( | 578 FOR_EACH_OBSERVER( |
| 560 Observer, observers_, | 579 Observer, observers_, |
| 561 OnRemoteServiceStateUpdated(state_, token_->done_description())); | 580 OnRemoteServiceStateUpdated(state_, token_->done_description())); |
| 562 } | 581 } |
| 563 } | 582 } |
| 564 | 583 |
| 584 if (!token_->callback().is_null()) | |
| 585 token_->callback().Run(); | |
| 586 | |
| 565 token_->ResetTask(FROM_HERE); | 587 token_->ResetTask(FROM_HERE); |
| 566 if (!pending_tasks_.empty()) { | 588 if (!pending_tasks_.empty()) { |
| 567 base::Closure closure = pending_tasks_.front(); | 589 base::Closure closure = pending_tasks_.front(); |
| 568 pending_tasks_.pop_front(); | 590 pending_tasks_.pop_front(); |
| 569 closure.Run(); | 591 closure.Run(); |
| 570 return; | 592 return; |
| 571 } | 593 } |
| 572 | 594 |
| 573 if (state_ != REMOTE_SERVICE_OK || old_state == state_) | 595 SchedulePolling(); |
| 596 | |
| 597 if (state_ != REMOTE_SERVICE_OK) | |
| 574 return; | 598 return; |
| 575 | 599 |
| 576 // If the state has become OK and we have any pending batch sync origins | 600 // If the state has become OK and we have any pending batch sync origins |
| 577 // restart batch sync for them. | 601 // restart batch sync for them. |
| 578 if (!pending_batch_sync_origins_.empty()) { | 602 if (!pending_batch_sync_origins_.empty()) { |
| 579 GURL origin = *pending_batch_sync_origins_.begin(); | 603 GURL origin = *pending_batch_sync_origins_.begin(); |
| 580 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); | 604 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); |
| 581 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); | 605 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); |
| 582 StartBatchSyncForOrigin(origin, resource_id); | 606 StartBatchSyncForOrigin(origin, resource_id); |
| 607 return; | |
| 583 } | 608 } |
| 609 | |
| 610 // Notify observer of the update of |pending_changes_|. | |
| 611 FOR_EACH_OBSERVER(Observer, observers_, | |
| 612 OnRemoteChangeQueueUpdated(pending_changes_.size())); | |
| 584 } | 613 } |
| 585 | 614 |
| 586 void DriveFileSyncService::UpdateServiceState() { | 615 void DriveFileSyncService::UpdateServiceState() { |
| 587 switch (last_operation_status_) { | 616 switch (last_operation_status_) { |
| 588 // Possible regular operation errors. | 617 // Possible regular operation errors. |
| 589 case fileapi::SYNC_STATUS_OK: | 618 case fileapi::SYNC_STATUS_OK: |
| 590 case fileapi::SYNC_STATUS_FILE_BUSY: | 619 case fileapi::SYNC_STATUS_FILE_BUSY: |
| 591 case fileapi::SYNC_STATUS_HAS_CONFLICT: | 620 case fileapi::SYNC_STATUS_HAS_CONFLICT: |
| 592 case fileapi::SYNC_STATUS_NO_CONFLICT: | 621 case fileapi::SYNC_STATUS_NO_CONFLICT: |
| 593 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC: | 622 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC: |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 | 664 |
| 636 void DriveFileSyncService::DidInitializeMetadataStore( | 665 void DriveFileSyncService::DidInitializeMetadataStore( |
| 637 scoped_ptr<TaskToken> token, | 666 scoped_ptr<TaskToken> token, |
| 638 fileapi::SyncStatusCode status, | 667 fileapi::SyncStatusCode status, |
| 639 bool created) { | 668 bool created) { |
| 640 if (status != fileapi::SYNC_STATUS_OK) { | 669 if (status != fileapi::SYNC_STATUS_OK) { |
| 641 NotifyTaskDone(status, token.Pass()); | 670 NotifyTaskDone(status, token.Pass()); |
| 642 return; | 671 return; |
| 643 } | 672 } |
| 644 | 673 |
| 674 largest_fetched_changestamp_ = metadata_store_->GetLargestChangeStamp(); | |
| 675 | |
| 645 if (metadata_store_->sync_root_directory().empty()) { | 676 if (metadata_store_->sync_root_directory().empty()) { |
| 646 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback)); | 677 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback)); |
| 647 return; | 678 return; |
| 648 } | 679 } |
| 649 | 680 |
| 650 NotifyTaskDone(status, token.Pass()); | 681 NotifyTaskDone(status, token.Pass()); |
| 651 | 682 |
| 652 for (std::map<GURL, std::string>::const_iterator itr = | 683 for (std::map<GURL, std::string>::const_iterator itr = |
| 653 metadata_store_->batch_sync_origins().begin(); | 684 metadata_store_->batch_sync_origins().begin(); |
| 654 itr != metadata_store_->batch_sync_origins().end(); | 685 itr != metadata_store_->batch_sync_origins().end(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 const std::string& resource_id, | 776 const std::string& resource_id, |
| 746 google_apis::GDataErrorCode error, | 777 google_apis::GDataErrorCode error, |
| 747 int64 largest_changestamp) { | 778 int64 largest_changestamp) { |
| 748 if (error != google_apis::HTTP_SUCCESS) { | 779 if (error != google_apis::HTTP_SUCCESS) { |
| 749 pending_batch_sync_origins_.insert(origin); | 780 pending_batch_sync_origins_.insert(origin); |
| 750 // TODO(tzik): Refine this error code. | 781 // TODO(tzik): Refine this error code. |
| 751 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | 782 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); |
| 752 return; | 783 return; |
| 753 } | 784 } |
| 754 | 785 |
| 786 if (metadata_store_->incremental_sync_origins().empty()) { | |
| 787 largest_fetched_changestamp_ = largest_changestamp; | |
| 788 metadata_store_->SetLargestChangeStamp( | |
| 789 largest_changestamp, | |
| 790 base::Bind(&EmptyStatusCallback)); | |
| 791 } | |
| 792 | |
| 755 DCHECK(token); | 793 DCHECK(token); |
| 756 token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving remote files"); | 794 token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving remote files"); |
| 757 sync_client_->ListFiles( | 795 sync_client_->ListFiles( |
| 758 resource_id, | 796 resource_id, |
| 759 base::Bind( | 797 base::Bind( |
| 760 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, | 798 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, |
| 761 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); | 799 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); |
| 762 } | 800 } |
| 763 | 801 |
| 764 void DriveFileSyncService::DidGetDirectoryContentForBatchSync( | 802 void DriveFileSyncService::DidGetDirectoryContentForBatchSync( |
| 765 scoped_ptr<TaskToken> token, | 803 scoped_ptr<TaskToken> token, |
| 766 const GURL& origin, | 804 const GURL& origin, |
| 767 int64 largest_changestamp, | 805 int64 largest_changestamp, |
| 768 google_apis::GDataErrorCode error, | 806 google_apis::GDataErrorCode error, |
| 769 scoped_ptr<google_apis::DocumentFeed> feed) { | 807 scoped_ptr<google_apis::DocumentFeed> feed) { |
| 770 if (error != google_apis::HTTP_SUCCESS) { | 808 if (error != google_apis::HTTP_SUCCESS) { |
| 771 pending_batch_sync_origins_.insert(origin); | 809 pending_batch_sync_origins_.insert(origin); |
| 772 // TODO(tzik): Refine this error code. | 810 // TODO(tzik): Refine this error code. |
| 773 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | 811 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); |
| 774 return; | 812 return; |
| 775 } | 813 } |
| 776 | 814 |
| 777 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; | 815 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; |
| 778 for (iterator itr = feed->entries().begin(); | 816 for (iterator itr = feed->entries().begin(); |
| 779 itr != feed->entries().end(); ++itr) { | 817 itr != feed->entries().end(); ++itr) { |
| 780 AppendNewRemoteChange(origin, *itr, largest_changestamp, | 818 AppendNewRemoteChange(origin, **itr, largest_changestamp, |
| 781 REMOTE_SYNC_TYPE_BATCH); | 819 REMOTE_SYNC_TYPE_BATCH); |
| 782 } | 820 } |
| 783 | 821 |
| 784 GURL next_feed_url; | 822 GURL next_feed_url; |
| 785 if (feed->GetNextFeedURL(&next_feed_url)) { | 823 if (feed->GetNextFeedURL(&next_feed_url)) { |
| 786 sync_client_->ContinueListing( | 824 sync_client_->ContinueListing( |
| 787 next_feed_url, | 825 next_feed_url, |
| 788 base::Bind( | 826 base::Bind( |
| 789 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, | 827 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, |
| 790 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); | 828 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 875 return SYNC_OPERATION_FAILED; | 913 return SYNC_OPERATION_FAILED; |
| 876 } | 914 } |
| 877 | 915 |
| 878 void DriveFileSyncService::DidApplyLocalChange( | 916 void DriveFileSyncService::DidApplyLocalChange( |
| 879 scoped_ptr<TaskToken> token, | 917 scoped_ptr<TaskToken> token, |
| 880 const fileapi::FileSystemURL& url, | 918 const fileapi::FileSystemURL& url, |
| 881 const google_apis::GDataErrorCode error, | 919 const google_apis::GDataErrorCode error, |
| 882 const fileapi::SyncStatusCallback& callback, | 920 const fileapi::SyncStatusCallback& callback, |
| 883 fileapi::SyncStatusCode status) { | 921 fileapi::SyncStatusCode status) { |
| 884 if (status == fileapi::SYNC_STATUS_OK) { | 922 if (status == fileapi::SYNC_STATUS_OK) { |
| 885 CancelRemoteChange(url); | 923 RemoveRemoteChange(url); |
| 886 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | 924 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); |
| 887 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); | 925 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); |
| 888 return; | 926 return; |
| 889 } | 927 } |
| 890 NotifyTaskDone(status, token.Pass()); | 928 NotifyTaskDone(status, token.Pass()); |
| 891 callback.Run(status); | 929 callback.Run(status); |
| 892 } | 930 } |
| 893 | 931 |
| 894 void DriveFileSyncService::DidUploadNewFile( | 932 void DriveFileSyncService::DidUploadNewFile( |
| 895 scoped_ptr<TaskToken> token, | 933 scoped_ptr<TaskToken> token, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1010 const DriveMetadata& drive_metadata = param->drive_metadata; | 1048 const DriveMetadata& drive_metadata = param->drive_metadata; |
| 1011 | 1049 |
| 1012 status = metadata_store_->ReadEntry(param->remote_change.url, | 1050 status = metadata_store_->ReadEntry(param->remote_change.url, |
| 1013 ¶m->drive_metadata); | 1051 ¶m->drive_metadata); |
| 1014 DCHECK(status == fileapi::SYNC_STATUS_OK || | 1052 DCHECK(status == fileapi::SYNC_STATUS_OK || |
| 1015 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND); | 1053 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND); |
| 1016 | 1054 |
| 1017 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK); | 1055 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK); |
| 1018 if (missing_db_entry) { | 1056 if (missing_db_entry) { |
| 1019 param->drive_metadata.set_resource_id(param->remote_change.resource_id); | 1057 param->drive_metadata.set_resource_id(param->remote_change.resource_id); |
| 1058 param->drive_metadata.set_md5_checksum(std::string()); | |
| 1020 param->drive_metadata.set_conflicted(false); | 1059 param->drive_metadata.set_conflicted(false); |
| 1021 } | 1060 } |
| 1022 bool missing_local_file = | 1061 bool missing_local_file = |
| 1023 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN); | 1062 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN); |
| 1024 | 1063 |
| 1025 if (param->drive_metadata.conflicted()) { | 1064 if (param->drive_metadata.conflicted()) { |
| 1026 if (missing_local_file) { | 1065 if (missing_local_file) { |
| 1027 if (param->remote_change.change.IsAddOrUpdate()) { | 1066 if (param->remote_change.change.IsAddOrUpdate()) { |
| 1028 NOTIMPLEMENTED() << "ResolveToRemote()"; | 1067 NOTIMPLEMENTED() << "ResolveToRemote()"; |
| 1029 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED); | 1068 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1089 | 1128 |
| 1090 DCHECK(param->remote_change.change.IsDelete()); | 1129 DCHECK(param->remote_change.change.IsDelete()); |
| 1091 if (local_changes.empty()) { | 1130 if (local_changes.empty()) { |
| 1092 if (missing_local_file) { | 1131 if (missing_local_file) { |
| 1093 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1132 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
| 1094 DeleteMetadataForRemoteSync(param.Pass()); | 1133 DeleteMetadataForRemoteSync(param.Pass()); |
| 1095 return; | 1134 return; |
| 1096 } | 1135 } |
| 1097 DCHECK(!missing_local_file); | 1136 DCHECK(!missing_local_file); |
| 1098 param->operation_type = fileapi::SYNC_OPERATION_DELETE; | 1137 param->operation_type = fileapi::SYNC_OPERATION_DELETE; |
| 1138 | |
| 1139 const fileapi::FileChange& file_change = param->remote_change.change; | |
| 1099 param->processor->ApplyRemoteChange( | 1140 param->processor->ApplyRemoteChange( |
| 1100 param->remote_change.change, FilePath(), url, | 1141 file_change, FilePath(), url, |
| 1101 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(), | 1142 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(), |
| 1102 base::Passed(¶m))); | 1143 base::Passed(¶m))); |
| 1103 return; | 1144 return; |
| 1104 } | 1145 } |
| 1105 | 1146 |
| 1106 DCHECK(!local_changes.empty()); | 1147 DCHECK(!local_changes.empty()); |
| 1107 if (local_changes.list().back().IsAddOrUpdate()) { | 1148 if (local_changes.list().back().IsAddOrUpdate()) { |
| 1108 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1149 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
| 1109 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); | 1150 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); |
| 1110 return; | 1151 return; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1129 } | 1170 } |
| 1130 | 1171 |
| 1131 void DriveFileSyncService::DidGetTemporaryFileForDownload( | 1172 void DriveFileSyncService::DidGetTemporaryFileForDownload( |
| 1132 scoped_ptr<ProcessRemoteChangeParam> param, | 1173 scoped_ptr<ProcessRemoteChangeParam> param, |
| 1133 bool success) { | 1174 bool success) { |
| 1134 if (!success) { | 1175 if (!success) { |
| 1135 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED); | 1176 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED); |
| 1136 return; | 1177 return; |
| 1137 } | 1178 } |
| 1138 | 1179 |
| 1139 DriveMetadata metadata; | |
| 1140 metadata_store_->ReadEntry(param->remote_change.url, &metadata); | |
| 1141 | |
| 1142 const FilePath& temporary_file_path = param->temporary_file_path; | 1180 const FilePath& temporary_file_path = param->temporary_file_path; |
| 1143 std::string resource_id = param->remote_change.resource_id; | 1181 std::string resource_id = param->remote_change.resource_id; |
| 1182 const DriveMetadata& drive_metadata = param->drive_metadata; | |
| 1144 sync_client_->DownloadFile( | 1183 sync_client_->DownloadFile( |
| 1145 resource_id, metadata.md5_checksum(), | 1184 resource_id, drive_metadata.md5_checksum(), |
| 1146 temporary_file_path, | 1185 temporary_file_path, |
| 1147 base::Bind(&DriveFileSyncService::DidDownloadFile, | 1186 base::Bind(&DriveFileSyncService::DidDownloadFile, |
| 1148 AsWeakPtr(), base::Passed(¶m))); | 1187 AsWeakPtr(), base::Passed(¶m))); |
| 1149 } | 1188 } |
| 1150 | 1189 |
| 1151 void DriveFileSyncService::DidDownloadFile( | 1190 void DriveFileSyncService::DidDownloadFile( |
| 1152 scoped_ptr<ProcessRemoteChangeParam> param, | 1191 scoped_ptr<ProcessRemoteChangeParam> param, |
| 1153 google_apis::GDataErrorCode error, | 1192 google_apis::GDataErrorCode error, |
| 1154 const std::string& md5_checksum) { | 1193 const std::string& md5_checksum) { |
| 1155 if (error == google_apis::HTTP_NOT_MODIFIED) { | 1194 if (error == google_apis::HTTP_NOT_MODIFIED) { |
| 1156 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1195 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
| 1157 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); | 1196 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); |
| 1158 return; | 1197 return; |
| 1159 } | 1198 } |
| 1160 | 1199 |
| 1161 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCodeWrapper(error); | 1200 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCodeWrapper(error); |
| 1162 if (status != fileapi::SYNC_STATUS_OK) { | 1201 if (status != fileapi::SYNC_STATUS_OK) { |
| 1163 AbortRemoteSync(param.Pass(), status); | 1202 AbortRemoteSync(param.Pass(), status); |
| 1164 return; | 1203 return; |
| 1165 } | 1204 } |
| 1166 | 1205 |
| 1167 param->md5_checksum = md5_checksum; | 1206 param->drive_metadata.set_md5_checksum(md5_checksum); |
| 1168 const fileapi::FileChange& change = param->remote_change.change; | 1207 const fileapi::FileChange& change = param->remote_change.change; |
| 1169 const FilePath& temporary_file_path = param->temporary_file_path; | 1208 const FilePath& temporary_file_path = param->temporary_file_path; |
| 1170 const fileapi::FileSystemURL& url = param->remote_change.url; | 1209 const fileapi::FileSystemURL& url = param->remote_change.url; |
| 1171 param->processor->ApplyRemoteChange( | 1210 param->processor->ApplyRemoteChange( |
| 1172 change, temporary_file_path, url, | 1211 change, temporary_file_path, url, |
| 1173 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, | 1212 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, |
| 1174 AsWeakPtr(), base::Passed(¶m))); | 1213 AsWeakPtr(), base::Passed(¶m))); |
| 1175 } | 1214 } |
| 1176 | 1215 |
| 1177 void DriveFileSyncService::DidApplyRemoteChange( | 1216 void DriveFileSyncService::DidApplyRemoteChange( |
| 1178 scoped_ptr<ProcessRemoteChangeParam> param, | 1217 scoped_ptr<ProcessRemoteChangeParam> param, |
| 1179 fileapi::SyncStatusCode status) { | 1218 fileapi::SyncStatusCode status) { |
| 1180 if (status != fileapi::SYNC_STATUS_OK) { | 1219 if (status != fileapi::SYNC_STATUS_OK) { |
| 1181 AbortRemoteSync(param.Pass(), status); | 1220 AbortRemoteSync(param.Pass(), status); |
| 1182 return; | 1221 return; |
| 1183 } | 1222 } |
| 1184 | 1223 |
| 1185 fileapi::FileSystemURL url = param->remote_change.url; | 1224 fileapi::FileSystemURL url = param->remote_change.url; |
| 1186 if (param->remote_change.change.IsDelete()) { | 1225 if (param->remote_change.change.IsDelete()) { |
| 1187 DeleteMetadataForRemoteSync(param.Pass()); | 1226 DeleteMetadataForRemoteSync(param.Pass()); |
| 1188 return; | 1227 return; |
| 1189 } | 1228 } |
| 1190 | 1229 |
| 1191 DriveMetadata metadata; | 1230 const DriveMetadata& drive_metadata = param->drive_metadata; |
| 1192 metadata.set_resource_id(param->remote_change.resource_id); | 1231 param->drive_metadata.set_resource_id(param->remote_change.resource_id); |
| 1193 metadata.set_md5_checksum(param->md5_checksum); | 1232 param->drive_metadata.set_conflicted(false); |
| 1194 metadata.set_conflicted(false); | |
| 1195 | 1233 |
| 1196 metadata_store_->UpdateEntry( | 1234 metadata_store_->UpdateEntry( |
| 1197 url, metadata, | 1235 url, drive_metadata, |
| 1198 base::Bind(&DriveFileSyncService::CompleteRemoteSync, | 1236 base::Bind(&DriveFileSyncService::CompleteRemoteSync, |
| 1199 AsWeakPtr(), base::Passed(¶m))); | 1237 AsWeakPtr(), base::Passed(¶m))); |
| 1200 } | 1238 } |
| 1201 | 1239 |
| 1202 void DriveFileSyncService::DeleteMetadataForRemoteSync( | 1240 void DriveFileSyncService::DeleteMetadataForRemoteSync( |
| 1203 scoped_ptr<ProcessRemoteChangeParam> param) { | 1241 scoped_ptr<ProcessRemoteChangeParam> param) { |
| 1204 fileapi::FileSystemURL url = param->remote_change.url; | 1242 fileapi::FileSystemURL url = param->remote_change.url; |
| 1205 metadata_store_->DeleteEntry( | 1243 metadata_store_->DeleteEntry( |
| 1206 url, | 1244 url, |
| 1207 base::Bind(&DriveFileSyncService::CompleteRemoteSync, | 1245 base::Bind(&DriveFileSyncService::CompleteRemoteSync, |
| 1208 AsWeakPtr(), base::Passed(¶m))); | 1246 AsWeakPtr(), base::Passed(¶m))); |
| 1209 } | 1247 } |
| 1210 | 1248 |
| 1211 void DriveFileSyncService::CompleteRemoteSync( | 1249 void DriveFileSyncService::CompleteRemoteSync( |
| 1212 scoped_ptr<ProcessRemoteChangeParam> param, | 1250 scoped_ptr<ProcessRemoteChangeParam> param, |
| 1213 fileapi::SyncStatusCode status) { | 1251 fileapi::SyncStatusCode status) { |
| 1214 if (status != fileapi::SYNC_STATUS_OK) { | 1252 if (status != fileapi::SYNC_STATUS_OK) { |
| 1215 AbortRemoteSync(param.Pass(), status); | 1253 AbortRemoteSync(param.Pass(), status); |
| 1216 return; | 1254 return; |
| 1217 } | 1255 } |
| 1218 | 1256 |
| 1219 CancelRemoteChange(param->remote_change.url); | 1257 RemoveRemoteChange(param->remote_change.url); |
| 1220 | 1258 |
| 1221 GURL origin = param->remote_change.url.origin(); | 1259 GURL origin = param->remote_change.url.origin(); |
| 1222 if (metadata_store_->IsIncrementalSyncOrigin(origin)) { | 1260 if (metadata_store_->IsIncrementalSyncOrigin(origin)) { |
| 1223 int64 changestamp = param->remote_change.changestamp; | 1261 int64 changestamp = param->remote_change.changestamp; |
| 1224 metadata_store_->SetLargestChangeStamp( | 1262 metadata_store_->SetLargestChangeStamp( |
| 1225 changestamp, | 1263 changestamp, |
| 1226 base::Bind(&DriveFileSyncService::FinalizeRemoteSync, | 1264 base::Bind(&DriveFileSyncService::FinalizeRemoteSync, |
| 1227 AsWeakPtr(), base::Passed(¶m))); | 1265 AsWeakPtr(), base::Passed(¶m))); |
| 1228 return; | 1266 return; |
| 1229 } | 1267 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1250 param->callback.Run(status, param->remote_change.url, | 1288 param->callback.Run(status, param->remote_change.url, |
| 1251 param->operation_type); | 1289 param->operation_type); |
| 1252 } else { | 1290 } else { |
| 1253 param->callback.Run(status, param->remote_change.url, | 1291 param->callback.Run(status, param->remote_change.url, |
| 1254 fileapi::SYNC_OPERATION_NONE); | 1292 fileapi::SYNC_OPERATION_NONE); |
| 1255 } | 1293 } |
| 1256 } | 1294 } |
| 1257 | 1295 |
| 1258 void DriveFileSyncService::AppendNewRemoteChange( | 1296 void DriveFileSyncService::AppendNewRemoteChange( |
| 1259 const GURL& origin, | 1297 const GURL& origin, |
| 1260 google_apis::DocumentEntry* entry, | 1298 const google_apis::DocumentEntry& entry, |
| 1261 int64 changestamp, | 1299 int64 changestamp, |
| 1262 RemoteSyncType sync_type) { | 1300 RemoteSyncType sync_type) { |
| 1263 // TODO(tzik): Normalize the path here. | 1301 // TODO(tzik): Normalize the path here. |
| 1264 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry->title())); | 1302 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry.title())); |
| 1265 | 1303 |
| 1266 PathToChange* path_to_change = &url_to_change_[origin]; | 1304 PathToChange* path_to_change = &url_to_change_[origin]; |
| 1267 PathToChange::iterator found = path_to_change->find(path); | 1305 PathToChange::iterator found = path_to_change->find(path); |
| 1268 if (found != path_to_change->end()) { | 1306 if (found != path_to_change->end()) { |
| 1269 if (found->second.changestamp >= changestamp) | 1307 if (found->second.changestamp >= changestamp) |
| 1270 return; | 1308 return; |
| 1271 pending_changes_.erase(found->second.position_in_queue); | 1309 pending_changes_.erase(found->second.position_in_queue); |
| 1272 } | 1310 } |
| 1273 | 1311 |
| 1274 fileapi::FileSystemURL url( | 1312 fileapi::FileSystemURL url( |
| 1275 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path)); | 1313 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path)); |
| 1276 | 1314 |
| 1277 fileapi::FileChange::ChangeType change_type; | 1315 fileapi::FileChange::ChangeType change_type; |
| 1278 fileapi::SyncFileType file_type; | 1316 fileapi::SyncFileType file_type; |
| 1279 if (entry->deleted()) { | 1317 if (entry.deleted()) { |
| 1280 change_type = fileapi::FileChange::FILE_CHANGE_DELETE; | 1318 change_type = fileapi::FileChange::FILE_CHANGE_DELETE; |
| 1281 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN; | 1319 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN; |
| 1282 } else { | 1320 } else { |
| 1283 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE; | 1321 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE; |
| 1284 if (entry->kind() == google_apis::ENTRY_KIND_FOLDER) | 1322 if (entry.is_folder()) |
| 1285 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY; | 1323 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY; |
| 1286 else | 1324 else |
| 1287 file_type = fileapi::SYNC_FILE_TYPE_FILE; | 1325 file_type = fileapi::SYNC_FILE_TYPE_FILE; |
| 1288 } | 1326 } |
| 1289 | 1327 |
| 1290 fileapi::FileChange file_change(change_type, file_type); | 1328 fileapi::FileChange file_change(change_type, file_type); |
| 1291 | 1329 |
| 1292 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = | 1330 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = |
| 1293 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url)); | 1331 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url)); |
| 1294 DCHECK(inserted_to_queue.second); | 1332 DCHECK(inserted_to_queue.second); |
| 1295 | 1333 |
| 1296 (*path_to_change)[path] = RemoteChange( | 1334 (*path_to_change)[path] = RemoteChange( |
| 1297 changestamp, entry->resource_id(), url, file_change, | 1335 changestamp, entry.resource_id(), url, file_change, |
| 1298 inserted_to_queue.first); | 1336 inserted_to_queue.first); |
| 1299 } | 1337 } |
| 1300 | 1338 |
| 1301 void DriveFileSyncService::CancelRemoteChange( | 1339 void DriveFileSyncService::RemoveRemoteChange( |
| 1302 const fileapi::FileSystemURL& url) { | 1340 const fileapi::FileSystemURL& url) { |
| 1303 URLToChange::iterator found_origin = url_to_change_.find(url.origin()); | 1341 URLToChange::iterator found_origin = url_to_change_.find(url.origin()); |
| 1304 if (found_origin == url_to_change_.end()) | 1342 if (found_origin == url_to_change_.end()) |
| 1305 return; | 1343 return; |
| 1306 | 1344 |
| 1307 PathToChange* path_to_change = &found_origin->second; | 1345 PathToChange* path_to_change = &found_origin->second; |
| 1308 PathToChange::iterator found_change = path_to_change->find(url.path()); | 1346 PathToChange::iterator found_change = path_to_change->find(url.path()); |
| 1309 if (found_change == path_to_change->end()) | 1347 if (found_change == path_to_change->end()) |
| 1310 return; | 1348 return; |
| 1311 | 1349 |
| 1312 pending_changes_.erase(found_change->second.position_in_queue); | 1350 pending_changes_.erase(found_change->second.position_in_queue); |
| 1313 path_to_change->erase(found_change); | 1351 path_to_change->erase(found_change); |
| 1314 if (path_to_change->empty()) | 1352 if (path_to_change->empty()) |
| 1315 url_to_change_.erase(found_origin); | 1353 url_to_change_.erase(found_origin); |
| 1316 | 1354 |
| 1317 MaybeMarkAsIncrementalSyncOrigin(url.origin()); | 1355 if (metadata_store_->IsBatchSyncOrigin(url.origin()) && |
| 1318 } | 1356 !ContainsKey(url_to_change_, url.origin())) { |
| 1319 | 1357 metadata_store_->MoveBatchSyncOriginToIncremental(url.origin()); |
| 1320 void DriveFileSyncService::MaybeMarkAsIncrementalSyncOrigin( | 1358 } |
| 1321 const GURL& origin) { | |
| 1322 if (metadata_store_->IsBatchSyncOrigin(origin) && | |
| 1323 !ContainsKey(url_to_change_, origin)) | |
| 1324 metadata_store_->MoveBatchSyncOriginToIncremental(origin); | |
| 1325 } | 1359 } |
| 1326 | 1360 |
| 1327 bool DriveFileSyncService::GetPendingChangeForFileSystemURL( | 1361 bool DriveFileSyncService::GetPendingChangeForFileSystemURL( |
| 1328 const fileapi::FileSystemURL& url, | 1362 const fileapi::FileSystemURL& url, |
| 1329 RemoteChange* change) const { | 1363 RemoteChange* change) const { |
| 1330 DCHECK(change); | 1364 DCHECK(change); |
| 1331 URLToChange::const_iterator found_url = url_to_change_.find(url.origin()); | 1365 URLToChange::const_iterator found_url = url_to_change_.find(url.origin()); |
| 1332 if (found_url == url_to_change_.end()) | 1366 if (found_url == url_to_change_.end()) |
| 1333 return false; | 1367 return false; |
| 1334 const PathToChange& path_to_change = found_url->second; | 1368 const PathToChange& path_to_change = found_url->second; |
| 1335 PathToChange::const_iterator found_path = path_to_change.find(url.path()); | 1369 PathToChange::const_iterator found_path = path_to_change.find(url.path()); |
| 1336 if (found_path == path_to_change.end()) | 1370 if (found_path == path_to_change.end()) |
| 1337 return false; | 1371 return false; |
| 1338 *change = found_path->second; | 1372 *change = found_path->second; |
| 1339 return true; | 1373 return true; |
| 1340 } | 1374 } |
| 1341 | 1375 |
| 1376 void DriveFileSyncService::FetchChangesForIncrementalSync() { | |
| 1377 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE, | |
| 1378 "Fetching remote change list")); | |
| 1379 if (!token) { | |
| 1380 pending_tasks_.push_back(base::Bind( | |
| 1381 &DriveFileSyncService::FetchChangesForIncrementalSync, AsWeakPtr())); | |
| 1382 return; | |
| 1383 } | |
| 1384 | |
| 1385 polling_enabled_ = false; | |
| 1386 token->set_callback(base::Bind(&EnablePolling, &polling_enabled_)); | |
| 1387 | |
| 1388 if (metadata_store_->incremental_sync_origins().empty()) { | |
| 1389 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | |
| 1390 return; | |
| 1391 } | |
| 1392 | |
| 1393 sync_client_->ListChanges( | |
| 1394 largest_fetched_changestamp_, | |
| 1395 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, | |
| 1396 AsWeakPtr(), base::Passed(&token))); | |
| 1397 } | |
| 1398 | |
| 1399 void DriveFileSyncService::DidFetchChangesForIncrementalSync( | |
| 1400 scoped_ptr<TaskToken> token, | |
| 1401 google_apis::GDataErrorCode error, | |
| 1402 scoped_ptr<google_apis::DocumentFeed> changes) { | |
| 1403 if (error != google_apis::HTTP_SUCCESS) { | |
| 1404 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | |
| 1405 return; | |
| 1406 } | |
| 1407 | |
| 1408 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; | |
| 1409 for (iterator itr = changes->entries().begin(); | |
| 1410 itr != changes->entries().end(); ++itr) { | |
| 1411 const google_apis::DocumentEntry& entry = **itr; | |
| 1412 GURL origin; | |
| 1413 if (!GetOriginForEntry(entry, &origin)) | |
| 1414 continue; | |
| 1415 | |
| 1416 AppendNewRemoteChange(origin, entry, entry.changestamp(), | |
| 1417 REMOTE_SYNC_TYPE_INCREMENTAL); | |
| 1418 } | |
| 1419 | |
| 1420 GURL next_feed; | |
| 1421 if (changes->GetNextFeedURL(&next_feed)) { | |
| 1422 sync_client_->ContinueListing( | |
| 1423 next_feed, | |
| 1424 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, | |
| 1425 AsWeakPtr(), base::Passed(&token))); | |
| 1426 return; | |
| 1427 } | |
| 1428 | |
| 1429 largest_fetched_changestamp_ = changes->largest_changestamp(); | |
| 1430 | |
| 1431 if (changes->start_index() == 0 && changes->entries().empty()) { | |
| 1432 // If this set of changes is the first feed and it's empty, update | |
| 1433 // the polling delay to wait longer. | |
| 1434 polling_delay_seconds_ = std::min( | |
| 1435 static_cast<int64>(kDelayMultiplier * polling_delay_seconds_), | |
| 1436 kMaximumPollingDelaySeconds); | |
| 1437 } else { | |
| 1438 polling_delay_seconds_ = kMinimumPollingDelaySeconds; | |
| 1439 } | |
| 1440 | |
| 1441 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | |
| 1442 } | |
| 1443 | |
| 1444 bool DriveFileSyncService::GetOriginForEntry( | |
| 1445 const google_apis::DocumentEntry& entry, | |
| 1446 GURL* origin_out) { | |
| 1447 typedef ScopedVector<google_apis::Link>::const_iterator iterator; | |
| 1448 for (iterator itr = entry.links().begin(); | |
| 1449 itr != entry.links().end(); ++itr) { | |
| 1450 if ((*itr)->type() != google_apis::Link::LINK_PARENT) | |
| 1451 continue; | |
| 1452 GURL origin(UTF16ToUTF8((*itr)->title())); | |
| 1453 if (!origin.is_valid()) | |
| 1454 continue; | |
| 1455 | |
| 1456 if (!metadata_store_->IsBatchSyncOrigin(origin) && | |
| 1457 !metadata_store_->IsIncrementalSyncOrigin(origin)) | |
| 1458 continue; | |
| 1459 std::string resource_id(metadata_store_->GetResourceIdForOrigin(origin)); | |
| 1460 GURL resource_link(sync_client_->ResourceIdToResourceLink(resource_id)); | |
| 1461 if ((*itr)->href().GetOrigin() != resource_link.GetOrigin() || | |
| 1462 (*itr)->href().path() != resource_link.path()) | |
| 1463 continue; | |
| 1464 | |
| 1465 *origin_out = origin; | |
| 1466 return true; | |
| 1467 } | |
| 1468 return false; | |
| 1469 } | |
| 1470 | |
| 1471 void DriveFileSyncService::SchedulePolling() { | |
| 1472 if (!pending_batch_sync_origins_.empty() || | |
| 1473 metadata_store_->incremental_sync_origins().empty() || | |
| 1474 !pending_changes_.empty() || | |
| 1475 !polling_enabled_ || | |
| 1476 polling_timer_.IsRunning()) | |
| 1477 return; | |
| 1478 | |
| 1479 if (state_ != REMOTE_SERVICE_OK && | |
| 1480 state_ != REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) | |
| 1481 return; | |
| 1482 | |
| 1483 if (state_ == REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) | |
| 1484 polling_delay_seconds_ = kMaximumPollingDelaySeconds; | |
| 1485 | |
| 1486 DVLOG(1) << "Polling scheduled" | |
| 1487 << " (delay:" << polling_delay_seconds_ << "s)"; | |
| 1488 | |
| 1489 polling_timer_.Start( | |
| 1490 FROM_HERE, base::TimeDelta::FromSeconds(polling_delay_seconds_), | |
| 1491 base::Bind(&DriveFileSyncService::FetchChangesForIncrementalSync, | |
| 1492 AsWeakPtr())); | |
| 1493 } | |
| 1494 | |
| 1342 fileapi::SyncStatusCode | 1495 fileapi::SyncStatusCode |
| 1343 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( | 1496 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( |
| 1344 google_apis::GDataErrorCode error) const { | 1497 google_apis::GDataErrorCode error) const { |
| 1345 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); | 1498 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); |
| 1346 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) | 1499 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) |
| 1347 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; | 1500 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; |
| 1348 return status; | 1501 return status; |
| 1349 } | 1502 } |
| 1350 | 1503 |
| 1351 } // namespace sync_file_system | 1504 } // namespace sync_file_system |
| OLD | NEW |