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