| 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/gdata/gdata_wapi_feed_loader.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_wapi_feed_loader.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/format_macros.h" |
| 9 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 10 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
| 11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 13 #include "base/stringprintf.h" | 14 #include "base/stringprintf.h" |
| 14 #include "base/threading/sequenced_worker_pool.h" | 15 #include "base/threading/sequenced_worker_pool.h" |
| 15 #include "chrome/browser/chromeos/gdata/drive_webapps_registry.h" | 16 #include "chrome/browser/chromeos/gdata/drive_webapps_registry.h" |
| 17 #include "chrome/browser/chromeos/gdata/drive_api_parser.h" |
| 16 #include "chrome/browser/chromeos/gdata/gdata_cache.h" | 18 #include "chrome/browser/chromeos/gdata/gdata_cache.h" |
| 17 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h" | 19 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h" |
| 18 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 20 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
| 19 #include "chrome/browser/chromeos/gdata/gdata_wapi_feed_processor.h" | 21 #include "chrome/browser/chromeos/gdata/gdata_wapi_feed_processor.h" |
| 20 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| 21 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 22 | 24 |
| 23 using content::BrowserThread; | 25 using content::BrowserThread; |
| 24 | 26 |
| 25 namespace gdata { | 27 namespace gdata { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 } | 131 } |
| 130 | 132 |
| 131 bool UseLevelDB() { | 133 bool UseLevelDB() { |
| 132 return CommandLine::ForCurrentProcess()->HasSwitch( | 134 return CommandLine::ForCurrentProcess()->HasSwitch( |
| 133 switches::kUseLevelDBForGData); | 135 switches::kUseLevelDBForGData); |
| 134 } | 136 } |
| 135 | 137 |
| 136 } // namespace | 138 } // namespace |
| 137 | 139 |
| 138 GetDocumentsParams::GetDocumentsParams( | 140 GetDocumentsParams::GetDocumentsParams( |
| 139 int start_changestamp, | 141 int64 start_changestamp, |
| 140 int root_feed_changestamp, | 142 int64 root_feed_changestamp, |
| 141 std::vector<DocumentFeed*>* feed_list, | 143 std::vector<DocumentFeed*>* feed_list, |
| 142 bool should_fetch_multiple_feeds, | 144 bool should_fetch_multiple_feeds, |
| 143 const FilePath& search_file_path, | 145 const FilePath& search_file_path, |
| 144 const std::string& search_query, | 146 const std::string& search_query, |
| 145 const std::string& directory_resource_id, | 147 const std::string& directory_resource_id, |
| 146 const FindEntryCallback& callback, | 148 const FindEntryCallback& callback, |
| 147 GetDocumentsUiState* ui_state) | 149 GetDocumentsUiState* ui_state) |
| 148 : start_changestamp(start_changestamp), | 150 : start_changestamp(start_changestamp), |
| 149 root_feed_changestamp(root_feed_changestamp), | 151 root_feed_changestamp(root_feed_changestamp), |
| 150 feed_list(feed_list), | 152 feed_list(feed_list), |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 observers_.AddObserver(observer); | 214 observers_.AddObserver(observer); |
| 213 } | 215 } |
| 214 | 216 |
| 215 void GDataWapiFeedLoader::RemoveObserver(Observer* observer) { | 217 void GDataWapiFeedLoader::RemoveObserver(Observer* observer) { |
| 216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 217 observers_.RemoveObserver(observer); | 219 observers_.RemoveObserver(observer); |
| 218 } | 220 } |
| 219 | 221 |
| 220 void GDataWapiFeedLoader::ReloadFromServerIfNeeded( | 222 void GDataWapiFeedLoader::ReloadFromServerIfNeeded( |
| 221 ContentOrigin initial_origin, | 223 ContentOrigin initial_origin, |
| 222 int local_changestamp, | 224 int64 local_changestamp, |
| 223 const FilePath& search_file_path, | 225 const FilePath& search_file_path, |
| 224 const FindEntryCallback& callback) { | 226 const FindEntryCallback& callback) { |
| 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 226 | 228 |
| 227 DVLOG(1) << "ReloadFeedFromServerIfNeeded local_changestamp=" | 229 DVLOG(1) << "ReloadFeedFromServerIfNeeded local_changestamp=" |
| 228 << local_changestamp << ", initial_origin=" << initial_origin; | 230 << local_changestamp << ", initial_origin=" << initial_origin; |
| 229 | 231 |
| 230 // First fetch the latest changestamp to see if there were any new changes | 232 // First fetch the latest changestamp to see if there were any new changes |
| 231 // there at all. | 233 // there at all. |
| 234 if (gdata::util::IsDriveV2ApiEnabled()) { |
| 235 documents_service_->GetAboutResource( |
| 236 base::Bind(&GDataWapiFeedLoader::OnGetAboutResource, |
| 237 weak_ptr_factory_.GetWeakPtr(), |
| 238 initial_origin, |
| 239 local_changestamp, |
| 240 search_file_path, |
| 241 callback)); |
| 242 return; |
| 243 } |
| 244 |
| 232 documents_service_->GetAccountMetadata( | 245 documents_service_->GetAccountMetadata( |
| 233 base::Bind(&GDataWapiFeedLoader::OnGetAccountMetadata, | 246 base::Bind(&GDataWapiFeedLoader::OnGetAccountMetadata, |
| 234 weak_ptr_factory_.GetWeakPtr(), | 247 weak_ptr_factory_.GetWeakPtr(), |
| 235 initial_origin, | 248 initial_origin, |
| 236 local_changestamp, | 249 local_changestamp, |
| 237 search_file_path, | 250 search_file_path, |
| 238 callback)); | 251 callback)); |
| 239 } | 252 } |
| 240 | 253 |
| 241 void GDataWapiFeedLoader::OnGetAccountMetadata( | 254 void GDataWapiFeedLoader::OnGetAccountMetadata( |
| 242 ContentOrigin initial_origin, | 255 ContentOrigin initial_origin, |
| 243 int local_changestamp, | 256 int64 local_changestamp, |
| 244 const FilePath& search_file_path, | 257 const FilePath& search_file_path, |
| 245 const FindEntryCallback& callback, | 258 const FindEntryCallback& callback, |
| 246 GDataErrorCode status, | 259 GDataErrorCode status, |
| 247 scoped_ptr<base::Value> feed_data) { | 260 scoped_ptr<base::Value> feed_data) { |
| 248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 249 | 262 |
| 250 GDataFileError error = util::GDataToGDataFileError(status); | 263 GDataFileError error = util::GDataToGDataFileError(status); |
| 251 if (error != GDATA_FILE_OK) { | 264 if (error != GDATA_FILE_OK) { |
| 252 // Get changes starting from the next changestamp from what we have locally. | 265 // Get changes starting from the next changestamp from what we have locally. |
| 253 LoadFromServer(initial_origin, | 266 LoadFromServer(initial_origin, |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 true, /* should_fetch_multiple_feeds */ | 339 true, /* should_fetch_multiple_feeds */ |
| 327 search_file_path, | 340 search_file_path, |
| 328 std::string() /* no search query */, | 341 std::string() /* no search query */, |
| 329 GURL(), /* feed not explicitly set */ | 342 GURL(), /* feed not explicitly set */ |
| 330 std::string() /* no directory resource ID */, | 343 std::string() /* no directory resource ID */, |
| 331 callback, | 344 callback, |
| 332 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded, | 345 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded, |
| 333 weak_ptr_factory_.GetWeakPtr())); | 346 weak_ptr_factory_.GetWeakPtr())); |
| 334 } | 347 } |
| 335 | 348 |
| 349 void GDataWapiFeedLoader::OnGetAboutResource( |
| 350 ContentOrigin initial_origin, |
| 351 int64 local_changestamp, |
| 352 const FilePath& search_file_path, |
| 353 const FindEntryCallback& callback, |
| 354 GDataErrorCode status, |
| 355 scoped_ptr<base::Value> feed_data) { |
| 356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 357 |
| 358 GDataFileError error = util::GDataToGDataFileError(status); |
| 359 if (error != GDATA_FILE_OK) { |
| 360 // Get changes starting from the next changestamp from what we have locally. |
| 361 LoadFromServer(initial_origin, |
| 362 local_changestamp + 1, 0, |
| 363 true, /* should_fetch_multiple_feeds */ |
| 364 search_file_path, |
| 365 std::string() /* no search query */, |
| 366 GURL(), /* feed not explicitly set */ |
| 367 std::string() /* no directory resource ID */, |
| 368 callback, |
| 369 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded, |
| 370 weak_ptr_factory_.GetWeakPtr())); |
| 371 return; |
| 372 } |
| 373 |
| 374 scoped_ptr<AboutResource> about_resource; |
| 375 if (feed_data.get()) |
| 376 about_resource = AboutResource::CreateFrom(*feed_data); |
| 377 |
| 378 if (!about_resource.get()) { |
| 379 LoadFromServer(initial_origin, |
| 380 local_changestamp + 1, 0, |
| 381 true, /* should_fetch_multiple_feeds */ |
| 382 search_file_path, |
| 383 std::string() /* no search query */, |
| 384 GURL(), /* feed not explicitly set */ |
| 385 std::string() /* no directory resource ID */, |
| 386 callback, |
| 387 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded, |
| 388 weak_ptr_factory_.GetWeakPtr())); |
| 389 return; |
| 390 } |
| 391 |
| 392 bool changes_detected = true; |
| 393 int64 largest_changestamp = about_resource->largest_change_id(); |
| 394 directory_service_->InitializeRootEntry(about_resource->root_folder_id()); |
| 395 |
| 396 if (local_changestamp >= largest_changestamp) { |
| 397 if (local_changestamp > largest_changestamp) { |
| 398 LOG(WARNING) << "Cached client feed is fresher than server, client = " |
| 399 << local_changestamp |
| 400 << ", server = " |
| 401 << largest_changestamp; |
| 402 } |
| 403 // If our cache holds the latest state from the server, change the |
| 404 // state to FROM_SERVER. |
| 405 directory_service_->set_origin( |
| 406 initial_origin == FROM_CACHE ? FROM_SERVER : initial_origin); |
| 407 changes_detected = false; |
| 408 } |
| 409 |
| 410 // No changes detected, continue with search as planned. |
| 411 if (!changes_detected) { |
| 412 if (!callback.is_null()) { |
| 413 directory_service_->FindEntryByPathAndRunSync(search_file_path, |
| 414 callback); |
| 415 } |
| 416 return; |
| 417 } |
| 418 |
| 419 // Load changes from the server. |
| 420 LoadFromServer(initial_origin, |
| 421 local_changestamp > 0 ? local_changestamp + 1 : 0, |
| 422 largest_changestamp, |
| 423 true, /* should_fetch_multiple_feeds */ |
| 424 search_file_path, |
| 425 std::string() /* no search query */, |
| 426 GURL(), /* feed not explicitly set */ |
| 427 std::string() /* no directory resource ID */, |
| 428 callback, |
| 429 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded, |
| 430 weak_ptr_factory_.GetWeakPtr())); |
| 431 } |
| 432 |
| 433 // TODO(kochi): Fix too many parameters. http://crbug.com/141359 |
| 336 void GDataWapiFeedLoader::LoadFromServer( | 434 void GDataWapiFeedLoader::LoadFromServer( |
| 337 ContentOrigin initial_origin, | 435 ContentOrigin initial_origin, |
| 338 int start_changestamp, | 436 int64 start_changestamp, |
| 339 int root_feed_changestamp, | 437 int64 root_feed_changestamp, |
| 340 bool should_fetch_multiple_feeds, | 438 bool should_fetch_multiple_feeds, |
| 341 const FilePath& search_file_path, | 439 const FilePath& search_file_path, |
| 342 const std::string& search_query, | 440 const std::string& search_query, |
| 343 const GURL& feed_to_load, | 441 const GURL& feed_to_load, |
| 344 const std::string& directory_resource_id, | 442 const std::string& directory_resource_id, |
| 345 const FindEntryCallback& entry_found_callback, | 443 const FindEntryCallback& entry_found_callback, |
| 346 const LoadDocumentFeedCallback& feed_load_callback) { | 444 const LoadDocumentFeedCallback& feed_load_callback) { |
| 347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 348 | 446 |
| 349 // |feed_list| will contain the list of all collected feed updates that | 447 // |feed_list| will contain the list of all collected feed updates that |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 callback.Run(params, GDATA_FILE_ERROR_FAILED); | 540 callback.Run(params, GDATA_FILE_ERROR_FAILED); |
| 443 } | 541 } |
| 444 | 542 |
| 445 return; | 543 return; |
| 446 } | 544 } |
| 447 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url); | 545 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url); |
| 448 | 546 |
| 449 #ifndef NDEBUG | 547 #ifndef NDEBUG |
| 450 // Save initial root feed for analysis. | 548 // Save initial root feed for analysis. |
| 451 std::string file_name = | 549 std::string file_name = |
| 452 base::StringPrintf("DEBUG_feed_%d.json", | 550 base::StringPrintf("DEBUG_feed_%" PRId64 ".json", |
| 453 params->start_changestamp); | 551 params->start_changestamp); |
| 454 util::PostBlockingPoolSequencedTask( | 552 util::PostBlockingPoolSequencedTask( |
| 455 FROM_HERE, | 553 FROM_HERE, |
| 456 blocking_task_runner_, | 554 blocking_task_runner_, |
| 457 base::Bind(&SaveFeedOnBlockingPoolForDebugging, | 555 base::Bind(&SaveFeedOnBlockingPoolForDebugging, |
| 458 cache_->GetCacheDirectoryPath( | 556 cache_->GetCacheDirectoryPath( |
| 459 GDataCache::CACHE_TYPE_META).Append(file_name), | 557 GDataCache::CACHE_TYPE_META).Append(file_name), |
| 460 base::Passed(&data))); | 558 base::Passed(&data))); |
| 461 #endif | 559 #endif |
| 462 | 560 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 util::PostBlockingPoolSequencedTask( | 777 util::PostBlockingPoolSequencedTask( |
| 680 FROM_HERE, | 778 FROM_HERE, |
| 681 blocking_task_runner_, | 779 blocking_task_runner_, |
| 682 base::Bind(&SaveProtoOnBlockingPool, path, | 780 base::Bind(&SaveProtoOnBlockingPool, path, |
| 683 base::Passed(serialized_proto.Pass()))); | 781 base::Passed(serialized_proto.Pass()))); |
| 684 } | 782 } |
| 685 } | 783 } |
| 686 | 784 |
| 687 GDataFileError GDataWapiFeedLoader::UpdateFromFeed( | 785 GDataFileError GDataWapiFeedLoader::UpdateFromFeed( |
| 688 const std::vector<DocumentFeed*>& feed_list, | 786 const std::vector<DocumentFeed*>& feed_list, |
| 689 int start_changestamp, | 787 int64 start_changestamp, |
| 690 int root_feed_changestamp) { | 788 int64 root_feed_changestamp) { |
| 691 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 692 DVLOG(1) << "Updating directory with a feed"; | 790 DVLOG(1) << "Updating directory with a feed"; |
| 693 | 791 |
| 694 std::set<FilePath> changed_dirs; | 792 std::set<FilePath> changed_dirs; |
| 695 | 793 |
| 696 GDataWapiFeedProcessor feed_processor(directory_service_); | 794 GDataWapiFeedProcessor feed_processor(directory_service_); |
| 697 const GDataFileError error = feed_processor.ApplyFeeds( | 795 const GDataFileError error = feed_processor.ApplyFeeds( |
| 698 feed_list, | 796 feed_list, |
| 699 start_changestamp, | 797 start_changestamp, |
| 700 root_feed_changestamp, | 798 root_feed_changestamp, |
| 701 &changed_dirs); | 799 &changed_dirs); |
| 702 | 800 |
| 703 // Don't send directory content change notification while performing | 801 // Don't send directory content change notification while performing |
| 704 // the initial content retrieval. | 802 // the initial content retrieval. |
| 705 const bool should_notify_directory_changed = (start_changestamp != 0); | 803 const bool should_notify_directory_changed = (start_changestamp != 0); |
| 706 if (should_notify_directory_changed) { | 804 if (should_notify_directory_changed) { |
| 707 for (std::set<FilePath>::iterator dir_iter = changed_dirs.begin(); | 805 for (std::set<FilePath>::iterator dir_iter = changed_dirs.begin(); |
| 708 dir_iter != changed_dirs.end(); ++dir_iter) { | 806 dir_iter != changed_dirs.end(); ++dir_iter) { |
| 709 FOR_EACH_OBSERVER(Observer, observers_, | 807 FOR_EACH_OBSERVER(Observer, observers_, |
| 710 OnDirectoryChanged(*dir_iter)); | 808 OnDirectoryChanged(*dir_iter)); |
| 711 } | 809 } |
| 712 } | 810 } |
| 713 | 811 |
| 714 return error; | 812 return error; |
| 715 } | 813 } |
| 716 | 814 |
| 717 } // namespace gdata | 815 } // namespace gdata |
| OLD | NEW |