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 <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 return; | 69 return; |
70 } | 70 } |
71 | 71 |
72 if (!file_util::Delete(file_path, true)) | 72 if (!file_util::Delete(file_path, true)) |
73 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: " | 73 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: " |
74 << file_path.value(); | 74 << file_path.value(); |
75 } | 75 } |
76 | 76 |
77 void EmptyStatusCallback(fileapi::SyncStatusCode code) {} | 77 void EmptyStatusCallback(fileapi::SyncStatusCode code) {} |
78 | 78 |
79 void MarkFetchingChangesCompleted(bool* is_fetching_changes) { | |
80 *is_fetching_changes = false; | |
81 } | |
82 | |
83 void DidRemoveOrigin(const GURL& origin, fileapi::SyncStatusCode status) { | 79 void DidRemoveOrigin(const GURL& origin, fileapi::SyncStatusCode status) { |
84 // TODO(calvinlo): Disable syncing if status not ok (http://crbug.com/171611). | 80 // TODO(calvinlo): Disable syncing if status not ok (http://crbug.com/171611). |
85 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); | 81 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); |
86 LOG(WARNING) << "Remove origin failed for: " << origin.spec() | 82 LOG(WARNING) << "Remove origin failed for: " << origin.spec() |
87 << " status=" << status; | 83 << " status=" << status; |
88 } | 84 } |
89 | 85 |
90 fileapi::FileChange CreateFileChange(bool is_deleted) { | 86 fileapi::FileChange CreateFileChange(bool is_deleted) { |
91 if (is_deleted) { | 87 if (is_deleted) { |
92 return fileapi::FileChange(fileapi::FileChange::FILE_CHANGE_DELETE, | 88 return fileapi::FileChange(fileapi::FileChange::FILE_CHANGE_DELETE, |
(...skipping 11 matching lines...) Expand all Loading... |
104 public: | 100 public: |
105 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service) | 101 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service) |
106 : sync_service_(sync_service), | 102 : sync_service_(sync_service), |
107 task_type_(TASK_TYPE_NONE) { | 103 task_type_(TASK_TYPE_NONE) { |
108 } | 104 } |
109 | 105 |
110 void ResetTask(const tracked_objects::Location& location) { | 106 void ResetTask(const tracked_objects::Location& location) { |
111 location_ = location; | 107 location_ = location; |
112 task_type_ = TASK_TYPE_NONE; | 108 task_type_ = TASK_TYPE_NONE; |
113 description_.clear(); | 109 description_.clear(); |
114 if (!completion_callback_.is_null()) | |
115 completion_callback_.Run(); | |
116 completion_callback_.Reset(); | |
117 } | 110 } |
118 | 111 |
119 void UpdateTask(const tracked_objects::Location& location, | 112 void UpdateTask(const tracked_objects::Location& location, |
120 TaskType task_type, | 113 TaskType task_type, |
121 const std::string& description) { | 114 const std::string& description) { |
122 location_ = location; | 115 location_ = location; |
123 task_type_ = task_type; | 116 task_type_ = task_type; |
124 description_ = description; | 117 description_ = description; |
125 | 118 |
126 DVLOG(2) << "Token updated: " << description_ | 119 DVLOG(2) << "Token updated: " << description_ |
127 << " " << location_.ToString(); | 120 << " " << location_.ToString(); |
128 } | 121 } |
129 | 122 |
130 const tracked_objects::Location& location() const { return location_; } | 123 const tracked_objects::Location& location() const { return location_; } |
131 TaskType task_type() const { return task_type_; } | 124 TaskType task_type() const { return task_type_; } |
132 const std::string& description() const { return description_; } | 125 const std::string& description() const { return description_; } |
133 std::string done_description() const { return description_ + " done"; } | 126 std::string done_description() const { return description_ + " done"; } |
134 | 127 |
135 void set_completion_callback(const base::Closure& callback) { | |
136 completion_callback_ = callback; | |
137 } | |
138 | |
139 const base::Closure& completion_callback() { | |
140 return completion_callback_; | |
141 } | |
142 | |
143 ~TaskToken() { | 128 ~TaskToken() { |
144 // All task on DriveFileSyncService must hold TaskToken instance to ensure | 129 // All task on DriveFileSyncService must hold TaskToken instance to ensure |
145 // no other tasks are running. Also, as soon as a task finishes to work, | 130 // no other tasks are running. Also, as soon as a task finishes to work, |
146 // it must return the token to DriveFileSyncService. | 131 // it must return the token to DriveFileSyncService. |
147 // Destroying a token with valid |sync_service_| indicates the token was | 132 // Destroying a token with valid |sync_service_| indicates the token was |
148 // dropped by a task without returning. | 133 // dropped by a task without returning. |
149 if (sync_service_) { | 134 if (sync_service_) { |
150 LOG(ERROR) << "Unexpected TaskToken deletion from: " | 135 LOG(ERROR) << "Unexpected TaskToken deletion from: " |
151 << location_.ToString() << " while: " << description_; | 136 << location_.ToString() << " while: " << description_; |
152 } | 137 } |
153 DCHECK(!sync_service_); | 138 DCHECK(!sync_service_); |
154 } | 139 } |
155 | 140 |
156 private: | 141 private: |
157 base::WeakPtr<DriveFileSyncService> sync_service_; | 142 base::WeakPtr<DriveFileSyncService> sync_service_; |
158 tracked_objects::Location location_; | 143 tracked_objects::Location location_; |
159 TaskType task_type_; | 144 TaskType task_type_; |
160 std::string description_; | 145 std::string description_; |
161 base::Closure completion_callback_; | |
162 | 146 |
163 DISALLOW_COPY_AND_ASSIGN(TaskToken); | 147 DISALLOW_COPY_AND_ASSIGN(TaskToken); |
164 }; | 148 }; |
165 | 149 |
166 void DriveFileSyncService::OnInvalidatorStateChange( | 150 void DriveFileSyncService::OnInvalidatorStateChange( |
167 syncer::InvalidatorState state) { | 151 syncer::InvalidatorState state) { |
168 SetPushNotificationEnabled(state); | 152 SetPushNotificationEnabled(state); |
169 } | 153 } |
170 | 154 |
171 void DriveFileSyncService::SetPushNotificationEnabled( | 155 void DriveFileSyncService::SetPushNotificationEnabled( |
172 syncer::InvalidatorState state) { | 156 syncer::InvalidatorState state) { |
173 push_notification_enabled_ = (state == syncer::INVALIDATIONS_ENABLED); | 157 push_notification_enabled_ = (state == syncer::INVALIDATIONS_ENABLED); |
174 if (!push_notification_enabled_) | 158 if (!push_notification_enabled_) |
175 return; | 159 return; |
176 | 160 |
177 // Push notifications are enabled so reset polling timer. | 161 // Push notifications are enabled so reset polling timer. |
178 UpdatePollingDelay(kPollingDelaySecondsWithNotification); | 162 UpdatePollingDelay(kPollingDelaySecondsWithNotification); |
179 } | 163 } |
180 | 164 |
181 void DriveFileSyncService::OnIncomingInvalidation( | 165 void DriveFileSyncService::OnIncomingInvalidation( |
182 const syncer::ObjectIdInvalidationMap& invalidation_map) { | 166 const syncer::ObjectIdInvalidationMap& invalidation_map) { |
183 DCHECK(push_notification_enabled_); | 167 DCHECK(push_notification_enabled_); |
184 DCHECK_EQ(1U, invalidation_map.size()); | 168 DCHECK_EQ(1U, invalidation_map.size()); |
185 const invalidation::ObjectId object_id( | 169 const invalidation::ObjectId object_id( |
186 ipc::invalidation::ObjectSource::COSMO_CHANGELOG, | 170 ipc::invalidation::ObjectSource::COSMO_CHANGELOG, |
187 kDriveInvalidationObjectId); | 171 kDriveInvalidationObjectId); |
188 DCHECK_EQ(1U, invalidation_map.count(object_id)); | 172 DCHECK_EQ(1U, invalidation_map.count(object_id)); |
189 | 173 |
190 FetchChangesForIncrementalSync(); | 174 may_have_unfetched_changes_ = true; |
| 175 MaybeStartFetchChanges(); |
191 } | 176 } |
192 | 177 |
193 struct DriveFileSyncService::ProcessRemoteChangeParam { | 178 struct DriveFileSyncService::ProcessRemoteChangeParam { |
194 scoped_ptr<TaskToken> token; | 179 scoped_ptr<TaskToken> token; |
195 RemoteChangeProcessor* processor; | 180 RemoteChangeProcessor* processor; |
196 RemoteChange remote_change; | 181 RemoteChange remote_change; |
197 fileapi::SyncFileCallback callback; | 182 fileapi::SyncFileCallback callback; |
198 | 183 |
199 DriveMetadata drive_metadata; | 184 DriveMetadata drive_metadata; |
200 bool metadata_updated; | 185 bool metadata_updated; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 | 266 |
282 DriveFileSyncService::DriveFileSyncService(Profile* profile) | 267 DriveFileSyncService::DriveFileSyncService(Profile* profile) |
283 : profile_(profile), | 268 : profile_(profile), |
284 last_operation_status_(fileapi::SYNC_STATUS_OK), | 269 last_operation_status_(fileapi::SYNC_STATUS_OK), |
285 state_(REMOTE_SERVICE_OK), | 270 state_(REMOTE_SERVICE_OK), |
286 sync_enabled_(true), | 271 sync_enabled_(true), |
287 largest_fetched_changestamp_(0), | 272 largest_fetched_changestamp_(0), |
288 push_notification_registered_(false), | 273 push_notification_registered_(false), |
289 push_notification_enabled_(false), | 274 push_notification_enabled_(false), |
290 polling_delay_seconds_(kMinimumPollingDelaySeconds), | 275 polling_delay_seconds_(kMinimumPollingDelaySeconds), |
291 is_fetching_changes_(false), | 276 may_have_unfetched_changes_(true), |
292 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 277 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
293 temporary_file_dir_ = | 278 temporary_file_dir_ = |
294 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); | 279 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); |
295 token_.reset(new TaskToken(AsWeakPtr())); | 280 token_.reset(new TaskToken(AsWeakPtr())); |
296 | 281 |
297 sync_client_.reset(new DriveFileSyncClient(profile)); | 282 sync_client_.reset(new DriveFileSyncClient(profile)); |
298 sync_client_->AddObserver(this); | 283 sync_client_->AddObserver(this); |
299 | 284 |
300 metadata_store_.reset(new DriveMetadataStore( | 285 metadata_store_.reset(new DriveMetadataStore( |
301 profile->GetPath().Append(kSyncFileSystemDir), | 286 profile->GetPath().Append(kSyncFileSystemDir), |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 return; | 394 return; |
410 } | 395 } |
411 | 396 |
412 OriginToChangesMap::iterator found = origin_to_changes_map_.find(origin); | 397 OriginToChangesMap::iterator found = origin_to_changes_map_.find(origin); |
413 if (found != origin_to_changes_map_.end()) { | 398 if (found != origin_to_changes_map_.end()) { |
414 for (PathToChangeMap::iterator itr = found->second.begin(); | 399 for (PathToChangeMap::iterator itr = found->second.begin(); |
415 itr != found->second.end(); ++itr) | 400 itr != found->second.end(); ++itr) |
416 pending_changes_.erase(itr->second.position_in_queue); | 401 pending_changes_.erase(itr->second.position_in_queue); |
417 origin_to_changes_map_.erase(found); | 402 origin_to_changes_map_.erase(found); |
418 } | 403 } |
| 404 pending_batch_sync_origins_.erase(origin); |
419 | 405 |
420 metadata_store_->RemoveOrigin(origin, base::Bind( | 406 metadata_store_->RemoveOrigin(origin, base::Bind( |
421 &DriveFileSyncService::DidRemoveOriginOnMetadataStore, | 407 &DriveFileSyncService::DidRemoveOriginOnMetadataStore, |
422 AsWeakPtr(), base::Passed(&token), callback)); | 408 AsWeakPtr(), base::Passed(&token), callback)); |
423 } | 409 } |
424 | 410 |
425 void DriveFileSyncService::ProcessRemoteChange( | 411 void DriveFileSyncService::ProcessRemoteChange( |
426 RemoteChangeProcessor* processor, | 412 RemoteChangeProcessor* processor, |
427 const fileapi::SyncFileCallback& callback) { | 413 const fileapi::SyncFileCallback& callback) { |
428 scoped_ptr<TaskToken> token( | 414 scoped_ptr<TaskToken> token( |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 if (state_ == REMOTE_SERVICE_OK) | 656 if (state_ == REMOTE_SERVICE_OK) |
671 return; | 657 return; |
672 DVLOG(1) << "OnAuthenticated"; | 658 DVLOG(1) << "OnAuthenticated"; |
673 state_ = REMOTE_SERVICE_OK; | 659 state_ = REMOTE_SERVICE_OK; |
674 if (GetCurrentState() != REMOTE_SERVICE_OK) | 660 if (GetCurrentState() != REMOTE_SERVICE_OK) |
675 return; | 661 return; |
676 FOR_EACH_OBSERVER( | 662 FOR_EACH_OBSERVER( |
677 Observer, service_observers_, | 663 Observer, service_observers_, |
678 OnRemoteServiceStateUpdated(GetCurrentState(), "Authenticated")); | 664 OnRemoteServiceStateUpdated(GetCurrentState(), "Authenticated")); |
679 UpdatePollingDelay(kMinimumPollingDelaySeconds); | 665 UpdatePollingDelay(kMinimumPollingDelaySeconds); |
680 SchedulePolling(); | 666 |
| 667 may_have_unfetched_changes_ = true; |
| 668 MaybeStartFetchChanges(); |
681 } | 669 } |
682 | 670 |
683 void DriveFileSyncService::OnNetworkConnected() { | 671 void DriveFileSyncService::OnNetworkConnected() { |
684 if (state_ == REMOTE_SERVICE_OK) | 672 if (state_ == REMOTE_SERVICE_OK) |
685 return; | 673 return; |
686 DVLOG(1) << "OnNetworkConnected"; | 674 DVLOG(1) << "OnNetworkConnected"; |
687 state_ = REMOTE_SERVICE_OK; | 675 state_ = REMOTE_SERVICE_OK; |
688 if (GetCurrentState() != REMOTE_SERVICE_OK) | 676 if (GetCurrentState() != REMOTE_SERVICE_OK) |
689 return; | 677 return; |
690 FOR_EACH_OBSERVER( | 678 FOR_EACH_OBSERVER( |
691 Observer, service_observers_, | 679 Observer, service_observers_, |
692 OnRemoteServiceStateUpdated(GetCurrentState(), "Network connected")); | 680 OnRemoteServiceStateUpdated(GetCurrentState(), "Network connected")); |
693 UpdatePollingDelay(kMinimumPollingDelaySeconds); | 681 UpdatePollingDelay(kMinimumPollingDelaySeconds); |
694 SchedulePolling(); | 682 |
| 683 may_have_unfetched_changes_ = true; |
| 684 MaybeStartFetchChanges(); |
695 } | 685 } |
696 | 686 |
697 // Called by CreateForTesting. | 687 // Called by CreateForTesting. |
698 DriveFileSyncService::DriveFileSyncService( | 688 DriveFileSyncService::DriveFileSyncService( |
699 Profile* profile, | 689 Profile* profile, |
700 const base::FilePath& base_dir, | 690 const base::FilePath& base_dir, |
701 scoped_ptr<DriveFileSyncClient> sync_client, | 691 scoped_ptr<DriveFileSyncClient> sync_client, |
702 scoped_ptr<DriveMetadataStore> metadata_store) | 692 scoped_ptr<DriveMetadataStore> metadata_store) |
703 : profile_(profile), | 693 : profile_(profile), |
704 last_operation_status_(fileapi::SYNC_STATUS_OK), | 694 last_operation_status_(fileapi::SYNC_STATUS_OK), |
705 state_(REMOTE_SERVICE_OK), | 695 state_(REMOTE_SERVICE_OK), |
706 sync_enabled_(true), | 696 sync_enabled_(true), |
707 largest_fetched_changestamp_(0), | 697 largest_fetched_changestamp_(0), |
708 push_notification_registered_(false), | 698 push_notification_registered_(false), |
709 push_notification_enabled_(false), | 699 push_notification_enabled_(false), |
710 polling_delay_seconds_(-1), | 700 polling_delay_seconds_(-1), |
711 is_fetching_changes_(false), | 701 may_have_unfetched_changes_(false), |
712 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 702 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
713 DCHECK(profile); | 703 DCHECK(profile); |
714 temporary_file_dir_ = base_dir.Append(kTempDirName); | 704 temporary_file_dir_ = base_dir.Append(kTempDirName); |
715 | 705 |
716 token_.reset(new TaskToken(AsWeakPtr())); | 706 token_.reset(new TaskToken(AsWeakPtr())); |
717 sync_client_ = sync_client.Pass(); | 707 sync_client_ = sync_client.Pass(); |
718 metadata_store_ = metadata_store.Pass(); | 708 metadata_store_ = metadata_store.Pass(); |
719 | 709 |
720 base::MessageLoopProxy::current()->PostTask( | 710 base::MessageLoopProxy::current()->PostTask( |
721 FROM_HERE, | 711 FROM_HERE, |
(...skipping 16 matching lines...) Expand all Loading... |
738 return token_.Pass(); | 728 return token_.Pass(); |
739 } | 729 } |
740 | 730 |
741 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, | 731 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, |
742 scoped_ptr<TaskToken> token) { | 732 scoped_ptr<TaskToken> token) { |
743 DCHECK(token); | 733 DCHECK(token); |
744 last_operation_status_ = status; | 734 last_operation_status_ = status; |
745 token_ = token.Pass(); | 735 token_ = token.Pass(); |
746 TRACE_EVENT_ASYNC_END0("Sync FileSystem", "GetToken", this); | 736 TRACE_EVENT_ASYNC_END0("Sync FileSystem", "GetToken", this); |
747 | 737 |
748 | |
749 if (token_->task_type() != TASK_TYPE_NONE) { | 738 if (token_->task_type() != TASK_TYPE_NONE) { |
750 DVLOG(2) << "NotifyTaskDone: " << token_->description() | 739 DVLOG(2) << "NotifyTaskDone: " << token_->description() |
751 << ": finished with status=" << status | 740 << ": finished with status=" << status |
752 << " (" << SyncStatusCodeToString(status) << ")" | 741 << " (" << SyncStatusCodeToString(status) << ")" |
753 << " " << token_->location().ToString(); | 742 << " " << token_->location().ToString(); |
754 | 743 |
755 RemoteServiceState old_state = GetCurrentState(); | 744 RemoteServiceState old_state = GetCurrentState(); |
756 UpdateServiceState(); | 745 UpdateServiceState(); |
757 | 746 |
758 // Reset the polling delay. This will adjust the polling timer | 747 // Reset the polling delay. This will adjust the polling timer |
759 // based on the current service state. | 748 // based on the current service state. |
760 UpdatePollingDelay(polling_delay_seconds_); | 749 UpdatePollingDelay(polling_delay_seconds_); |
761 | 750 |
762 // Notify remote sync service state if the state has been changed. | 751 // Notify remote sync service state if the state has been changed. |
763 if (!token_->description().empty() || old_state != GetCurrentState()) { | 752 if (!token_->description().empty() || old_state != GetCurrentState()) { |
764 FOR_EACH_OBSERVER( | 753 FOR_EACH_OBSERVER( |
765 Observer, service_observers_, | 754 Observer, service_observers_, |
766 OnRemoteServiceStateUpdated(GetCurrentState(), | 755 OnRemoteServiceStateUpdated(GetCurrentState(), |
767 token_->done_description())); | 756 token_->done_description())); |
768 } | 757 } |
769 } | 758 } |
770 | 759 |
771 if (!token_->completion_callback().is_null()) | |
772 token_->completion_callback().Run(); | |
773 | |
774 token_->ResetTask(FROM_HERE); | 760 token_->ResetTask(FROM_HERE); |
775 if (!pending_tasks_.empty()) { | 761 if (!pending_tasks_.empty()) { |
776 base::Closure closure = pending_tasks_.front(); | 762 base::Closure closure = pending_tasks_.front(); |
777 pending_tasks_.pop_front(); | 763 pending_tasks_.pop_front(); |
778 closure.Run(); | 764 closure.Run(); |
779 return; | 765 return; |
780 } | 766 } |
781 | 767 |
782 SchedulePolling(); | 768 if (GetCurrentState() == REMOTE_SERVICE_DISABLED) |
783 | |
784 if (GetCurrentState() != REMOTE_SERVICE_OK && | |
785 GetCurrentState() != REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) | |
786 return; | 769 return; |
787 | 770 |
788 // If the state has become OK or TEMPORARY_UNAVAILABLE and we have any | 771 MaybeStartFetchChanges(); |
789 // pending batch sync origins, restart batch sync for them. | 772 |
790 if (!pending_batch_sync_origins_.empty()) { | 773 SchedulePolling(); |
791 GURL origin = *pending_batch_sync_origins_.begin(); | |
792 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); | |
793 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); | |
794 StartBatchSyncForOrigin(origin, resource_id); | |
795 return; | |
796 } | |
797 | 774 |
798 // Notify observer of the update of |pending_changes_|. | 775 // Notify observer of the update of |pending_changes_|. |
799 FOR_EACH_OBSERVER(Observer, service_observers_, | 776 FOR_EACH_OBSERVER(Observer, service_observers_, |
800 OnRemoteChangeQueueUpdated(pending_changes_.size())); | 777 OnRemoteChangeQueueUpdated(pending_changes_.size())); |
801 } | 778 } |
802 | 779 |
803 void DriveFileSyncService::UpdateServiceState() { | 780 void DriveFileSyncService::UpdateServiceState() { |
804 switch (last_operation_status_) { | 781 switch (last_operation_status_) { |
805 // Possible regular operation errors. | 782 // Possible regular operation errors. |
806 case fileapi::SYNC_STATUS_OK: | 783 case fileapi::SYNC_STATUS_OK: |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 return; | 945 return; |
969 } | 946 } |
970 RegisterOriginForTrackingChanges(origin, callback); | 947 RegisterOriginForTrackingChanges(origin, callback); |
971 } | 948 } |
972 | 949 |
973 void DriveFileSyncService::StartBatchSyncForOrigin( | 950 void DriveFileSyncService::StartBatchSyncForOrigin( |
974 const GURL& origin, | 951 const GURL& origin, |
975 const std::string& resource_id) { | 952 const std::string& resource_id) { |
976 scoped_ptr<TaskToken> token( | 953 scoped_ptr<TaskToken> token( |
977 GetToken(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving largest changestamp")); | 954 GetToken(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving largest changestamp")); |
978 if (!token) { | 955 DCHECK(token); |
979 pending_batch_sync_origins_.insert(origin); | 956 DCHECK(GetCurrentState() == REMOTE_SERVICE_OK || may_have_unfetched_changes_); |
980 return; | 957 |
981 } | 958 DVLOG(1) << "Start batch sync for:" << origin.spec(); |
982 | 959 |
983 sync_client_->GetLargestChangeStamp( | 960 sync_client_->GetLargestChangeStamp( |
984 base::Bind(&DriveFileSyncService::DidGetLargestChangeStampForBatchSync, | 961 base::Bind(&DriveFileSyncService::DidGetLargestChangeStampForBatchSync, |
985 AsWeakPtr(), base::Passed(&token), origin, resource_id)); | 962 AsWeakPtr(), base::Passed(&token), origin, resource_id)); |
| 963 |
| 964 may_have_unfetched_changes_ = false; |
986 } | 965 } |
987 | 966 |
988 void DriveFileSyncService::DidGetDirectoryForOrigin( | 967 void DriveFileSyncService::DidGetDirectoryForOrigin( |
989 scoped_ptr<TaskToken> token, | 968 scoped_ptr<TaskToken> token, |
990 const GURL& origin, | 969 const GURL& origin, |
991 const fileapi::SyncStatusCallback& callback, | 970 const fileapi::SyncStatusCallback& callback, |
992 google_apis::GDataErrorCode error, | 971 google_apis::GDataErrorCode error, |
993 const std::string& resource_id) { | 972 const std::string& resource_id) { |
994 if (error != google_apis::HTTP_SUCCESS && | 973 if (error != google_apis::HTTP_SUCCESS && |
995 error != google_apis::HTTP_CREATED) { | 974 error != google_apis::HTTP_CREATED) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); | 1044 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); |
1066 return; | 1045 return; |
1067 } | 1046 } |
1068 | 1047 |
1069 // Move |origin| to the incremental sync origin set if the origin has no file. | 1048 // Move |origin| to the incremental sync origin set if the origin has no file. |
1070 if (metadata_store_->IsBatchSyncOrigin(origin) && | 1049 if (metadata_store_->IsBatchSyncOrigin(origin) && |
1071 !ContainsKey(origin_to_changes_map_, origin)) { | 1050 !ContainsKey(origin_to_changes_map_, origin)) { |
1072 metadata_store_->MoveBatchSyncOriginToIncremental(origin); | 1051 metadata_store_->MoveBatchSyncOriginToIncremental(origin); |
1073 } | 1052 } |
1074 | 1053 |
| 1054 // If this was the last batch sync origin and push_notification is enabled |
| 1055 // (indicates that we may have longer polling cycle), trigger the first |
| 1056 // incremental sync on next task cycle. |
| 1057 if (pending_batch_sync_origins_.empty() && |
| 1058 push_notification_enabled_) { |
| 1059 may_have_unfetched_changes_ = true; |
| 1060 } |
| 1061 |
1075 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | 1062 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); |
1076 } | 1063 } |
1077 | 1064 |
1078 void DriveFileSyncService::DidRemoveOriginOnMetadataStore( | 1065 void DriveFileSyncService::DidRemoveOriginOnMetadataStore( |
1079 scoped_ptr<TaskToken> token, | 1066 scoped_ptr<TaskToken> token, |
1080 const fileapi::SyncStatusCallback& callback, | 1067 const fileapi::SyncStatusCallback& callback, |
1081 fileapi::SyncStatusCode status) { | 1068 fileapi::SyncStatusCode status) { |
1082 NotifyTaskDone(status, token.Pass()); | 1069 NotifyTaskDone(status, token.Pass()); |
1083 callback.Run(status); | 1070 callback.Run(status); |
1084 } | 1071 } |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1830 if (found_url == origin_to_changes_map_.end()) | 1817 if (found_url == origin_to_changes_map_.end()) |
1831 return false; | 1818 return false; |
1832 const PathToChangeMap& path_to_change = found_url->second; | 1819 const PathToChangeMap& path_to_change = found_url->second; |
1833 PathToChangeMap::const_iterator found_path = path_to_change.find(url.path()); | 1820 PathToChangeMap::const_iterator found_path = path_to_change.find(url.path()); |
1834 if (found_path == path_to_change.end()) | 1821 if (found_path == path_to_change.end()) |
1835 return false; | 1822 return false; |
1836 *change = found_path->second; | 1823 *change = found_path->second; |
1837 return true; | 1824 return true; |
1838 } | 1825 } |
1839 | 1826 |
| 1827 void DriveFileSyncService::MaybeStartFetchChanges() { |
| 1828 if (!token_ || GetCurrentState() == REMOTE_SERVICE_DISABLED) { |
| 1829 // If another task is already running or the service is disabled |
| 1830 // just return here. |
| 1831 // Note that token_ should be already non-null if this is called |
| 1832 // from NotifyTaskDone(). |
| 1833 return; |
| 1834 } |
| 1835 |
| 1836 // If we have pending_batch_sync_origins, try starting the batch sync. |
| 1837 if (!pending_batch_sync_origins_.empty()) { |
| 1838 if (GetCurrentState() == REMOTE_SERVICE_OK || |
| 1839 may_have_unfetched_changes_) { |
| 1840 GURL origin = *pending_batch_sync_origins_.begin(); |
| 1841 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); |
| 1842 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); |
| 1843 StartBatchSyncForOrigin(origin, resource_id); |
| 1844 } |
| 1845 return; |
| 1846 } |
| 1847 |
| 1848 if (may_have_unfetched_changes_ && |
| 1849 !metadata_store_->incremental_sync_origins().empty() && |
| 1850 pending_changes_.empty()) { |
| 1851 FetchChangesForIncrementalSync(); |
| 1852 } |
| 1853 } |
| 1854 |
1840 void DriveFileSyncService::FetchChangesForIncrementalSync() { | 1855 void DriveFileSyncService::FetchChangesForIncrementalSync() { |
1841 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE, | 1856 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE, |
1842 "Fetching remote change list")); | 1857 "Fetching remote change list")); |
1843 // If we got |token| successfully, |is_fetching_changes_| should be false. | 1858 DCHECK(token); |
1844 // |is_fetching_changes_| is true only when the FetchChanges sequence is | 1859 DCHECK(may_have_unfetched_changes_); |
1845 // running or is in |pending_queue_|. In both case, the token is owned by | 1860 DCHECK(pending_batch_sync_origins_.empty()); |
1846 // the FetchChanges sequence. | 1861 DCHECK(!metadata_store_->incremental_sync_origins().empty()); |
1847 DCHECK(!token || !is_fetching_changes_); | 1862 DCHECK(pending_changes_.empty()); |
1848 | |
1849 if (!sync_enabled_ || | |
1850 is_fetching_changes_ || | |
1851 !pending_batch_sync_origins_.empty() || | |
1852 metadata_store_->incremental_sync_origins().empty() || | |
1853 !pending_changes_.empty()) { | |
1854 if (token) { | |
1855 token->ResetTask(FROM_HERE); | |
1856 NotifyTaskDone(last_operation_status_, token.Pass()); | |
1857 } | |
1858 return; | |
1859 } | |
1860 | |
1861 is_fetching_changes_ = true; | |
1862 | |
1863 if (!token) { | |
1864 pending_tasks_.push_back(base::Bind( | |
1865 &DriveFileSyncService::FetchChangesForIncrementalSync, AsWeakPtr())); | |
1866 return; | |
1867 } | |
1868 | |
1869 token->set_completion_callback( | |
1870 base::Bind(&MarkFetchingChangesCompleted, &is_fetching_changes_)); | |
1871 | |
1872 if (metadata_store_->incremental_sync_origins().empty()) { | |
1873 token->ResetTask(FROM_HERE); | |
1874 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | |
1875 return; | |
1876 } | |
1877 | 1863 |
1878 DVLOG(1) << "FetchChangesForIncrementalSync (start_changestamp:" | 1864 DVLOG(1) << "FetchChangesForIncrementalSync (start_changestamp:" |
1879 << (largest_fetched_changestamp_ + 1) << ")"; | 1865 << (largest_fetched_changestamp_ + 1) << ")"; |
1880 | 1866 |
1881 sync_client_->ListChanges( | 1867 sync_client_->ListChanges( |
1882 largest_fetched_changestamp_ + 1, | 1868 largest_fetched_changestamp_ + 1, |
1883 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, | 1869 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, |
1884 AsWeakPtr(), base::Passed(&token), false)); | 1870 AsWeakPtr(), base::Passed(&token), false)); |
| 1871 |
| 1872 may_have_unfetched_changes_ = false; |
1885 } | 1873 } |
1886 | 1874 |
1887 void DriveFileSyncService::DidFetchChangesForIncrementalSync( | 1875 void DriveFileSyncService::DidFetchChangesForIncrementalSync( |
1888 scoped_ptr<TaskToken> token, | 1876 scoped_ptr<TaskToken> token, |
1889 bool has_new_changes, | 1877 bool has_new_changes, |
1890 google_apis::GDataErrorCode error, | 1878 google_apis::GDataErrorCode error, |
1891 scoped_ptr<google_apis::ResourceList> changes) { | 1879 scoped_ptr<google_apis::ResourceList> changes) { |
1892 if (error != google_apis::HTTP_SUCCESS) { | 1880 if (error != google_apis::HTTP_SUCCESS) { |
1893 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | 1881 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); |
1894 return; | 1882 return; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1978 ids.insert(invalidation::ObjectId( | 1966 ids.insert(invalidation::ObjectId( |
1979 ipc::invalidation::ObjectSource::COSMO_CHANGELOG, | 1967 ipc::invalidation::ObjectSource::COSMO_CHANGELOG, |
1980 kDriveInvalidationObjectId)); | 1968 kDriveInvalidationObjectId)); |
1981 profile_sync_service->UpdateRegisteredInvalidationIds(this, ids); | 1969 profile_sync_service->UpdateRegisteredInvalidationIds(this, ids); |
1982 push_notification_registered_ = true; | 1970 push_notification_registered_ = true; |
1983 SetPushNotificationEnabled(profile_sync_service->GetInvalidatorState()); | 1971 SetPushNotificationEnabled(profile_sync_service->GetInvalidatorState()); |
1984 } | 1972 } |
1985 | 1973 |
1986 void DriveFileSyncService::SchedulePolling() { | 1974 void DriveFileSyncService::SchedulePolling() { |
1987 if (polling_timer_.IsRunning() || | 1975 if (polling_timer_.IsRunning() || |
1988 polling_delay_seconds_ < 0) | 1976 polling_delay_seconds_ < 0 || |
1989 return; | 1977 GetCurrentState() == REMOTE_SERVICE_DISABLED) |
1990 | |
1991 if (state_ != REMOTE_SERVICE_OK && | |
1992 state_ != REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) | |
1993 return; | 1978 return; |
1994 | 1979 |
1995 DVLOG(1) << "Polling scheduled" | 1980 DVLOG(1) << "Polling scheduled" |
1996 << " (delay:" << polling_delay_seconds_ << "s)"; | 1981 << " (delay:" << polling_delay_seconds_ << "s)"; |
1997 | 1982 |
1998 polling_timer_.Start( | 1983 polling_timer_.Start( |
1999 FROM_HERE, base::TimeDelta::FromSeconds(polling_delay_seconds_), | 1984 FROM_HERE, base::TimeDelta::FromSeconds(polling_delay_seconds_), |
2000 base::Bind(&DriveFileSyncService::FetchChangesForIncrementalSync, | 1985 base::Bind(&DriveFileSyncService::OnPollingTimerFired, AsWeakPtr())); |
2001 AsWeakPtr())); | 1986 } |
| 1987 |
| 1988 void DriveFileSyncService::OnPollingTimerFired() { |
| 1989 may_have_unfetched_changes_ = true; |
| 1990 MaybeStartFetchChanges(); |
2002 } | 1991 } |
2003 | 1992 |
2004 void DriveFileSyncService::UpdatePollingDelay(int64 new_delay_sec) { | 1993 void DriveFileSyncService::UpdatePollingDelay(int64 new_delay_sec) { |
2005 // polling_delay_seconds_ made negative to disable polling for testing. | 1994 // polling_delay_seconds_ made negative to disable polling for testing. |
2006 if (polling_delay_seconds_ < 0) | 1995 if (polling_delay_seconds_ < 0) |
2007 return; | 1996 return; |
2008 | 1997 |
2009 if (state_ == REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) { | 1998 if (state_ == REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) { |
2010 // If the service state is TEMPORARY_UNAVAILABLE, poll the service | 1999 // If the service state is TEMPORARY_UNAVAILABLE, poll the service |
2011 // with a modest duration (but more frequently than | 2000 // with a modest duration (but more frequently than |
(...skipping 21 matching lines...) Expand all Loading... |
2033 fileapi::SyncStatusCode | 2022 fileapi::SyncStatusCode |
2034 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( | 2023 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( |
2035 google_apis::GDataErrorCode error) const { | 2024 google_apis::GDataErrorCode error) const { |
2036 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); | 2025 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); |
2037 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) | 2026 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) |
2038 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; | 2027 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; |
2039 return status; | 2028 return status; |
2040 } | 2029 } |
2041 | 2030 |
2042 } // namespace sync_file_system | 2031 } // namespace sync_file_system |
OLD | NEW |