Chromium Code Reviews| 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/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 using content::BrowserThread; | 21 using content::BrowserThread; |
| 22 | 22 |
| 23 namespace drive { | 23 namespace drive { |
| 24 | 24 |
| 25 ChangeListLoader::ChangeListLoader(DriveResourceMetadata* resource_metadata, | 25 ChangeListLoader::ChangeListLoader(DriveResourceMetadata* resource_metadata, |
| 26 DriveScheduler* scheduler, | 26 DriveScheduler* scheduler, |
| 27 DriveWebAppsRegistry* webapps_registry) | 27 DriveWebAppsRegistry* webapps_registry) |
| 28 : resource_metadata_(resource_metadata), | 28 : resource_metadata_(resource_metadata), |
| 29 scheduler_(scheduler), | 29 scheduler_(scheduler), |
| 30 webapps_registry_(webapps_registry), | 30 webapps_registry_(webapps_registry), |
| 31 refreshing_(false), | |
| 32 last_known_remote_changestamp_(0), | 31 last_known_remote_changestamp_(0), |
| 33 loaded_(false), | 32 loaded_(false), |
| 34 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 33 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 35 } | 34 } |
| 36 | 35 |
| 37 ChangeListLoader::~ChangeListLoader() { | 36 ChangeListLoader::~ChangeListLoader() { |
| 38 } | 37 } |
| 39 | 38 |
| 39 bool ChangeListLoader::refreshing() const { | |
| 40 // Callback for change list loading is stored in pending_load_callback_[""]. | |
| 41 // It is non-empty if and only if there is an in-flight loading operation. | |
| 42 LoadCallbackMap::const_iterator iter = pending_load_callback_.find(""); | |
| 43 return iter != pending_load_callback_.end() && !iter->second.empty(); | |
|
hashimoto
2013/04/17 08:15:37
nit: Is there any chance for iter->second to retur
kinaba
2013/04/17 08:46:23
no. done.
| |
| 44 } | |
| 45 | |
| 40 void ChangeListLoader::AddObserver(ChangeListLoaderObserver* observer) { | 46 void ChangeListLoader::AddObserver(ChangeListLoaderObserver* observer) { |
| 41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 42 observers_.AddObserver(observer); | 48 observers_.AddObserver(observer); |
| 43 } | 49 } |
| 44 | 50 |
| 45 void ChangeListLoader::RemoveObserver(ChangeListLoaderObserver* observer) { | 51 void ChangeListLoader::RemoveObserver(ChangeListLoaderObserver* observer) { |
| 46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 47 observers_.RemoveObserver(observer); | 53 observers_.RemoveObserver(observer); |
| 48 } | 54 } |
| 49 | 55 |
| 50 void ChangeListLoader::LoadFromServerIfNeeded( | 56 void ChangeListLoader::LoadFromServerIfNeeded( |
| 51 const DirectoryFetchInfo& directory_fetch_info, | 57 const DirectoryFetchInfo& directory_fetch_info, |
| 52 const FileOperationCallback& callback) { | 58 int64 local_changestamp) { |
| 53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 54 DCHECK(!callback.is_null()); | |
| 55 | |
| 56 // Sets the refreshing flag, so that the caller does not send refresh requests | |
| 57 // in parallel (see DriveFileSystem::CheckForUpdates). Corresponding | |
| 58 // "refresh_ = false" is in OnGetAboutResource when the cached feed is up to | |
| 59 // date, or in OnFeedFromServerLoaded called back from LoadFromServer(). | |
| 60 refreshing_ = true; | |
| 61 | 60 |
| 62 // Drive v2 needs a separate application list fetch operation. | 61 // Drive v2 needs a separate application list fetch operation. |
| 63 // On GData WAPI, it is not necessary in theory, because the response | 62 // On GData WAPI, it is not necessary in theory, because the response |
| 64 // of account metadata can include both about account information (such as | 63 // of account metadata can include both about account information (such as |
| 65 // quota) and an application list at once. | 64 // quota) and an application list at once. |
| 66 // However, for Drive API v2 migration, we connect to the server twice | 65 // However, for Drive API v2 migration, we connect to the server twice |
| 67 // (one for about account information and another for an application list) | 66 // (one for about account information and another for an application list) |
| 68 // regardless of underlying API, so that we can simplify the code. | 67 // regardless of underlying API, so that we can simplify the code. |
| 69 // Note that the size of account metadata on GData WAPI seems small enough | 68 // Note that the size of account metadata on GData WAPI seems small enough |
| 70 // and (by controlling the query parameter) the response for GetAboutResource | 69 // and (by controlling the query parameter) the response for GetAboutResource |
| 71 // operation doesn't contain application list. Thus, the effect should be | 70 // operation doesn't contain application list. Thus, the effect should be |
| 72 // small cost. | 71 // small cost. |
| 73 // TODO(haruki): Application list rarely changes and is not necessarily | 72 // TODO(haruki): Application list rarely changes and is not necessarily |
| 74 // refreshed as often as files. | 73 // refreshed as often as files. |
| 75 scheduler_->GetAppList( | 74 scheduler_->GetAppList( |
| 76 base::Bind(&ChangeListLoader::OnGetAppList, | 75 base::Bind(&ChangeListLoader::OnGetAppList, |
| 77 weak_ptr_factory_.GetWeakPtr())); | 76 weak_ptr_factory_.GetWeakPtr())); |
| 78 | 77 |
| 79 // First fetch the latest changestamp to see if there were any new changes | 78 // First fetch the latest changestamp to see if there were any new changes |
| 80 // there at all. | 79 // there at all. |
| 81 scheduler_->GetAboutResource( | 80 scheduler_->GetAboutResource( |
| 82 base::Bind(&ChangeListLoader::LoadFromServerIfNeededAfterGetAbout, | 81 base::Bind(&ChangeListLoader::LoadFromServerIfNeededAfterGetAbout, |
| 83 weak_ptr_factory_.GetWeakPtr(), | 82 weak_ptr_factory_.GetWeakPtr(), |
| 84 directory_fetch_info, | 83 directory_fetch_info, |
| 85 callback)); | 84 local_changestamp)); |
| 86 } | 85 } |
| 87 | 86 |
| 88 void ChangeListLoader::LoadFromServerIfNeededAfterGetAbout( | 87 void ChangeListLoader::LoadFromServerIfNeededAfterGetAbout( |
| 89 const DirectoryFetchInfo& directory_fetch_info, | 88 const DirectoryFetchInfo& directory_fetch_info, |
| 90 const FileOperationCallback& callback, | 89 int64 local_changestamp, |
| 91 google_apis::GDataErrorCode status, | 90 google_apis::GDataErrorCode status, |
| 92 scoped_ptr<google_apis::AboutResource> about_resource) { | 91 scoped_ptr<google_apis::AboutResource> about_resource) { |
| 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 94 DCHECK(!callback.is_null()); | |
| 95 DCHECK(refreshing_); | |
| 96 DCHECK_EQ(util::GDataToDriveFileError(status) == DRIVE_FILE_OK, | 93 DCHECK_EQ(util::GDataToDriveFileError(status) == DRIVE_FILE_OK, |
| 97 about_resource.get() != NULL); | 94 about_resource.get() != NULL); |
| 98 | 95 |
| 99 if (util::GDataToDriveFileError(status) == DRIVE_FILE_OK) { | 96 if (util::GDataToDriveFileError(status) == DRIVE_FILE_OK) { |
| 100 DCHECK(about_resource); | 97 DCHECK(about_resource); |
| 101 last_known_remote_changestamp_ = about_resource->largest_change_id(); | 98 last_known_remote_changestamp_ = about_resource->largest_change_id(); |
| 102 } | 99 } |
| 103 | 100 |
| 104 resource_metadata_->GetLargestChangestamp( | |
| 105 base::Bind(&ChangeListLoader::CompareChangestampsAndLoadIfNeeded, | |
| 106 weak_ptr_factory_.GetWeakPtr(), | |
| 107 directory_fetch_info, | |
| 108 callback, | |
| 109 base::Passed(&about_resource))); | |
| 110 } | |
| 111 | |
| 112 void ChangeListLoader::CompareChangestampsAndLoadIfNeeded( | |
| 113 const DirectoryFetchInfo& directory_fetch_info, | |
| 114 const FileOperationCallback& callback, | |
| 115 scoped_ptr<google_apis::AboutResource> about_resource, | |
| 116 int64 local_changestamp) { | |
| 117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 118 DCHECK(!callback.is_null()); | |
| 119 DCHECK(refreshing_); | |
| 120 | |
| 121 int64 remote_changestamp = | 101 int64 remote_changestamp = |
| 122 about_resource ? about_resource->largest_change_id() : 0; | 102 about_resource ? about_resource->largest_change_id() : 0; |
| 123 if (remote_changestamp > 0 && local_changestamp >= remote_changestamp) { | 103 if (remote_changestamp > 0 && local_changestamp >= remote_changestamp) { |
| 124 if (local_changestamp > remote_changestamp) { | 104 if (local_changestamp > remote_changestamp) { |
| 125 LOG(WARNING) << "Cached client feed is fresher than server, client = " | 105 LOG(WARNING) << "Cached client feed is fresher than server, client = " |
| 126 << local_changestamp | 106 << local_changestamp |
| 127 << ", server = " | 107 << ", server = " |
| 128 << remote_changestamp; | 108 << remote_changestamp; |
| 129 } | 109 } |
| 130 | 110 |
| 131 // No changes detected, tell the client that the loading was successful. | 111 // No changes detected, tell the client that the loading was successful. |
| 132 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); | 112 OnChangeListLoadComplete(DRIVE_FILE_OK); |
| 133 return; | 113 return; |
| 134 } | 114 } |
| 135 | 115 |
| 136 int64 start_changestamp = local_changestamp > 0 ? local_changestamp + 1 : 0; | 116 int64 start_changestamp = local_changestamp > 0 ? local_changestamp + 1 : 0; |
| 137 if (start_changestamp == 0 && !about_resource.get()) { | 117 if (start_changestamp == 0 && !about_resource.get()) { |
| 138 // Full update needs AboutResource. If this is a full update, we should just | 118 // Full update needs AboutResource. If this is a full update, we should just |
| 139 // give up. Note that to exit from the feed loading, we always have to flush | 119 // give up. Note that to exit from the feed loading, we always have to flush |
| 140 // the pending callback tasks via OnChangeListLoadComplete. | 120 // the pending callback tasks via OnChangeListLoadComplete. |
| 141 OnChangeListLoadComplete(callback, DRIVE_FILE_ERROR_FAILED); | 121 OnChangeListLoadComplete(DRIVE_FILE_ERROR_FAILED); |
| 142 return; | 122 return; |
| 143 } | 123 } |
| 144 | 124 |
| 145 if (directory_fetch_info.empty()) { | 125 if (directory_fetch_info.empty()) { |
| 146 // If the caller is not interested in a particular directory, just start | 126 // If the caller is not interested in a particular directory, just start |
| 147 // loading the change list. | 127 // loading the change list. |
| 148 LoadChangeListFromServer(about_resource.Pass(), | 128 LoadChangeListFromServer(about_resource.Pass(), start_changestamp); |
| 149 start_changestamp, | |
| 150 callback); | |
| 151 } else if (directory_fetch_info.changestamp() < remote_changestamp) { | |
| 152 // If the caller is interested in a particular directory, and the | |
| 153 // directory changestamp is older than server's, start loading the | |
| 154 // directory first. Skip special entries as they are not meaningful in the | |
| 155 // server. | |
| 156 DVLOG(1) << "Fast-fetching directory: " << directory_fetch_info.ToString() | |
| 157 << "; remote_changestamp: " << remote_changestamp; | |
| 158 const DirectoryFetchInfo new_directory_fetch_info( | |
| 159 directory_fetch_info.resource_id(), remote_changestamp); | |
| 160 DoLoadDirectoryFromServer( | |
| 161 new_directory_fetch_info, | |
| 162 base::Bind(&ChangeListLoader::StartLoadChangeListFromServer, | |
| 163 weak_ptr_factory_.GetWeakPtr(), | |
| 164 directory_fetch_info, | |
| 165 base::Passed(&about_resource), | |
| 166 start_changestamp, | |
| 167 callback)); | |
| 168 } else { | 129 } else { |
| 169 // The directory is up-to-date, but not the case for other parts. | 130 // If the caller is interested in a particular directory, start loading the |
| 170 // Proceed to change list loading. StartLoadChangeListFromServer will | 131 // directory first. |
| 171 // run |callback| for notifying the directory is ready before feed load. | 132 CheckChangestampAndLoadDirectoryIfNeeed( |
| 172 StartLoadChangeListFromServer(directory_fetch_info, | 133 directory_fetch_info, |
| 173 about_resource.Pass(), | 134 local_changestamp, |
| 174 start_changestamp, | 135 base::Bind( |
| 175 callback, | 136 &ChangeListLoader::LoadChangeListFromServerAfterLoadDirectory, |
| 176 DRIVE_FILE_OK); | 137 weak_ptr_factory_.GetWeakPtr(), |
| 138 directory_fetch_info, | |
| 139 base::Passed(&about_resource), | |
| 140 start_changestamp)); | |
| 177 } | 141 } |
| 178 } | 142 } |
| 179 | 143 |
| 180 void ChangeListLoader::LoadChangeListFromServer( | 144 void ChangeListLoader::LoadChangeListFromServer( |
| 181 scoped_ptr<google_apis::AboutResource> about_resource, | 145 scoped_ptr<google_apis::AboutResource> about_resource, |
| 182 int64 start_changestamp, | 146 int64 start_changestamp) { |
| 183 const FileOperationCallback& callback) { | |
| 184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 185 DCHECK(!callback.is_null()); | |
| 186 DCHECK(refreshing_); | |
| 187 | 148 |
| 188 bool is_delta_feed = start_changestamp != 0; | 149 bool is_delta_feed = start_changestamp != 0; |
| 189 const LoadFeedListCallback& completion_callback = | 150 const LoadFeedListCallback& completion_callback = |
| 190 base::Bind(&ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer, | 151 base::Bind(&ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer, |
| 191 weak_ptr_factory_.GetWeakPtr(), | 152 weak_ptr_factory_.GetWeakPtr(), |
| 192 base::Passed(&about_resource), | 153 base::Passed(&about_resource), |
| 193 is_delta_feed, | 154 is_delta_feed); |
| 194 callback); | |
| 195 base::TimeTicks start_time = base::TimeTicks::Now(); | 155 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 196 if (is_delta_feed) { | 156 if (is_delta_feed) { |
| 197 scheduler_->GetChangeList( | 157 scheduler_->GetChangeList( |
| 198 start_changestamp, | 158 start_changestamp, |
| 199 base::Bind(&ChangeListLoader::OnGetResourceList, | 159 base::Bind(&ChangeListLoader::OnGetResourceList, |
| 200 weak_ptr_factory_.GetWeakPtr(), | 160 weak_ptr_factory_.GetWeakPtr(), |
| 201 base::Passed(ScopedVector<ChangeList>()), | 161 base::Passed(ScopedVector<ChangeList>()), |
| 202 completion_callback, | 162 completion_callback, |
| 203 start_time)); | 163 start_time)); |
| 204 } else { | 164 } else { |
| 205 // This is full feed fetch. | 165 // This is full feed fetch. |
| 206 scheduler_->GetAllResourceList( | 166 scheduler_->GetAllResourceList( |
| 207 base::Bind(&ChangeListLoader::OnGetResourceList, | 167 base::Bind(&ChangeListLoader::OnGetResourceList, |
| 208 weak_ptr_factory_.GetWeakPtr(), | 168 weak_ptr_factory_.GetWeakPtr(), |
| 209 base::Passed(ScopedVector<ChangeList>()), | 169 base::Passed(ScopedVector<ChangeList>()), |
| 210 completion_callback, | 170 completion_callback, |
| 211 start_time)); | 171 start_time)); |
| 212 } | 172 } |
| 213 } | 173 } |
| 214 | 174 |
| 215 void ChangeListLoader::StartLoadChangeListFromServer( | 175 void ChangeListLoader::LoadChangeListFromServerAfterLoadDirectory( |
| 216 const DirectoryFetchInfo& directory_fetch_info, | 176 const DirectoryFetchInfo& directory_fetch_info, |
| 217 scoped_ptr<google_apis::AboutResource> about_resource, | 177 scoped_ptr<google_apis::AboutResource> about_resource, |
| 218 int64 start_changestamp, | 178 int64 start_changestamp, |
| 219 const FileOperationCallback& callback, | |
| 220 DriveFileError error) { | 179 DriveFileError error) { |
| 221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 222 DCHECK(!callback.is_null()); | |
| 223 DCHECK(refreshing_); | |
| 224 | 181 |
| 225 if (error == DRIVE_FILE_OK) { | 182 if (error == DRIVE_FILE_OK) { |
| 226 OnDirectoryLoadComplete(directory_fetch_info, callback, DRIVE_FILE_OK); | 183 // The directory fast-fetch succeeded. Runs the callbacks waiting for the |
| 227 DVLOG(1) << "Fast-fetch was successful: " << directory_fetch_info.ToString() | 184 // directory loading. If failed, do not flush so they're run after the |
| 228 << "; Start loading the change list"; | 185 // change list loading is complete. |
| 229 // Stop passing |callback| as it's just consumed. | 186 OnDirectoryLoadComplete(directory_fetch_info, DRIVE_FILE_OK); |
| 230 LoadChangeListFromServer( | |
| 231 about_resource.Pass(), | |
| 232 start_changestamp, | |
| 233 base::Bind(&util::EmptyFileOperationCallback)); | |
| 234 } else { | |
| 235 // The directory fast-fetch failed, but the change list loading may | |
| 236 // succeed. Keep passing |callback| so it's run after the change list | |
| 237 // loading is complete. | |
| 238 LoadChangeListFromServer( | |
| 239 about_resource.Pass(), start_changestamp, callback); | |
| 240 } | 187 } |
| 188 LoadChangeListFromServer(about_resource.Pass(), start_changestamp); | |
| 241 } | 189 } |
| 242 | 190 |
| 243 void ChangeListLoader::SearchFromServerAfterGetResourceList( | 191 void ChangeListLoader::SearchFromServerAfterGetResourceList( |
| 244 const LoadFeedListCallback& callback, | 192 const LoadFeedListCallback& callback, |
| 245 google_apis::GDataErrorCode status, | 193 google_apis::GDataErrorCode status, |
| 246 scoped_ptr<google_apis::ResourceList> resource_list) { | 194 scoped_ptr<google_apis::ResourceList> resource_list) { |
| 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 248 DCHECK(!callback.is_null()); | 196 DCHECK(!callback.is_null()); |
| 249 | 197 |
| 250 DriveFileError error = util::GDataToDriveFileError(status); | 198 DriveFileError error = util::GDataToDriveFileError(status); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 } | 286 } |
| 339 | 287 |
| 340 void ChangeListLoader::LoadDirectoryFromServerAfterGetAbout( | 288 void ChangeListLoader::LoadDirectoryFromServerAfterGetAbout( |
| 341 const std::string& directory_resource_id, | 289 const std::string& directory_resource_id, |
| 342 const FileOperationCallback& callback, | 290 const FileOperationCallback& callback, |
| 343 google_apis::GDataErrorCode status, | 291 google_apis::GDataErrorCode status, |
| 344 scoped_ptr<google_apis::AboutResource> about_resource) { | 292 scoped_ptr<google_apis::AboutResource> about_resource) { |
| 345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 346 DCHECK(!callback.is_null()); | 294 DCHECK(!callback.is_null()); |
| 347 | 295 |
| 348 int64 remote_changestamp = 0; | |
| 349 if (util::GDataToDriveFileError(status) == DRIVE_FILE_OK) { | 296 if (util::GDataToDriveFileError(status) == DRIVE_FILE_OK) { |
| 350 DCHECK(about_resource); | 297 DCHECK(about_resource); |
| 351 remote_changestamp = about_resource->largest_change_id(); | 298 last_known_remote_changestamp_ = about_resource->largest_change_id(); |
| 352 last_known_remote_changestamp_ = remote_changestamp; | |
| 353 } | 299 } |
| 354 | 300 |
| 355 const DirectoryFetchInfo directory_fetch_info(directory_resource_id, | 301 const DirectoryFetchInfo directory_fetch_info( |
| 356 remote_changestamp); | 302 directory_resource_id, |
| 303 last_known_remote_changestamp_); | |
| 357 DoLoadDirectoryFromServer(directory_fetch_info, callback); | 304 DoLoadDirectoryFromServer(directory_fetch_info, callback); |
| 358 } | 305 } |
| 359 | 306 |
| 360 void ChangeListLoader::DoLoadDirectoryFromServer( | 307 void ChangeListLoader::DoLoadDirectoryFromServer( |
| 361 const DirectoryFetchInfo& directory_fetch_info, | 308 const DirectoryFetchInfo& directory_fetch_info, |
| 362 const FileOperationCallback& callback) { | 309 const FileOperationCallback& callback) { |
| 363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 364 DCHECK(!callback.is_null()); | 311 DCHECK(!callback.is_null()); |
| 365 DCHECK(!directory_fetch_info.empty()); | 312 DCHECK(!directory_fetch_info.empty()); |
| 366 DVLOG(1) << "Start loading directory: " << directory_fetch_info.ToString(); | 313 DVLOG(1) << "Start loading directory: " << directory_fetch_info.ToString(); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 530 scheduler_->ContinueGetResourceList( | 477 scheduler_->ContinueGetResourceList( |
| 531 next_feed, | 478 next_feed, |
| 532 base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList, | 479 base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList, |
| 533 weak_ptr_factory_.GetWeakPtr(), callback)); | 480 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 534 } | 481 } |
| 535 } | 482 } |
| 536 | 483 |
| 537 void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer( | 484 void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer( |
| 538 scoped_ptr<google_apis::AboutResource> about_resource, | 485 scoped_ptr<google_apis::AboutResource> about_resource, |
| 539 bool is_delta_feed, | 486 bool is_delta_feed, |
| 540 const FileOperationCallback& callback, | |
| 541 ScopedVector<ChangeList> change_lists, | 487 ScopedVector<ChangeList> change_lists, |
| 542 DriveFileError error) { | 488 DriveFileError error) { |
| 543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 489 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 544 DCHECK(!callback.is_null()); | |
| 545 DCHECK(refreshing_); | |
| 546 | 490 |
| 547 if (error != DRIVE_FILE_OK) { | 491 if (error != DRIVE_FILE_OK) { |
| 548 OnChangeListLoadComplete(callback, error); | 492 OnChangeListLoadComplete(error); |
| 549 return; | 493 return; |
| 550 } | 494 } |
| 551 | 495 |
| 552 UpdateFromFeed(about_resource.Pass(), | 496 UpdateFromFeed(about_resource.Pass(), |
| 553 change_lists.Pass(), | 497 change_lists.Pass(), |
| 554 is_delta_feed, | 498 is_delta_feed, |
| 555 base::Bind(&ChangeListLoader::OnUpdateFromFeed, | 499 base::Bind(&ChangeListLoader::OnUpdateFromFeed, |
| 556 weak_ptr_factory_.GetWeakPtr(), | 500 weak_ptr_factory_.GetWeakPtr())); |
| 557 !loaded(), // is_initial_load | |
| 558 callback)); | |
| 559 } | 501 } |
| 560 | 502 |
| 561 void ChangeListLoader::LoadIfNeeded( | 503 void ChangeListLoader::LoadIfNeeded( |
| 562 const DirectoryFetchInfo& directory_fetch_info, | 504 const DirectoryFetchInfo& directory_fetch_info, |
| 563 const FileOperationCallback& callback) { | 505 const FileOperationCallback& callback) { |
| 564 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 565 DCHECK(!callback.is_null()); | 507 DCHECK(!callback.is_null()); |
| 566 | 508 |
| 567 // If feed has already been loaded, for normal feed fetch (= empty | 509 // If feed has already been loaded, for normal feed fetch (= empty |
| 568 // directory_fetch_info), we have nothing to do. For "fast fetch", we need to | 510 // directory_fetch_info), we have nothing to do. For "fast fetch", we need to |
| 569 // schedule a fetching if a feed refresh is currently running, because we | 511 // schedule a fetching if a feed refresh is currently running, because we |
| 570 // don't want to wait a possibly large delta feed to arrive. | 512 // don't want to wait a possibly large delta feed to arrive. |
| 571 if (loaded() && (directory_fetch_info.empty() || !refreshing())) { | 513 if (loaded() && (directory_fetch_info.empty() || !refreshing())) { |
| 572 base::MessageLoopProxy::current()->PostTask( | 514 base::MessageLoopProxy::current()->PostTask( |
| 573 FROM_HERE, | 515 FROM_HERE, |
| 574 base::Bind(callback, DRIVE_FILE_OK)); | 516 base::Bind(callback, DRIVE_FILE_OK)); |
| 575 return; | 517 return; |
| 576 } | 518 } |
| 519 Load(directory_fetch_info, callback); | |
| 520 } | |
| 577 | 521 |
| 578 // At this point, it is either !loaded() or refreshing(). | 522 void ChangeListLoader::Load(const DirectoryFetchInfo& directory_fetch_info, |
| 579 // If the change list loading is in progress, schedule the callback to | 523 const FileOperationCallback& callback) { |
| 580 // run when it's ready (i.e. when the entire resource list is loaded, or | 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 581 // the directory contents are available per "fast fetch"). | 525 DCHECK(!callback.is_null()); |
| 582 if (refreshing()) { | 526 |
| 583 ScheduleRun(directory_fetch_info, callback); | 527 // Check if this is the first time this ChangeListLoader do loading. |
| 528 // Note: refreshing() depends on pending_load_callback_ so check in advance. | |
| 529 const bool is_initial_load = (!loaded_ && !refreshing()); | |
| 530 | |
| 531 // Register the callback function to be called when it is loaded. | |
| 532 const std::string& resource_id = directory_fetch_info.resource_id(); | |
| 533 pending_load_callback_[resource_id].push_back(callback); | |
| 534 | |
| 535 // If loading task for |resource_id| is already running, do nothing. | |
| 536 if (pending_load_callback_[resource_id].size() > 1) | |
| 584 return; | 537 return; |
| 585 } | |
| 586 | 538 |
| 587 if (!directory_fetch_info.empty()) { | 539 // For initial loading, even for directory fetching, we do load the full |
| 588 // Add a dummy task to so ScheduleRun() can check that the directory is | 540 // feed from the server to sync up. So we register a dummy callback to |
| 589 // being fetched. This will be cleared either in | 541 // indicate that update for full hierarchy is running. |
| 590 // ProcessPendingLoadCallbackForDirectory() or FlushPendingLoadCallback(). | 542 if (is_initial_load && !resource_id.empty()) { |
| 591 pending_load_callback_[directory_fetch_info.resource_id()].push_back( | 543 pending_load_callback_[""].push_back( |
| 592 base::Bind(&util::EmptyFileOperationCallback)); | 544 base::Bind(&util::EmptyFileOperationCallback)); |
| 593 } | 545 } |
| 594 | 546 |
| 595 // First check if the local data is usable or not. | 547 // Check the current status of local metadata, and start loading if needed. |
| 596 CheckLocalChangestamp(base::Bind( | 548 resource_metadata_->GetLargestChangestamp( |
| 597 &ChangeListLoader::LoadAfterCheckLocalChangestamp, | 549 base::Bind(is_initial_load ? &ChangeListLoader::DoInitialLoad |
| 598 weak_ptr_factory_.GetWeakPtr(), | 550 : &ChangeListLoader::DoUpdateLoad, |
| 599 directory_fetch_info, | 551 weak_ptr_factory_.GetWeakPtr(), |
| 600 callback)); | 552 directory_fetch_info)); |
| 601 } | 553 } |
| 602 | 554 |
| 603 void ChangeListLoader::LoadAfterCheckLocalChangestamp( | 555 void ChangeListLoader::DoInitialLoad( |
| 604 const DirectoryFetchInfo& directory_fetch_info, | 556 const DirectoryFetchInfo& directory_fetch_info, |
| 605 const FileOperationCallback& callback, | |
| 606 int64 local_changestamp) { | 557 int64 local_changestamp) { |
| 607 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 608 DCHECK(!callback.is_null()); | |
| 609 | 559 |
| 610 if (local_changestamp > 0) { | 560 if (local_changestamp > 0) { |
| 611 loaded_ = true; | 561 // The local data is usable. Flush callbacks to tell loading was successful. |
| 562 OnChangeListLoadComplete(DRIVE_FILE_OK); | |
| 612 | 563 |
| 613 // The local data is usable. Change the refreshing state and tell the | 564 // Continues to load from server in background. |
| 614 // callback that the loading was successful. | 565 // Put dummy callbacks to indicate that fetching is still continuing. |
| 615 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); | 566 pending_load_callback_[directory_fetch_info.resource_id()].push_back( |
| 616 FOR_EACH_OBSERVER(ChangeListLoaderObserver, | 567 base::Bind(&util::EmptyFileOperationCallback)); |
| 617 observers_, | 568 if (!directory_fetch_info.empty()) { |
| 618 OnInitialFeedLoaded()); | 569 pending_load_callback_[""].push_back( |
| 570 base::Bind(&util::EmptyFileOperationCallback)); | |
| 571 } | |
| 572 } | |
| 573 LoadFromServerIfNeeded(directory_fetch_info, local_changestamp); | |
| 574 } | |
| 619 | 575 |
| 620 // Load from server if needed (i.e. the cache is old). Note that we | 576 void ChangeListLoader::DoUpdateLoad( |
| 621 // should still propagate |directory_fetch_info| though the directory is | 577 const DirectoryFetchInfo& directory_fetch_info, |
| 622 // loaded first. This way, the UI can get notified via a directory change | 578 int64 local_changestamp) { |
| 623 // event as soon as the current directory contents are fetched. | 579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 624 LoadFromServerIfNeeded(directory_fetch_info, | 580 |
| 625 base::Bind(&util::EmptyFileOperationCallback)); | 581 if (directory_fetch_info.empty()) { |
| 582 LoadFromServerIfNeeded(directory_fetch_info, local_changestamp); | |
| 626 } else { | 583 } else { |
| 627 // The local data is not usable. Start loading from the server. Though the | 584 // Note: CheckChangestampAndLoadDirectoryIfNeeded regards |
| 628 // function name ends with "IfNeeded", this function should always start | 585 // last_know_remote_changestamp_ as the remote changestamp. To be precise, |
| 629 // loading as the local changestamp is zero now. | 586 // we need to call GetAboutResource() here, as we do in other places like |
| 630 LoadFromServerIfNeeded(directory_fetch_info, callback); | 587 // LoadFromServerIfNeeded or LoadFromDirectory. However, |
| 588 // - It is costly to do GetAboutResource HTTP request every time. | |
| 589 // - The chance using an old value is small; it only happens when | |
| 590 // LoadIfNeeded is called during one GetAboutResource roundtrip time | |
| 591 // of a feed fetching. | |
| 592 // - Even if the value is old, it just marks the directory as older. It may | |
| 593 // trigger one future unnecessary re-fetch, but it'll never lose data. | |
| 594 CheckChangestampAndLoadDirectoryIfNeeed( | |
| 595 directory_fetch_info, | |
| 596 local_changestamp, | |
| 597 base::Bind(&ChangeListLoader::OnDirectoryLoadComplete, | |
| 598 weak_ptr_factory_.GetWeakPtr(), | |
| 599 directory_fetch_info)); | |
| 631 } | 600 } |
| 632 } | 601 } |
| 633 | 602 |
| 634 void ChangeListLoader::CheckLocalChangestamp( | |
| 635 const GetChangestampCallback& callback) { | |
| 636 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 637 DCHECK(!callback.is_null()); | |
| 638 DCHECK(!loaded_); | |
| 639 | |
| 640 // Sets the refreshing flag, so that the caller does not send refresh requests | |
| 641 // in parallel (see DriveFileSystem::LoadFeedIfNeeded). | |
| 642 // | |
| 643 // The flag will be unset when loading completes. | |
| 644 refreshing_ = true; | |
| 645 | |
| 646 resource_metadata_->GetLargestChangestamp(callback); | |
| 647 } | |
| 648 | |
| 649 | |
| 650 void ChangeListLoader::CheckForUpdates(const FileOperationCallback& callback) { | 603 void ChangeListLoader::CheckForUpdates(const FileOperationCallback& callback) { |
| 651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 604 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 652 DCHECK(!callback.is_null()); | 605 DCHECK(!callback.is_null()); |
| 653 | 606 |
| 654 if (loaded() && !refreshing()) | 607 if (loaded() && !refreshing()) |
| 655 LoadFromServerIfNeeded(DirectoryFetchInfo(), callback); | 608 Load(DirectoryFetchInfo(), callback); |
| 656 } | 609 } |
| 657 | 610 |
| 658 void ChangeListLoader::UpdateFromFeed( | 611 void ChangeListLoader::UpdateFromFeed( |
| 659 scoped_ptr<google_apis::AboutResource> about_resource, | 612 scoped_ptr<google_apis::AboutResource> about_resource, |
| 660 ScopedVector<ChangeList> change_lists, | 613 ScopedVector<ChangeList> change_lists, |
| 661 bool is_delta_feed, | 614 bool is_delta_feed, |
| 662 const base::Closure& update_finished_callback) { | 615 const base::Closure& update_finished_callback) { |
| 663 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 616 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 664 DCHECK(!update_finished_callback.is_null()); | 617 DCHECK(!update_finished_callback.is_null()); |
| 665 DVLOG(1) << "Updating directory with a feed"; | 618 DVLOG(1) << "Updating directory with a feed"; |
| 666 | 619 |
| 667 change_list_processor_.reset(new ChangeListProcessor(resource_metadata_)); | 620 change_list_processor_.reset(new ChangeListProcessor(resource_metadata_)); |
| 668 // Don't send directory content change notification while performing | 621 // Don't send directory content change notification while performing |
| 669 // the initial content retrieval. | 622 // the initial content retrieval. |
| 670 const bool should_notify_changed_directories = is_delta_feed; | 623 const bool should_notify_changed_directories = is_delta_feed; |
| 671 | 624 |
| 672 change_list_processor_->ApplyFeeds( | 625 change_list_processor_->ApplyFeeds( |
| 673 about_resource.Pass(), | 626 about_resource.Pass(), |
| 674 change_lists.Pass(), | 627 change_lists.Pass(), |
| 675 is_delta_feed, | 628 is_delta_feed, |
| 676 base::Bind(&ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed, | 629 base::Bind(&ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed, |
| 677 weak_ptr_factory_.GetWeakPtr(), | 630 weak_ptr_factory_.GetWeakPtr(), |
| 678 should_notify_changed_directories, | 631 should_notify_changed_directories, |
| 679 update_finished_callback)); | 632 update_finished_callback)); |
| 680 } | 633 } |
| 681 | 634 |
| 682 void ChangeListLoader::ScheduleRun( | 635 void ChangeListLoader::CheckChangestampAndLoadDirectoryIfNeeed( |
| 683 const DirectoryFetchInfo& directory_fetch_info, | 636 const DirectoryFetchInfo& directory_fetch_info, |
| 637 int64 local_changestamp, | |
| 684 const FileOperationCallback& callback) { | 638 const FileOperationCallback& callback) { |
| 685 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 639 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 686 DCHECK(!callback.is_null()); | 640 DCHECK(!directory_fetch_info.empty()); |
| 687 DCHECK(refreshing_); | |
| 688 | 641 |
| 689 if (directory_fetch_info.empty()) { | 642 int64 directory_changestamp = std::max(directory_fetch_info.changestamp(), |
| 690 // If the caller is not interested in a particular directory, just add the | 643 local_changestamp); |
| 691 // callback to the pending list and return. | |
| 692 pending_load_callback_[""].push_back(callback); | |
| 693 return; | |
| 694 } | |
| 695 | |
| 696 const std::string& resource_id = directory_fetch_info.resource_id(); | |
| 697 | |
| 698 // If the directory of interest is already scheduled to be fetched, add the | |
| 699 // callback to the pending list and return. | |
| 700 LoadCallbackMap::iterator it = pending_load_callback_.find(resource_id); | |
| 701 if (it != pending_load_callback_.end()) { | |
| 702 it->second.push_back(callback); | |
| 703 return; | |
| 704 } | |
| 705 | 644 |
| 706 // If the directory's changestamp is up-to-date, just schedule to run the | 645 // If the directory's changestamp is up-to-date, just schedule to run the |
| 707 // callback, as there is no need to fetch the directory. | 646 // callback, as there is no need to fetch the directory. |
| 708 // Note that |last_known_remote_changestamp_| is 0 when it is not received | 647 // Note that |last_known_remote_changestamp_| is 0 when it is not received |
| 709 // yet. In that case we conservatively assume that we need to fetch. | 648 // yet. In that case we conservatively assume that we need to fetch. |
| 710 if (last_known_remote_changestamp_ > 0 && | 649 if (last_known_remote_changestamp_ > 0 && |
| 711 directory_fetch_info.changestamp() >= last_known_remote_changestamp_) { | 650 directory_changestamp >= last_known_remote_changestamp_) { |
| 712 base::MessageLoopProxy::current()->PostTask( | 651 callback.Run(DRIVE_FILE_OK); |
| 713 FROM_HERE, | |
| 714 base::Bind(callback, DRIVE_FILE_OK)); | |
| 715 return; | 652 return; |
| 716 } | 653 } |
| 717 | 654 |
| 718 // The directory should be fetched. Add a dummy task to so ScheduleRun() | |
| 719 // can check that the directory is being fetched. | |
| 720 pending_load_callback_[resource_id].push_back( | |
| 721 base::Bind(&util::EmptyFileOperationCallback)); | |
| 722 | |
| 723 // Start fetching the directory content, and mark it with the changestamp | 655 // Start fetching the directory content, and mark it with the changestamp |
| 724 // |last_known_remote_changestamp_|. To be precise, instead we need to call | 656 // |last_known_remote_changestamp_|. |
| 725 // GetAboutResource() to get the latest changestamp. However, | |
| 726 // - It is costly to do GetAboutResource HTTP request every time. | |
| 727 // - The chance using an old value is small; it only happens when LoadIfNeeded | |
| 728 // is called during one GetAboutResource roundtrip time of a feed fetching. | |
| 729 // - Even if the value is old, it just marks the directory as older. It may | |
| 730 // trigger one future unnecessary re-fetch, but it'll never lose data, etc. | |
| 731 DirectoryFetchInfo new_directory_fetch_info( | 657 DirectoryFetchInfo new_directory_fetch_info( |
| 732 directory_fetch_info.resource_id(), | 658 directory_fetch_info.resource_id(), |
| 733 std::max(directory_fetch_info.changestamp(), | 659 std::max(directory_changestamp, last_known_remote_changestamp_)); |
| 734 last_known_remote_changestamp_)); | 660 DoLoadDirectoryFromServer(new_directory_fetch_info, callback); |
| 735 DoLoadDirectoryFromServer( | |
| 736 new_directory_fetch_info, | |
| 737 base::Bind(&ChangeListLoader::OnDirectoryLoadComplete, | |
| 738 weak_ptr_factory_.GetWeakPtr(), | |
| 739 directory_fetch_info, | |
| 740 callback)); | |
| 741 } | 661 } |
| 742 | 662 |
| 743 void ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed( | 663 void ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed( |
| 744 bool should_notify_changed_directories, | 664 bool should_notify_changed_directories, |
| 745 const base::Closure& update_finished_callback) { | 665 const base::Closure& update_finished_callback) { |
| 746 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 747 DCHECK(change_list_processor_.get()); | 667 DCHECK(change_list_processor_.get()); |
| 748 DCHECK(!update_finished_callback.is_null()); | 668 DCHECK(!update_finished_callback.is_null()); |
| 749 | 669 |
| 750 loaded_ = true; | |
| 751 | |
| 752 if (should_notify_changed_directories) { | 670 if (should_notify_changed_directories) { |
| 753 for (std::set<base::FilePath>::iterator dir_iter = | 671 for (std::set<base::FilePath>::iterator dir_iter = |
| 754 change_list_processor_->changed_dirs().begin(); | 672 change_list_processor_->changed_dirs().begin(); |
| 755 dir_iter != change_list_processor_->changed_dirs().end(); | 673 dir_iter != change_list_processor_->changed_dirs().end(); |
| 756 ++dir_iter) { | 674 ++dir_iter) { |
| 757 FOR_EACH_OBSERVER(ChangeListLoaderObserver, observers_, | 675 FOR_EACH_OBSERVER(ChangeListLoaderObserver, observers_, |
| 758 OnDirectoryChanged(*dir_iter)); | 676 OnDirectoryChanged(*dir_iter)); |
| 759 } | 677 } |
| 760 } | 678 } |
| 761 | 679 |
| 762 update_finished_callback.Run(); | 680 update_finished_callback.Run(); |
| 763 | 681 |
| 764 // Cannot delete change_list_processor_ yet because we are in | 682 // Cannot delete change_list_processor_ yet because we are in |
| 765 // on_complete_callback_, which is owned by change_list_processor_. | 683 // on_complete_callback_, which is owned by change_list_processor_. |
| 766 } | 684 } |
| 767 | 685 |
| 768 void ChangeListLoader::OnUpdateFromFeed( | 686 void ChangeListLoader::OnUpdateFromFeed() { |
| 769 bool is_inital_load, | |
| 770 const FileOperationCallback& callback) { | |
| 771 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 772 DCHECK(!callback.is_null()); | |
| 773 | 688 |
| 774 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); | 689 OnChangeListLoadComplete(DRIVE_FILE_OK); |
| 775 if (is_inital_load) { | |
| 776 FOR_EACH_OBSERVER(ChangeListLoaderObserver, | |
| 777 observers_, | |
| 778 OnInitialFeedLoaded()); | |
| 779 } | |
| 780 | 690 |
| 781 FOR_EACH_OBSERVER(ChangeListLoaderObserver, | 691 FOR_EACH_OBSERVER(ChangeListLoaderObserver, |
| 782 observers_, | 692 observers_, |
| 783 OnFeedFromServerLoaded()); | 693 OnFeedFromServerLoaded()); |
| 784 } | 694 } |
| 785 | 695 |
| 786 void ChangeListLoader::OnChangeListLoadComplete( | 696 void ChangeListLoader::OnChangeListLoadComplete(DriveFileError error) { |
| 787 const FileOperationCallback& callback, | |
| 788 DriveFileError error) { | |
| 789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 790 DCHECK(!callback.is_null()); | |
| 791 | 698 |
| 792 refreshing_ = false; | 699 if (!loaded_ && error == DRIVE_FILE_OK) { |
| 793 callback.Run(error); | 700 loaded_ = true; |
| 794 FlushPendingLoadCallback(error); | 701 FOR_EACH_OBSERVER(ChangeListLoaderObserver, |
| 795 } | 702 observers_, |
| 796 | 703 OnInitialFeedLoaded()); |
| 797 void ChangeListLoader::OnDirectoryLoadComplete( | 704 } |
| 798 const DirectoryFetchInfo& directory_fetch_info, | |
| 799 const FileOperationCallback& callback, | |
| 800 DriveFileError error) { | |
| 801 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 802 DCHECK(!callback.is_null()); | |
| 803 | |
| 804 callback.Run(error); | |
| 805 ProcessPendingLoadCallbackForDirectory(directory_fetch_info.resource_id(), | |
| 806 error); | |
| 807 } | |
| 808 | |
| 809 void ChangeListLoader::FlushPendingLoadCallback(DriveFileError error) { | |
| 810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 811 DCHECK(!refreshing_); | |
| 812 | 705 |
| 813 for (LoadCallbackMap::iterator it = pending_load_callback_.begin(); | 706 for (LoadCallbackMap::iterator it = pending_load_callback_.begin(); |
| 814 it != pending_load_callback_.end(); ++it) { | 707 it != pending_load_callback_.end(); ++it) { |
| 815 const std::vector<FileOperationCallback>& callbacks = it->second; | 708 const std::vector<FileOperationCallback>& callbacks = it->second; |
| 816 for (size_t i = 0; i < callbacks.size(); ++i) { | 709 for (size_t i = 0; i < callbacks.size(); ++i) { |
| 817 base::MessageLoopProxy::current()->PostTask( | 710 base::MessageLoopProxy::current()->PostTask( |
| 818 FROM_HERE, | 711 FROM_HERE, |
| 819 base::Bind(callbacks[i], error)); | 712 base::Bind(callbacks[i], error)); |
| 820 } | 713 } |
| 821 } | 714 } |
| 822 pending_load_callback_.clear(); | 715 pending_load_callback_.clear(); |
| 823 } | 716 } |
| 824 | 717 |
| 825 void ChangeListLoader::ProcessPendingLoadCallbackForDirectory( | 718 void ChangeListLoader::OnDirectoryLoadComplete( |
| 826 const std::string& resource_id, | 719 const DirectoryFetchInfo& directory_fetch_info, |
| 827 DriveFileError error) { | 720 DriveFileError error) { |
| 828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 721 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 829 | 722 |
| 723 if (error == DRIVE_FILE_OK) { | |
| 724 DVLOG(1) << "Fast-fetch was successful: " | |
|
hashimoto
2013/04/17 08:15:37
nit: How about using DVLOG_IF?
kinaba
2013/04/17 08:46:23
Done.
| |
| 725 << directory_fetch_info.ToString(); | |
| 726 } | |
| 727 | |
| 728 const std::string& resource_id = directory_fetch_info.resource_id(); | |
| 830 LoadCallbackMap::iterator it = pending_load_callback_.find(resource_id); | 729 LoadCallbackMap::iterator it = pending_load_callback_.find(resource_id); |
| 831 if (it != pending_load_callback_.end()) { | 730 if (it != pending_load_callback_.end()) { |
| 832 DVLOG(1) << "Running callback for " << resource_id; | 731 DVLOG(1) << "Running callback for " << resource_id; |
| 833 const std::vector<FileOperationCallback>& callbacks = it->second; | 732 const std::vector<FileOperationCallback>& callbacks = it->second; |
| 834 for (size_t i = 0; i < callbacks.size(); ++i) { | 733 for (size_t i = 0; i < callbacks.size(); ++i) { |
| 835 base::MessageLoopProxy::current()->PostTask( | 734 base::MessageLoopProxy::current()->PostTask( |
| 836 FROM_HERE, | 735 FROM_HERE, |
| 837 base::Bind(callbacks[i], error)); | 736 base::Bind(callbacks[i], error)); |
| 838 } | 737 } |
| 839 pending_load_callback_.erase(it); | 738 pending_load_callback_.erase(it); |
| 840 } | 739 } |
| 841 } | 740 } |
| 842 | 741 |
| 843 } // namespace drive | 742 } // namespace drive |
| OLD | NEW |