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/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 173 } |
174 | 174 |
175 void ChangeListLoader::LoadFromServerIfNeededAfterGetAbout( | 175 void ChangeListLoader::LoadFromServerIfNeededAfterGetAbout( |
176 const DirectoryFetchInfo& directory_fetch_info, | 176 const DirectoryFetchInfo& directory_fetch_info, |
177 const FileOperationCallback& callback, | 177 const FileOperationCallback& callback, |
178 google_apis::GDataErrorCode status, | 178 google_apis::GDataErrorCode status, |
179 scoped_ptr<google_apis::AboutResource> about_resource) { | 179 scoped_ptr<google_apis::AboutResource> about_resource) { |
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
181 DCHECK(!callback.is_null()); | 181 DCHECK(!callback.is_null()); |
182 DCHECK(refreshing_); | 182 DCHECK(refreshing_); |
| 183 DCHECK_EQ(util::GDataToDriveFileError(status) == DRIVE_FILE_OK, |
| 184 about_resource.get() != NULL); |
183 | 185 |
184 int64 remote_changestamp = 0; | 186 int64 remote_changestamp = 0; |
185 if (util::GDataToDriveFileError(status) == DRIVE_FILE_OK) { | 187 if (util::GDataToDriveFileError(status) == DRIVE_FILE_OK) { |
186 DCHECK(about_resource); | 188 DCHECK(about_resource); |
187 remote_changestamp = about_resource->largest_change_id(); | 189 remote_changestamp = about_resource->largest_change_id(); |
188 last_known_remote_changestamp_ = remote_changestamp; | 190 last_known_remote_changestamp_ = remote_changestamp; |
189 } | 191 } |
190 | 192 |
191 resource_metadata_->GetLargestChangestamp( | 193 resource_metadata_->GetLargestChangestamp( |
192 base::Bind(&ChangeListLoader::CompareChangestampsAndLoadIfNeeded, | 194 base::Bind(&ChangeListLoader::CompareChangestampsAndLoadIfNeeded, |
193 weak_ptr_factory_.GetWeakPtr(), | 195 weak_ptr_factory_.GetWeakPtr(), |
194 directory_fetch_info, | 196 directory_fetch_info, |
195 callback, | 197 callback, |
196 remote_changestamp)); | 198 base::Passed(&about_resource))); |
197 } | 199 } |
198 | 200 |
199 void ChangeListLoader::CompareChangestampsAndLoadIfNeeded( | 201 void ChangeListLoader::CompareChangestampsAndLoadIfNeeded( |
200 const DirectoryFetchInfo& directory_fetch_info, | 202 const DirectoryFetchInfo& directory_fetch_info, |
201 const FileOperationCallback& callback, | 203 const FileOperationCallback& callback, |
202 int64 remote_changestamp, | 204 scoped_ptr<google_apis::AboutResource> about_resource, |
203 int64 local_changestamp) { | 205 int64 local_changestamp) { |
204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
205 DCHECK(!callback.is_null()); | 207 DCHECK(!callback.is_null()); |
206 DCHECK(refreshing_); | 208 DCHECK(refreshing_); |
207 | 209 |
| 210 int64 remote_changestamp = |
| 211 about_resource ? about_resource->largest_change_id() : 0; |
208 if (remote_changestamp > 0 && local_changestamp >= remote_changestamp) { | 212 if (remote_changestamp > 0 && local_changestamp >= remote_changestamp) { |
209 if (local_changestamp > remote_changestamp) { | 213 if (local_changestamp > remote_changestamp) { |
210 LOG(WARNING) << "Cached client feed is fresher than server, client = " | 214 LOG(WARNING) << "Cached client feed is fresher than server, client = " |
211 << local_changestamp | 215 << local_changestamp |
212 << ", server = " | 216 << ", server = " |
213 << remote_changestamp; | 217 << remote_changestamp; |
214 } | 218 } |
215 | 219 |
216 // No changes detected, tell the client that the loading was successful. | 220 // No changes detected, tell the client that the loading was successful. |
217 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); | 221 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); |
218 return; | 222 return; |
219 } | 223 } |
220 | 224 |
221 int64 start_changestamp = local_changestamp > 0 ? local_changestamp + 1 : 0; | 225 int64 start_changestamp = local_changestamp > 0 ? local_changestamp + 1 : 0; |
| 226 if (start_changestamp == 0 && !about_resource.get()) { |
| 227 // Full update needs AboutResource. If this is a full update, we should just |
| 228 // give up. |
| 229 callback.Run(DRIVE_FILE_ERROR_FAILED); |
| 230 return; |
| 231 } |
222 | 232 |
223 if (directory_fetch_info.empty()) { | 233 if (directory_fetch_info.empty()) { |
224 // If the caller is not interested in a particular directory, just start | 234 // If the caller is not interested in a particular directory, just start |
225 // loading the change list. | 235 // loading the change list. |
226 LoadChangeListFromServer(start_changestamp, | 236 LoadChangeListFromServer(about_resource.Pass(), |
227 remote_changestamp, | 237 start_changestamp, |
228 callback); | 238 callback); |
229 } else if (directory_fetch_info.changestamp() < remote_changestamp) { | 239 } else if (directory_fetch_info.changestamp() < remote_changestamp) { |
230 // If the caller is interested in a particular directory, and the | 240 // If the caller is interested in a particular directory, and the |
231 // directory changestamp is older than server's, start loading the | 241 // directory changestamp is older than server's, start loading the |
232 // directory first. | 242 // directory first. |
233 DVLOG(1) << "Fast-fetching directory: " << directory_fetch_info.ToString() | 243 DVLOG(1) << "Fast-fetching directory: " << directory_fetch_info.ToString() |
234 << "; remote_changestamp: " << remote_changestamp; | 244 << "; remote_changestamp: " << remote_changestamp; |
235 const DirectoryFetchInfo new_directory_fetch_info( | 245 const DirectoryFetchInfo new_directory_fetch_info( |
236 directory_fetch_info.resource_id(), remote_changestamp); | 246 directory_fetch_info.resource_id(), remote_changestamp); |
237 DoLoadDirectoryFromServer( | 247 DoLoadDirectoryFromServer( |
238 new_directory_fetch_info, | 248 new_directory_fetch_info, |
239 base::Bind(&ChangeListLoader::StartLoadChangeListFromServer, | 249 base::Bind(&ChangeListLoader::StartLoadChangeListFromServer, |
240 weak_ptr_factory_.GetWeakPtr(), | 250 weak_ptr_factory_.GetWeakPtr(), |
241 directory_fetch_info, | 251 directory_fetch_info, |
| 252 base::Passed(&about_resource), |
242 start_changestamp, | 253 start_changestamp, |
243 remote_changestamp, | |
244 callback)); | 254 callback)); |
245 } else { | 255 } else { |
246 // The directory is up-to-date, hence there is no need to load. | 256 // The directory is up-to-date, hence there is no need to load. |
247 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); | 257 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); |
248 } | 258 } |
249 } | 259 } |
250 | 260 |
251 void ChangeListLoader::LoadChangeListFromServer( | 261 void ChangeListLoader::LoadChangeListFromServer( |
| 262 scoped_ptr<google_apis::AboutResource> about_resource, |
252 int64 start_changestamp, | 263 int64 start_changestamp, |
253 int64 remote_changestamp, | |
254 const FileOperationCallback& callback) { | 264 const FileOperationCallback& callback) { |
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
256 DCHECK(!callback.is_null()); | 266 DCHECK(!callback.is_null()); |
257 DCHECK(refreshing_); | 267 DCHECK(refreshing_); |
258 | 268 |
259 scoped_ptr<LoadFeedParams> load_params(new LoadFeedParams); | 269 scoped_ptr<LoadFeedParams> load_params(new LoadFeedParams); |
260 load_params->start_changestamp = start_changestamp; | 270 load_params->start_changestamp = start_changestamp; |
261 LoadFromServer( | 271 LoadFromServer( |
262 load_params.Pass(), | 272 load_params.Pass(), |
263 base::Bind(&ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer, | 273 base::Bind(&ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer, |
264 weak_ptr_factory_.GetWeakPtr(), | 274 weak_ptr_factory_.GetWeakPtr(), |
| 275 base::Passed(&about_resource), |
265 start_changestamp != 0, // is_delta_feed | 276 start_changestamp != 0, // is_delta_feed |
266 remote_changestamp, | |
267 callback)); | 277 callback)); |
268 } | 278 } |
269 | 279 |
270 void ChangeListLoader::StartLoadChangeListFromServer( | 280 void ChangeListLoader::StartLoadChangeListFromServer( |
271 const DirectoryFetchInfo& directory_fetch_info, | 281 const DirectoryFetchInfo& directory_fetch_info, |
| 282 scoped_ptr<google_apis::AboutResource> about_resource, |
272 int64 start_changestamp, | 283 int64 start_changestamp, |
273 int64 remote_changestamp, | |
274 const FileOperationCallback& callback, | 284 const FileOperationCallback& callback, |
275 DriveFileError error) { | 285 DriveFileError error) { |
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
277 DCHECK(!callback.is_null()); | 287 DCHECK(!callback.is_null()); |
278 DCHECK(refreshing_); | 288 DCHECK(refreshing_); |
279 | 289 |
280 if (error == DRIVE_FILE_OK) { | 290 if (error == DRIVE_FILE_OK) { |
281 callback.Run(DRIVE_FILE_OK); | 291 callback.Run(DRIVE_FILE_OK); |
282 DVLOG(1) << "Fast-fetch was successful: " << directory_fetch_info.ToString() | 292 DVLOG(1) << "Fast-fetch was successful: " << directory_fetch_info.ToString() |
283 << "; Start loading the change list"; | 293 << "; Start loading the change list"; |
284 // Stop passing |callback| as it's just consumed. | 294 // Stop passing |callback| as it's just consumed. |
285 LoadChangeListFromServer( | 295 LoadChangeListFromServer( |
| 296 about_resource.Pass(), |
286 start_changestamp, | 297 start_changestamp, |
287 remote_changestamp, | |
288 base::Bind(&util::EmptyFileOperationCallback)); | 298 base::Bind(&util::EmptyFileOperationCallback)); |
289 } else { | 299 } else { |
290 // The directory fast-fetch failed, but the change list loading may | 300 // The directory fast-fetch failed, but the change list loading may |
291 // succeed. Keep passing |callback| so it's run after the change list | 301 // succeed. Keep passing |callback| so it's run after the change list |
292 // loading is complete. | 302 // loading is complete. |
293 LoadChangeListFromServer(start_changestamp, remote_changestamp, callback); | 303 LoadChangeListFromServer( |
| 304 about_resource.Pass(), start_changestamp, callback); |
294 } | 305 } |
295 } | 306 } |
296 | 307 |
297 void ChangeListLoader::OnGetAppList(google_apis::GDataErrorCode status, | 308 void ChangeListLoader::OnGetAppList(google_apis::GDataErrorCode status, |
298 scoped_ptr<google_apis::AppList> app_list) { | 309 scoped_ptr<google_apis::AppList> app_list) { |
299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
300 | 311 |
301 DriveFileError error = util::GDataToDriveFileError(status); | 312 DriveFileError error = util::GDataToDriveFileError(status); |
302 if (error != DRIVE_FILE_OK) | 313 if (error != DRIVE_FILE_OK) |
303 return; | 314 return; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 | 449 |
439 scoped_ptr<LoadFeedParams> params(new LoadFeedParams); | 450 scoped_ptr<LoadFeedParams> params(new LoadFeedParams); |
440 params->search_query = search_query; | 451 params->search_query = search_query; |
441 params->shared_with_me = shared_with_me; | 452 params->shared_with_me = shared_with_me; |
442 params->feed_to_load = next_feed; | 453 params->feed_to_load = next_feed; |
443 params->load_subsequent_feeds = false; | 454 params->load_subsequent_feeds = false; |
444 LoadFromServer(params.Pass(), feed_load_callback); | 455 LoadFromServer(params.Pass(), feed_load_callback); |
445 } | 456 } |
446 | 457 |
447 void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer( | 458 void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer( |
| 459 scoped_ptr<google_apis::AboutResource> about_resource, |
448 bool is_delta_feed, | 460 bool is_delta_feed, |
449 int64 feed_changestamp, | |
450 const FileOperationCallback& callback, | 461 const FileOperationCallback& callback, |
451 const ScopedVector<google_apis::ResourceList>& feed_list, | 462 const ScopedVector<google_apis::ResourceList>& feed_list, |
452 DriveFileError error) { | 463 DriveFileError error) { |
453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
454 DCHECK(!callback.is_null()); | 465 DCHECK(!callback.is_null()); |
455 DCHECK(refreshing_); | 466 DCHECK(refreshing_); |
456 | 467 |
457 if (error != DRIVE_FILE_OK) { | 468 if (error != DRIVE_FILE_OK) { |
458 OnChangeListLoadComplete(callback, error); | 469 OnChangeListLoadComplete(callback, error); |
459 return; | 470 return; |
460 } | 471 } |
461 | 472 |
462 UpdateFromFeed(feed_list, | 473 UpdateFromFeed(about_resource.Pass(), |
| 474 feed_list, |
463 is_delta_feed, | 475 is_delta_feed, |
464 feed_changestamp, | |
465 base::Bind(&ChangeListLoader::OnUpdateFromFeed, | 476 base::Bind(&ChangeListLoader::OnUpdateFromFeed, |
466 weak_ptr_factory_.GetWeakPtr(), | 477 weak_ptr_factory_.GetWeakPtr(), |
467 !loaded(), // is_initial_load | 478 !loaded(), // is_initial_load |
468 callback)); | 479 callback)); |
469 } | 480 } |
470 | 481 |
471 void ChangeListLoader::LoadFromServerAfterGetResourceList( | 482 void ChangeListLoader::LoadFromServerAfterGetResourceList( |
472 scoped_ptr<LoadFeedParams> params, | 483 scoped_ptr<LoadFeedParams> params, |
473 const LoadFeedListCallback& callback, | 484 const LoadFeedListCallback& callback, |
474 base::TimeTicks start_time, | 485 base::TimeTicks start_time, |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 } | 698 } |
688 | 699 |
689 void ChangeListLoader::SaveFileSystem() { | 700 void ChangeListLoader::SaveFileSystem() { |
690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 701 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
691 | 702 |
692 resource_metadata_->MaybeSave( | 703 resource_metadata_->MaybeSave( |
693 cache_->GetCacheDirectoryPath(DriveCache::CACHE_TYPE_META)); | 704 cache_->GetCacheDirectoryPath(DriveCache::CACHE_TYPE_META)); |
694 } | 705 } |
695 | 706 |
696 void ChangeListLoader::UpdateFromFeed( | 707 void ChangeListLoader::UpdateFromFeed( |
| 708 scoped_ptr<google_apis::AboutResource> about_resource, |
697 const ScopedVector<google_apis::ResourceList>& feed_list, | 709 const ScopedVector<google_apis::ResourceList>& feed_list, |
698 bool is_delta_feed, | 710 bool is_delta_feed, |
699 int64 root_feed_changestamp, | |
700 const base::Closure& update_finished_callback) { | 711 const base::Closure& update_finished_callback) { |
701 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
702 DCHECK(!update_finished_callback.is_null()); | 713 DCHECK(!update_finished_callback.is_null()); |
703 DVLOG(1) << "Updating directory with a feed"; | 714 DVLOG(1) << "Updating directory with a feed"; |
704 | 715 |
705 change_list_processor_.reset(new ChangeListProcessor(resource_metadata_)); | 716 change_list_processor_.reset(new ChangeListProcessor(resource_metadata_)); |
706 // Don't send directory content change notification while performing | 717 // Don't send directory content change notification while performing |
707 // the initial content retrieval. | 718 // the initial content retrieval. |
708 const bool should_notify_changed_directories = is_delta_feed; | 719 const bool should_notify_changed_directories = is_delta_feed; |
709 | 720 |
710 change_list_processor_->ApplyFeeds( | 721 change_list_processor_->ApplyFeeds( |
| 722 about_resource.Pass(), |
711 feed_list, | 723 feed_list, |
712 is_delta_feed, | 724 is_delta_feed, |
713 root_feed_changestamp, | |
714 base::Bind(&ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed, | 725 base::Bind(&ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed, |
715 weak_ptr_factory_.GetWeakPtr(), | 726 weak_ptr_factory_.GetWeakPtr(), |
716 should_notify_changed_directories, | 727 should_notify_changed_directories, |
717 update_finished_callback)); | 728 update_finished_callback)); |
718 } | 729 } |
719 | 730 |
720 void ChangeListLoader::ScheduleRun( | 731 void ChangeListLoader::ScheduleRun( |
721 const DirectoryFetchInfo& directory_fetch_info, | 732 const DirectoryFetchInfo& directory_fetch_info, |
722 const FileOperationCallback& callback) { | 733 const FileOperationCallback& callback) { |
723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 734 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 for (size_t i = 0; i < callbacks.size(); ++i) { | 865 for (size_t i = 0; i < callbacks.size(); ++i) { |
855 base::MessageLoopProxy::current()->PostTask( | 866 base::MessageLoopProxy::current()->PostTask( |
856 FROM_HERE, | 867 FROM_HERE, |
857 base::Bind(callbacks[i], error)); | 868 base::Bind(callbacks[i], error)); |
858 } | 869 } |
859 pending_load_callback_.erase(it); | 870 pending_load_callback_.erase(it); |
860 } | 871 } |
861 } | 872 } |
862 | 873 |
863 } // namespace drive | 874 } // namespace drive |
OLD | NEW |