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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 // Loaded feed may be partial due to size limit on a single feed. In that case, | 121 // Loaded feed may be partial due to size limit on a single feed. In that case, |
122 // the loaded feed will have next feed url set. Iff |load_subsequent_feeds| | 122 // the loaded feed will have next feed url set. Iff |load_subsequent_feeds| |
123 // parameter is set, feed loader will load all subsequent feeds. | 123 // parameter is set, feed loader will load all subsequent feeds. |
124 // | 124 // |
125 // If invoked as a part of content search, query will be set in |search_query|. | 125 // If invoked as a part of content search, query will be set in |search_query|. |
126 // If |feed_to_load| is set, this is feed url that will be used to load feed. | 126 // If |feed_to_load| is set, this is feed url that will be used to load feed. |
127 // | 127 // |
128 // When all feeds are loaded, |feed_load_callback| is invoked with the retrieved | 128 // When all feeds are loaded, |feed_load_callback| is invoked with the retrieved |
129 // feeds. |feed_load_callback| must not be null. | 129 // feeds. |feed_load_callback| must not be null. |
130 struct ChangeListLoader::LoadFeedParams { | 130 struct ChangeListLoader::LoadFeedParams { |
131 explicit LoadFeedParams(const LoadFeedListCallback& feed_load_callback) | 131 LoadFeedParams() |
132 : start_changestamp(0), | 132 : start_changestamp(0), |
133 shared_with_me(false), | 133 shared_with_me(false), |
134 load_subsequent_feeds(true), | 134 load_subsequent_feeds(true) {} |
135 feed_load_callback(feed_load_callback) {} | |
136 | |
137 // Runs this->feed_load_callback with |error|. | |
138 void RunFeedLoadCallback(DriveFileError error) { | |
139 feed_load_callback.Run(feed_list, error); | |
140 } | |
141 | 135 |
142 // Changestamps are positive numbers in increasing order. The difference | 136 // Changestamps are positive numbers in increasing order. The difference |
143 // between two changestamps is proportional equal to number of items in | 137 // between two changestamps is proportional equal to number of items in |
144 // delta feed between them - bigger the difference, more likely bigger | 138 // delta feed between them - bigger the difference, more likely bigger |
145 // number of items in delta feeds. | 139 // number of items in delta feeds. |
146 int64 start_changestamp; | 140 int64 start_changestamp; |
147 std::string search_query; | 141 std::string search_query; |
148 bool shared_with_me; | 142 bool shared_with_me; |
149 std::string directory_resource_id; | 143 std::string directory_resource_id; |
150 GURL feed_to_load; | 144 GURL feed_to_load; |
151 bool load_subsequent_feeds; | 145 bool load_subsequent_feeds; |
152 const LoadFeedListCallback feed_load_callback; | |
153 ScopedVector<google_apis::ResourceList> feed_list; | 146 ScopedVector<google_apis::ResourceList> feed_list; |
154 scoped_ptr<GetResourceListUiState> ui_state; | 147 scoped_ptr<GetResourceListUiState> ui_state; |
155 }; | 148 }; |
156 | 149 |
157 // Defines set of parameters sent to callback OnProtoLoaded(). | 150 // Defines set of parameters sent to callback OnProtoLoaded(). |
158 struct ChangeListLoader::LoadRootFeedParams { | 151 struct ChangeListLoader::LoadRootFeedParams { |
159 explicit LoadRootFeedParams(const FileOperationCallback& callback) | 152 explicit LoadRootFeedParams(const FileOperationCallback& callback) |
160 : load_start_time(base::Time::Now()), | 153 : load_start_time(base::Time::Now()), |
161 callback(callback) {} | 154 callback(callback) {} |
162 | 155 |
163 std::string proto; | 156 std::string proto; |
164 base::Time last_modified; | 157 base::Time last_modified; |
165 // Time when filesystem began to be loaded from disk. | 158 // Time when filesystem began to be loaded from disk. |
166 base::Time load_start_time; | 159 base::Time load_start_time; |
167 const FileOperationCallback callback; | 160 const FileOperationCallback callback; |
168 }; | 161 }; |
169 | 162 |
170 // Defines parameters sent to UpdateMetadataFromFeedAfterLoadFromServer(). | |
171 // | |
172 // In the case of loading the root feed we use |root_feed_changestamp| as its | |
173 // initial changestamp value since it does not come with that info. | |
174 // | |
175 // On initial feed load for Drive API, remember root ID for | |
176 // DriveResourceData initialization later in UpdateFromFeed(). | |
177 struct ChangeListLoader::UpdateMetadataParams { | |
178 UpdateMetadataParams(bool is_delta_feed, | |
179 int64 feed_changestamp, | |
180 const FileOperationCallback& callback) | |
181 : is_delta_feed(is_delta_feed), | |
182 feed_changestamp(feed_changestamp), | |
183 callback(callback) {} | |
184 | |
185 const bool is_delta_feed; | |
186 const int64 feed_changestamp; | |
187 const FileOperationCallback callback; | |
188 }; | |
189 | |
190 // Defines set of parameters sent to callback OnNotifyResourceListFetched(). | 163 // Defines set of parameters sent to callback OnNotifyResourceListFetched(). |
191 // This is a trick to update the number of fetched documents frequently on | 164 // This is a trick to update the number of fetched documents frequently on |
192 // UI. Due to performance reason, we need to fetch a number of files at | 165 // UI. Due to performance reason, we need to fetch a number of files at |
193 // a time. However, it'll take long time, and a user has no way to know | 166 // a time. However, it'll take long time, and a user has no way to know |
194 // the current update state. In order to make users comfortable, | 167 // the current update state. In order to make users comfortable, |
195 // we increment the number of fetched documents with more frequent but smaller | 168 // we increment the number of fetched documents with more frequent but smaller |
196 // steps than actual fetching. | 169 // steps than actual fetching. |
197 struct ChangeListLoader::GetResourceListUiState { | 170 struct ChangeListLoader::GetResourceListUiState { |
198 explicit GetResourceListUiState(base::TimeTicks start_time) | 171 explicit GetResourceListUiState(base::TimeTicks start_time) |
199 : num_fetched_documents(0), | 172 : num_fetched_documents(0), |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 << local_changestamp | 294 << local_changestamp |
322 << ", server = " | 295 << ", server = " |
323 << remote_changestamp; | 296 << remote_changestamp; |
324 } | 297 } |
325 | 298 |
326 // No changes detected, tell the client that the loading was successful. | 299 // No changes detected, tell the client that the loading was successful. |
327 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); | 300 OnChangeListLoadComplete(callback, DRIVE_FILE_OK); |
328 return; | 301 return; |
329 } | 302 } |
330 | 303 |
331 // Load changes from the server. | |
332 int64 start_changestamp = local_changestamp > 0 ? local_changestamp + 1 : 0; | 304 int64 start_changestamp = local_changestamp > 0 ? local_changestamp + 1 : 0; |
333 scoped_ptr<LoadFeedParams> load_params(new LoadFeedParams( | 305 |
| 306 // TODO(satorux): Use directory_fetch_info to start "fast-fetch" here. |
| 307 LoadChangeListFromServer(start_changestamp, |
| 308 remote_changestamp, |
| 309 callback); |
| 310 } |
| 311 |
| 312 void ChangeListLoader::LoadChangeListFromServer( |
| 313 int64 start_changestamp, |
| 314 int64 remote_changestamp, |
| 315 const FileOperationCallback& callback) { |
| 316 scoped_ptr<LoadFeedParams> load_params(new LoadFeedParams); |
| 317 load_params->start_changestamp = start_changestamp; |
| 318 LoadFromServer( |
| 319 load_params.Pass(), |
334 base::Bind(&ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer, | 320 base::Bind(&ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer, |
335 weak_ptr_factory_.GetWeakPtr(), | 321 weak_ptr_factory_.GetWeakPtr(), |
336 UpdateMetadataParams(start_changestamp != 0, // is_delta_feed | 322 start_changestamp != 0, // is_delta_feed |
337 remote_changestamp, | 323 remote_changestamp, |
338 callback)))); | 324 callback)); |
339 load_params->start_changestamp = start_changestamp; | |
340 | |
341 // TODO(satorux): Use directory_fetch_info to start "fast-fetch" here. | |
342 LoadFromServer(load_params.Pass()); | |
343 } | 325 } |
344 | 326 |
345 void ChangeListLoader::OnGetAppList(google_apis::GDataErrorCode status, | 327 void ChangeListLoader::OnGetAppList(google_apis::GDataErrorCode status, |
346 scoped_ptr<google_apis::AppList> app_list) { | 328 scoped_ptr<google_apis::AppList> app_list) { |
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
348 | 330 |
349 DriveFileError error = util::GDataToDriveFileError(status); | 331 DriveFileError error = util::GDataToDriveFileError(status); |
350 if (error != DRIVE_FILE_OK) | 332 if (error != DRIVE_FILE_OK) |
351 return; | 333 return; |
352 | 334 |
353 if (app_list.get()) { | 335 if (app_list.get()) { |
354 webapps_registry_->UpdateFromAppList(*app_list); | 336 webapps_registry_->UpdateFromAppList(*app_list); |
355 } | 337 } |
356 } | 338 } |
357 | 339 |
358 void ChangeListLoader::LoadFromServer(scoped_ptr<LoadFeedParams> params) { | 340 void ChangeListLoader::LoadFromServer(scoped_ptr<LoadFeedParams> params, |
| 341 const LoadFeedListCallback& callback) { |
359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 343 DCHECK(!callback.is_null()); |
360 | 344 |
361 const base::TimeTicks start_time = base::TimeTicks::Now(); | 345 const base::TimeTicks start_time = base::TimeTicks::Now(); |
362 | 346 |
363 // base::Passed() may get evaluated first, so get a pointer to params. | 347 // base::Passed() may get evaluated first, so get a pointer to params. |
364 LoadFeedParams* params_ptr = params.get(); | 348 LoadFeedParams* params_ptr = params.get(); |
365 scheduler_->GetResourceList( | 349 scheduler_->GetResourceList( |
366 params_ptr->feed_to_load, | 350 params_ptr->feed_to_load, |
367 params_ptr->start_changestamp, | 351 params_ptr->start_changestamp, |
368 params_ptr->search_query, | 352 params_ptr->search_query, |
369 params_ptr->shared_with_me, | 353 params_ptr->shared_with_me, |
370 params_ptr->directory_resource_id, | 354 params_ptr->directory_resource_id, |
371 base::Bind(&ChangeListLoader::OnGetResourceList, | 355 base::Bind(&ChangeListLoader::LoadFromServerAfterGetResourceList, |
372 weak_ptr_factory_.GetWeakPtr(), | 356 weak_ptr_factory_.GetWeakPtr(), |
373 base::Passed(¶ms), | 357 base::Passed(¶ms), |
| 358 callback, |
374 start_time)); | 359 start_time)); |
375 } | 360 } |
376 | 361 |
377 void ChangeListLoader::LoadDirectoryFromServer( | 362 void ChangeListLoader::LoadDirectoryFromServer( |
378 const std::string& directory_resource_id, | 363 const std::string& directory_resource_id, |
379 const FileOperationCallback& callback) { | 364 const FileOperationCallback& callback) { |
380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
381 DCHECK(!callback.is_null()); | 366 DCHECK(!callback.is_null()); |
382 | 367 |
383 // First fetch the latest changestamp to see if this directory needs to be | 368 // First fetch the latest changestamp to see if this directory needs to be |
(...skipping 25 matching lines...) Expand all Loading... |
409 DoLoadDirectoryFromServer(directory_fetch_info, callback); | 394 DoLoadDirectoryFromServer(directory_fetch_info, callback); |
410 } | 395 } |
411 | 396 |
412 void ChangeListLoader::DoLoadDirectoryFromServer( | 397 void ChangeListLoader::DoLoadDirectoryFromServer( |
413 const DirectoryFetchInfo& directory_fetch_info, | 398 const DirectoryFetchInfo& directory_fetch_info, |
414 const FileOperationCallback& callback) { | 399 const FileOperationCallback& callback) { |
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
416 DCHECK(!callback.is_null()); | 401 DCHECK(!callback.is_null()); |
417 DCHECK(!directory_fetch_info.empty()); | 402 DCHECK(!directory_fetch_info.empty()); |
418 | 403 |
419 scoped_ptr<LoadFeedParams> params(new LoadFeedParams( | 404 scoped_ptr<LoadFeedParams> params(new LoadFeedParams); |
| 405 params->directory_resource_id = directory_fetch_info.resource_id(); |
| 406 LoadFromServer( |
| 407 params.Pass(), |
420 base::Bind(&ChangeListLoader::DoLoadDirectoryFromServerAfterLoad, | 408 base::Bind(&ChangeListLoader::DoLoadDirectoryFromServerAfterLoad, |
421 weak_ptr_factory_.GetWeakPtr(), | 409 weak_ptr_factory_.GetWeakPtr(), |
422 directory_fetch_info, | 410 directory_fetch_info, |
423 callback))); | 411 callback)); |
424 params->directory_resource_id = directory_fetch_info.resource_id(); | |
425 LoadFromServer(params.Pass()); | |
426 } | 412 } |
427 | 413 |
428 void ChangeListLoader::DoLoadDirectoryFromServerAfterLoad( | 414 void ChangeListLoader::DoLoadDirectoryFromServerAfterLoad( |
429 const DirectoryFetchInfo& directory_fetch_info, | 415 const DirectoryFetchInfo& directory_fetch_info, |
430 const FileOperationCallback& callback, | 416 const FileOperationCallback& callback, |
431 const ScopedVector<google_apis::ResourceList>& resource_list, | 417 const ScopedVector<google_apis::ResourceList>& resource_list, |
432 DriveFileError error) { | 418 DriveFileError error) { |
433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
434 DCHECK(!callback.is_null()); | 420 DCHECK(!callback.is_null()); |
435 DCHECK(!directory_fetch_info.empty()); | 421 DCHECK(!directory_fetch_info.empty()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 455 } |
470 } | 456 } |
471 | 457 |
472 void ChangeListLoader::SearchFromServer( | 458 void ChangeListLoader::SearchFromServer( |
473 const std::string& search_query, | 459 const std::string& search_query, |
474 bool shared_with_me, | 460 bool shared_with_me, |
475 const GURL& next_feed, | 461 const GURL& next_feed, |
476 const LoadFeedListCallback& feed_load_callback) { | 462 const LoadFeedListCallback& feed_load_callback) { |
477 DCHECK(!feed_load_callback.is_null()); | 463 DCHECK(!feed_load_callback.is_null()); |
478 | 464 |
479 scoped_ptr<LoadFeedParams> params(new LoadFeedParams(feed_load_callback)); | 465 scoped_ptr<LoadFeedParams> params(new LoadFeedParams); |
480 params->search_query = search_query; | 466 params->search_query = search_query; |
481 params->shared_with_me = shared_with_me; | 467 params->shared_with_me = shared_with_me; |
482 params->feed_to_load = next_feed; | 468 params->feed_to_load = next_feed; |
483 params->load_subsequent_feeds = false; | 469 params->load_subsequent_feeds = false; |
484 LoadFromServer(params.Pass()); | 470 LoadFromServer(params.Pass(), feed_load_callback); |
485 } | 471 } |
486 | 472 |
487 void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer( | 473 void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer( |
488 const UpdateMetadataParams& params, | 474 bool is_delta_feed, |
| 475 int64 feed_changestamp, |
| 476 const FileOperationCallback& callback, |
489 const ScopedVector<google_apis::ResourceList>& feed_list, | 477 const ScopedVector<google_apis::ResourceList>& feed_list, |
490 DriveFileError error) { | 478 DriveFileError error) { |
491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
492 DCHECK(!params.callback.is_null()); | 480 DCHECK(!callback.is_null()); |
493 DCHECK(refreshing_); | 481 DCHECK(refreshing_); |
494 | 482 |
495 if (error != DRIVE_FILE_OK) { | 483 if (error != DRIVE_FILE_OK) { |
496 OnChangeListLoadComplete(params.callback, error); | 484 OnChangeListLoadComplete(callback, error); |
497 return; | 485 return; |
498 } | 486 } |
499 | 487 |
500 UpdateFromFeed(feed_list, | 488 UpdateFromFeed(feed_list, |
501 params.is_delta_feed, | 489 is_delta_feed, |
502 params.feed_changestamp, | 490 feed_changestamp, |
503 base::Bind(&ChangeListLoader::OnUpdateFromFeed, | 491 base::Bind(&ChangeListLoader::OnUpdateFromFeed, |
504 weak_ptr_factory_.GetWeakPtr(), | 492 weak_ptr_factory_.GetWeakPtr(), |
505 params.callback)); | 493 callback)); |
506 } | 494 } |
507 | 495 |
508 void ChangeListLoader::OnGetResourceList( | 496 void ChangeListLoader::LoadFromServerAfterGetResourceList( |
509 scoped_ptr<LoadFeedParams> params, | 497 scoped_ptr<LoadFeedParams> params, |
| 498 const LoadFeedListCallback& callback, |
510 base::TimeTicks start_time, | 499 base::TimeTicks start_time, |
511 google_apis::GDataErrorCode status, | 500 google_apis::GDataErrorCode status, |
512 scoped_ptr<google_apis::ResourceList> resource_list) { | 501 scoped_ptr<google_apis::ResourceList> resource_list) { |
513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 503 DCHECK(!callback.is_null()); |
514 | 504 |
515 if (params->feed_list.empty()) { | 505 if (params->feed_list.empty()) { |
516 UMA_HISTOGRAM_TIMES("Drive.InitialFeedLoadTime", | 506 UMA_HISTOGRAM_TIMES("Drive.InitialFeedLoadTime", |
517 base::TimeTicks::Now() - start_time); | 507 base::TimeTicks::Now() - start_time); |
518 } | 508 } |
519 | 509 |
520 DriveFileError error = util::GDataToDriveFileError(status); | 510 DriveFileError error = util::GDataToDriveFileError(status); |
521 if (error != DRIVE_FILE_OK) { | 511 if (error != DRIVE_FILE_OK) { |
522 params->RunFeedLoadCallback(error); | 512 callback.Run(params->feed_list, error); |
523 return; | 513 return; |
524 } | 514 } |
525 DCHECK(resource_list); | 515 DCHECK(resource_list); |
526 | 516 |
527 GURL next_feed_url; | 517 GURL next_feed_url; |
528 const bool has_next_feed_url = | 518 const bool has_next_feed_url = |
529 params->load_subsequent_feeds && | 519 params->load_subsequent_feeds && |
530 resource_list->GetNextFeedURL(&next_feed_url); | 520 resource_list->GetNextFeedURL(&next_feed_url); |
531 | 521 |
532 // Add the current feed to the list of collected feeds for this directory. | 522 // Add the current feed to the list of collected feeds for this directory. |
(...skipping 29 matching lines...) Expand all Loading... |
562 // |params| will be passed to the callback and thus nulled. Extract the | 552 // |params| will be passed to the callback and thus nulled. Extract the |
563 // pointer so we can use it bellow. | 553 // pointer so we can use it bellow. |
564 LoadFeedParams* params_ptr = params.get(); | 554 LoadFeedParams* params_ptr = params.get(); |
565 // Kick off the remaining part of the feeds. | 555 // Kick off the remaining part of the feeds. |
566 scheduler_->GetResourceList( | 556 scheduler_->GetResourceList( |
567 next_feed_url, | 557 next_feed_url, |
568 params_ptr->start_changestamp, | 558 params_ptr->start_changestamp, |
569 params_ptr->search_query, | 559 params_ptr->search_query, |
570 params_ptr->shared_with_me, | 560 params_ptr->shared_with_me, |
571 params_ptr->directory_resource_id, | 561 params_ptr->directory_resource_id, |
572 base::Bind(&ChangeListLoader::OnGetResourceList, | 562 base::Bind(&ChangeListLoader::LoadFromServerAfterGetResourceList, |
573 weak_ptr_factory_.GetWeakPtr(), | 563 weak_ptr_factory_.GetWeakPtr(), |
574 base::Passed(¶ms), | 564 base::Passed(¶ms), |
| 565 callback, |
575 start_time)); | 566 start_time)); |
576 return; | 567 return; |
577 } | 568 } |
578 | 569 |
579 // Notify the observers that all document feeds are fetched. | 570 // Notify the observers that all document feeds are fetched. |
580 FOR_EACH_OBSERVER(ChangeListLoaderObserver, observers_, | 571 FOR_EACH_OBSERVER(ChangeListLoaderObserver, observers_, |
581 OnResourceListFetched(num_accumulated_entries)); | 572 OnResourceListFetched(num_accumulated_entries)); |
582 | 573 |
583 UMA_HISTOGRAM_TIMES("Drive.EntireFeedLoadTime", | 574 UMA_HISTOGRAM_TIMES("Drive.EntireFeedLoadTime", |
584 base::TimeTicks::Now() - start_time); | 575 base::TimeTicks::Now() - start_time); |
585 | 576 |
586 // Run the callback so the client can process the retrieved feeds. | 577 // Run the callback so the client can process the retrieved feeds. |
587 params->RunFeedLoadCallback(DRIVE_FILE_OK); | 578 callback.Run(params->feed_list, DRIVE_FILE_OK); |
588 } | 579 } |
589 | 580 |
590 void ChangeListLoader::OnNotifyResourceListFetched( | 581 void ChangeListLoader::OnNotifyResourceListFetched( |
591 base::WeakPtr<GetResourceListUiState> ui_state) { | 582 base::WeakPtr<GetResourceListUiState> ui_state) { |
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 583 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
593 | 584 |
594 if (!ui_state) { | 585 if (!ui_state) { |
595 // The ui state instance is already released, which means the fetching | 586 // The ui state instance is already released, which means the fetching |
596 // is done and we don't need to update any more. | 587 // is done and we don't need to update any more. |
597 return; | 588 return; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 QueuedCallbackInfo info = queue_.front(); | 823 QueuedCallbackInfo info = queue_.front(); |
833 const FileOperationCallback& callback = info.second; | 824 const FileOperationCallback& callback = info.second; |
834 queue_.pop(); | 825 queue_.pop(); |
835 base::MessageLoopProxy::current()->PostTask( | 826 base::MessageLoopProxy::current()->PostTask( |
836 FROM_HERE, | 827 FROM_HERE, |
837 base::Bind(callback, error)); | 828 base::Bind(callback, error)); |
838 } | 829 } |
839 } | 830 } |
840 | 831 |
841 } // namespace drive | 832 } // namespace drive |
OLD | NEW |