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/chromeos/drive/change_list_loader.h" | 5 #include "chrome/browser/chromeos/drive/change_list_loader.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 int64 start_change_id_; | 171 int64 start_change_id_; |
172 ScopedVector<ChangeList> change_lists_; | 172 ScopedVector<ChangeList> change_lists_; |
173 base::WeakPtrFactory<DeltaFeedFetcher> weak_ptr_factory_; | 173 base::WeakPtrFactory<DeltaFeedFetcher> weak_ptr_factory_; |
174 DISALLOW_COPY_AND_ASSIGN(DeltaFeedFetcher); | 174 DISALLOW_COPY_AND_ASSIGN(DeltaFeedFetcher); |
175 }; | 175 }; |
176 | 176 |
177 // Fetches the resource entries in the directory with |directory_resource_id|. | 177 // Fetches the resource entries in the directory with |directory_resource_id|. |
178 class FastFetchFeedFetcher : public ChangeListLoader::FeedFetcher { | 178 class FastFetchFeedFetcher : public ChangeListLoader::FeedFetcher { |
179 public: | 179 public: |
180 FastFetchFeedFetcher(JobScheduler* scheduler, | 180 FastFetchFeedFetcher(JobScheduler* scheduler, |
181 const std::string& directory_resource_id) | 181 const std::string& directory_resource_id, |
| 182 const std::string& root_folder_id) |
182 : scheduler_(scheduler), | 183 : scheduler_(scheduler), |
183 directory_resource_id_(directory_resource_id), | 184 directory_resource_id_(directory_resource_id), |
| 185 root_folder_id_(root_folder_id), |
184 weak_ptr_factory_(this) { | 186 weak_ptr_factory_(this) { |
185 } | 187 } |
186 | 188 |
187 virtual ~FastFetchFeedFetcher() { | 189 virtual ~FastFetchFeedFetcher() { |
188 } | 190 } |
189 | 191 |
190 virtual void Run(const FeedFetcherCallback& callback) OVERRIDE { | 192 virtual void Run(const FeedFetcherCallback& callback) OVERRIDE { |
191 scheduler_->GetResourceListInDirectory( | 193 if (util::IsDriveV2ApiEnabled() && root_folder_id_.empty()) { |
192 directory_resource_id_, | 194 // The root folder id is not available yet. Fetch from the server. |
| 195 scheduler_->GetAboutResource( |
| 196 base::Bind(&FastFetchFeedFetcher::RunAfterGetAboutResource, |
| 197 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 198 return; |
| 199 } |
| 200 |
| 201 StartGetResourceListInDirectory(callback); |
| 202 } |
| 203 |
| 204 private: |
| 205 void RunAfterGetAboutResource( |
| 206 const FeedFetcherCallback& callback, |
| 207 google_apis::GDataErrorCode status, |
| 208 scoped_ptr<google_apis::AboutResource> about_resource) { |
| 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 210 DCHECK(!callback.is_null()); |
| 211 |
| 212 FileError error = GDataToFileError(status); |
| 213 if (error != FILE_ERROR_OK) { |
| 214 callback.Run(error, ScopedVector<ChangeList>()); |
| 215 return; |
| 216 } |
| 217 |
| 218 root_folder_id_ = about_resource->root_folder_id(); |
| 219 StartGetResourceListInDirectory(callback); |
| 220 } |
| 221 |
| 222 void StartGetResourceListInDirectory(const FeedFetcherCallback& callback) { |
| 223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 224 DCHECK(!callback.is_null()); |
| 225 DCHECK(!directory_resource_id_.empty()); |
| 226 DCHECK(!util::IsDriveV2ApiEnabled() || !root_folder_id_.empty()); |
| 227 |
| 228 // We use WAPI's GetResourceListInDirectory even if Drive API v2 is |
| 229 // enabled. This is the short term work around of the performance |
| 230 // regression. |
| 231 |
| 232 std::string resource_id = directory_resource_id_; |
| 233 if (util::IsDriveV2ApiEnabled() && |
| 234 directory_resource_id_ == root_folder_id_) { |
| 235 // GData WAPI doesn't accept the root directory id which is used in Drive |
| 236 // API v2. So it is necessary to translate it here. |
| 237 resource_id = util::kWapiRootDirectoryResourceId; |
| 238 } |
| 239 |
| 240 scheduler_->GetResourceListInDirectoryByWapi( |
| 241 resource_id, |
193 base::Bind(&FastFetchFeedFetcher::OnFileListFetched, | 242 base::Bind(&FastFetchFeedFetcher::OnFileListFetched, |
194 weak_ptr_factory_.GetWeakPtr(), callback)); | 243 weak_ptr_factory_.GetWeakPtr(), callback)); |
195 } | 244 } |
196 | 245 |
197 private: | |
198 void OnFileListFetched( | 246 void OnFileListFetched( |
199 const FeedFetcherCallback& callback, | 247 const FeedFetcherCallback& callback, |
200 google_apis::GDataErrorCode status, | 248 google_apis::GDataErrorCode status, |
201 scoped_ptr<google_apis::ResourceList> resource_list) { | 249 scoped_ptr<google_apis::ResourceList> resource_list) { |
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
203 DCHECK(!callback.is_null()); | 251 DCHECK(!callback.is_null()); |
204 | 252 |
205 FileError error = GDataToFileError(status); | 253 FileError error = GDataToFileError(status); |
206 if (error != FILE_ERROR_OK) { | 254 if (error != FILE_ERROR_OK) { |
207 callback.Run(error, ScopedVector<ChangeList>()); | 255 callback.Run(error, ScopedVector<ChangeList>()); |
208 return; | 256 return; |
209 } | 257 } |
210 | 258 |
211 // Add the current change list to the list of collected lists. | 259 // Add the current change list to the list of collected lists. |
212 DCHECK(resource_list); | 260 DCHECK(resource_list); |
213 change_lists_.push_back(new ChangeList(*resource_list)); | 261 ChangeList* change_list = new ChangeList(*resource_list); |
| 262 if (util::IsDriveV2ApiEnabled()) |
| 263 FixResourceIdInChangeList(change_list); |
| 264 change_lists_.push_back(change_list); |
214 | 265 |
215 GURL next_url; | 266 GURL next_url; |
216 if (resource_list->GetNextFeedURL(&next_url) && !next_url.is_empty()) { | 267 if (resource_list->GetNextFeedURL(&next_url) && !next_url.is_empty()) { |
217 // There is the remaining result so fetch it. | 268 // There is the remaining result so fetch it. |
218 scheduler_->GetRemainingFileList( | 269 scheduler_->GetRemainingFileList( |
219 next_url, | 270 next_url, |
220 base::Bind(&FastFetchFeedFetcher::OnFileListFetched, | 271 base::Bind(&FastFetchFeedFetcher::OnFileListFetched, |
221 weak_ptr_factory_.GetWeakPtr(), callback)); | 272 weak_ptr_factory_.GetWeakPtr(), callback)); |
222 return; | 273 return; |
223 } | 274 } |
224 | 275 |
225 // Note: The fetcher is managed by ChangeListLoader, and the instance | 276 // Note: The fetcher is managed by ChangeListLoader, and the instance |
226 // will be deleted in the callback. Do not touch the fields after this | 277 // will be deleted in the callback. Do not touch the fields after this |
227 // invocation. | 278 // invocation. |
228 callback.Run(FILE_ERROR_OK, change_lists_.Pass()); | 279 callback.Run(FILE_ERROR_OK, change_lists_.Pass()); |
229 } | 280 } |
230 | 281 |
| 282 void FixResourceIdInChangeList(ChangeList* change_list) { |
| 283 std::vector<ResourceEntry>* entries = change_list->mutable_entries(); |
| 284 for (size_t i = 0; i < entries->size(); ++i) { |
| 285 ResourceEntry* entry = &(*entries)[i]; |
| 286 if (entry->has_resource_id()) { |
| 287 entry->set_resource_id(UpgradeResourceIdFromGDataWapiToDriveApiV2( |
| 288 entry->resource_id())); |
| 289 } |
| 290 |
| 291 // Currently parent local id is the parent's resource id. |
| 292 // It will be replaced by actual local id. (crbug.com/260514). |
| 293 if (entry->has_parent_local_id()) { |
| 294 entry->set_parent_local_id(UpgradeResourceIdFromGDataWapiToDriveApiV2( |
| 295 entry->parent_local_id())); |
| 296 } |
| 297 } |
| 298 } |
| 299 |
| 300 std::string UpgradeResourceIdFromGDataWapiToDriveApiV2( |
| 301 const std::string& resource_id) { |
| 302 if (resource_id == util::kWapiRootDirectoryResourceId) |
| 303 return root_folder_id_; |
| 304 return drive::util::CanonicalizeResourceId(resource_id); |
| 305 } |
| 306 |
231 JobScheduler* scheduler_; | 307 JobScheduler* scheduler_; |
232 std::string directory_resource_id_; | 308 std::string directory_resource_id_; |
| 309 std::string root_folder_id_; |
233 ScopedVector<ChangeList> change_lists_; | 310 ScopedVector<ChangeList> change_lists_; |
234 base::WeakPtrFactory<FastFetchFeedFetcher> weak_ptr_factory_; | 311 base::WeakPtrFactory<FastFetchFeedFetcher> weak_ptr_factory_; |
235 DISALLOW_COPY_AND_ASSIGN(FastFetchFeedFetcher); | 312 DISALLOW_COPY_AND_ASSIGN(FastFetchFeedFetcher); |
236 }; | 313 }; |
237 | 314 |
238 } // namespace | 315 } // namespace |
239 | 316 |
240 ChangeListLoader::ChangeListLoader( | 317 ChangeListLoader::ChangeListLoader( |
241 base::SequencedTaskRunner* blocking_task_runner, | 318 base::SequencedTaskRunner* blocking_task_runner, |
242 ResourceMetadata* resource_metadata, | 319 ResourceMetadata* resource_metadata, |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 int64 local_changestamp, | 551 int64 local_changestamp, |
475 google_apis::GDataErrorCode status, | 552 google_apis::GDataErrorCode status, |
476 scoped_ptr<google_apis::AboutResource> about_resource) { | 553 scoped_ptr<google_apis::AboutResource> about_resource) { |
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 554 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
478 DCHECK_EQ(GDataToFileError(status) == FILE_ERROR_OK, | 555 DCHECK_EQ(GDataToFileError(status) == FILE_ERROR_OK, |
479 about_resource.get() != NULL); | 556 about_resource.get() != NULL); |
480 | 557 |
481 if (GDataToFileError(status) == FILE_ERROR_OK) { | 558 if (GDataToFileError(status) == FILE_ERROR_OK) { |
482 DCHECK(about_resource); | 559 DCHECK(about_resource); |
483 last_known_remote_changestamp_ = about_resource->largest_change_id(); | 560 last_known_remote_changestamp_ = about_resource->largest_change_id(); |
| 561 root_folder_id_ = about_resource->root_folder_id(); |
484 } | 562 } |
485 | 563 |
486 int64 remote_changestamp = | 564 int64 remote_changestamp = |
487 about_resource ? about_resource->largest_change_id() : 0; | 565 about_resource ? about_resource->largest_change_id() : 0; |
488 if (remote_changestamp > 0 && local_changestamp >= remote_changestamp) { | 566 if (remote_changestamp > 0 && local_changestamp >= remote_changestamp) { |
489 if (local_changestamp > remote_changestamp) { | 567 if (local_changestamp > remote_changestamp) { |
490 LOG(WARNING) << "Local resource metadata is fresher than server, local = " | 568 LOG(WARNING) << "Local resource metadata is fresher than server, local = " |
491 << local_changestamp | 569 << local_changestamp |
492 << ", server = " | 570 << ", server = " |
493 << remote_changestamp; | 571 << remote_changestamp; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 } | 678 } |
601 | 679 |
602 void ChangeListLoader::LoadDirectoryFromServerAfterGetAbout( | 680 void ChangeListLoader::LoadDirectoryFromServerAfterGetAbout( |
603 const std::string& directory_resource_id, | 681 const std::string& directory_resource_id, |
604 const FileOperationCallback& callback, | 682 const FileOperationCallback& callback, |
605 google_apis::GDataErrorCode status, | 683 google_apis::GDataErrorCode status, |
606 scoped_ptr<google_apis::AboutResource> about_resource) { | 684 scoped_ptr<google_apis::AboutResource> about_resource) { |
607 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 685 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
608 DCHECK(!callback.is_null()); | 686 DCHECK(!callback.is_null()); |
609 | 687 |
610 if (GDataToFileError(status) == FILE_ERROR_OK) | 688 if (GDataToFileError(status) == FILE_ERROR_OK) { |
| 689 DCHECK(about_resource); |
611 last_known_remote_changestamp_ = about_resource->largest_change_id(); | 690 last_known_remote_changestamp_ = about_resource->largest_change_id(); |
| 691 root_folder_id_ = about_resource->root_folder_id(); |
| 692 } |
612 | 693 |
613 DoLoadDirectoryFromServer( | 694 DoLoadDirectoryFromServer( |
614 DirectoryFetchInfo(directory_resource_id, last_known_remote_changestamp_), | 695 DirectoryFetchInfo(directory_resource_id, last_known_remote_changestamp_), |
615 callback); | 696 callback); |
616 } | 697 } |
617 | 698 |
618 void ChangeListLoader::CheckChangestampAndLoadDirectoryIfNeeded( | 699 void ChangeListLoader::CheckChangestampAndLoadDirectoryIfNeeded( |
619 const DirectoryFetchInfo& directory_fetch_info, | 700 const DirectoryFetchInfo& directory_fetch_info, |
620 int64 local_changestamp, | 701 int64 local_changestamp, |
621 const FileOperationCallback& callback) { | 702 const FileOperationCallback& callback) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 &ChangeListLoader | 762 &ChangeListLoader |
682 ::DoLoadGrandRootDirectoryFromServerAfterGetResourceEntryByPath, | 763 ::DoLoadGrandRootDirectoryFromServerAfterGetResourceEntryByPath, |
683 weak_ptr_factory_.GetWeakPtr(), | 764 weak_ptr_factory_.GetWeakPtr(), |
684 directory_fetch_info, | 765 directory_fetch_info, |
685 callback)); | 766 callback)); |
686 return; | 767 return; |
687 } | 768 } |
688 | 769 |
689 FastFetchFeedFetcher* fetcher = new FastFetchFeedFetcher( | 770 FastFetchFeedFetcher* fetcher = new FastFetchFeedFetcher( |
690 scheduler_, | 771 scheduler_, |
691 directory_fetch_info.resource_id()); | 772 directory_fetch_info.resource_id(), |
| 773 root_folder_id_); |
692 fast_fetch_feed_fetcher_set_.insert(fetcher); | 774 fast_fetch_feed_fetcher_set_.insert(fetcher); |
693 fetcher->Run( | 775 fetcher->Run( |
694 base::Bind(&ChangeListLoader::DoLoadDirectoryFromServerAfterLoad, | 776 base::Bind(&ChangeListLoader::DoLoadDirectoryFromServerAfterLoad, |
695 weak_ptr_factory_.GetWeakPtr(), | 777 weak_ptr_factory_.GetWeakPtr(), |
696 directory_fetch_info, | 778 directory_fetch_info, |
697 callback, | 779 callback, |
698 fetcher)); | 780 fetcher)); |
699 } | 781 } |
700 | 782 |
701 void | 783 void |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 FOR_EACH_OBSERVER(ChangeListLoaderObserver, observers_, | 968 FOR_EACH_OBSERVER(ChangeListLoaderObserver, observers_, |
887 OnDirectoryChanged(*dir_iter)); | 969 OnDirectoryChanged(*dir_iter)); |
888 } | 970 } |
889 } | 971 } |
890 | 972 |
891 callback.Run(); | 973 callback.Run(); |
892 } | 974 } |
893 | 975 |
894 } // namespace internal | 976 } // namespace internal |
895 } // namespace drive | 977 } // namespace drive |
OLD | NEW |