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 |