| 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 <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 // When the UI update has started. | 230 // When the UI update has started. |
| 231 base::TimeTicks start_time; | 231 base::TimeTicks start_time; |
| 232 | 232 |
| 233 // Time elapsed since the feed fetching was started. | 233 // Time elapsed since the feed fetching was started. |
| 234 base::TimeDelta feed_fetching_elapsed_time; | 234 base::TimeDelta feed_fetching_elapsed_time; |
| 235 | 235 |
| 236 base::WeakPtrFactory<GetDocumentsUiState> weak_ptr_factory; | 236 base::WeakPtrFactory<GetDocumentsUiState> weak_ptr_factory; |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 GDataWapiFeedLoader::GDataWapiFeedLoader( | 239 GDataWapiFeedLoader::GDataWapiFeedLoader( |
| 240 GDataDirectoryService* directory_service, | 240 DriveResourceMetadata* resource_metadata, |
| 241 DriveServiceInterface* drive_service, | 241 DriveServiceInterface* drive_service, |
| 242 DriveWebAppsRegistryInterface* webapps_registry, | 242 DriveWebAppsRegistryInterface* webapps_registry, |
| 243 GDataCache* cache, | 243 GDataCache* cache, |
| 244 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 244 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) |
| 245 : directory_service_(directory_service), | 245 : resource_metadata_(resource_metadata), |
| 246 drive_service_(drive_service), | 246 drive_service_(drive_service), |
| 247 webapps_registry_(webapps_registry), | 247 webapps_registry_(webapps_registry), |
| 248 cache_(cache), | 248 cache_(cache), |
| 249 blocking_task_runner_(blocking_task_runner), | 249 blocking_task_runner_(blocking_task_runner), |
| 250 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 250 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 251 } | 251 } |
| 252 | 252 |
| 253 GDataWapiFeedLoader::~GDataWapiFeedLoader() { | 253 GDataWapiFeedLoader::~GDataWapiFeedLoader() { |
| 254 } | 254 } |
| 255 | 255 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 bool changes_detected = true; | 345 bool changes_detected = true; |
| 346 if (local_changestamp >= account_metadata->largest_changestamp()) { | 346 if (local_changestamp >= account_metadata->largest_changestamp()) { |
| 347 if (local_changestamp > account_metadata->largest_changestamp()) { | 347 if (local_changestamp > account_metadata->largest_changestamp()) { |
| 348 LOG(WARNING) << "Cached client feed is fresher than server, client = " | 348 LOG(WARNING) << "Cached client feed is fresher than server, client = " |
| 349 << local_changestamp | 349 << local_changestamp |
| 350 << ", server = " | 350 << ", server = " |
| 351 << account_metadata->largest_changestamp(); | 351 << account_metadata->largest_changestamp(); |
| 352 } | 352 } |
| 353 // If our cache holds the latest state from the server, change the | 353 // If our cache holds the latest state from the server, change the |
| 354 // state to FROM_SERVER. | 354 // state to FROM_SERVER. |
| 355 directory_service_->set_origin( | 355 resource_metadata_->set_origin( |
| 356 initial_origin == FROM_CACHE ? FROM_SERVER : initial_origin); | 356 initial_origin == FROM_CACHE ? FROM_SERVER : initial_origin); |
| 357 changes_detected = false; | 357 changes_detected = false; |
| 358 } | 358 } |
| 359 | 359 |
| 360 // No changes detected, tell the client that the loading was successful. | 360 // No changes detected, tell the client that the loading was successful. |
| 361 if (!changes_detected) { | 361 if (!changes_detected) { |
| 362 if (!callback.is_null()) | 362 if (!callback.is_null()) |
| 363 callback.Run(GDATA_FILE_OK); | 363 callback.Run(GDATA_FILE_OK); |
| 364 return; | 364 return; |
| 365 } | 365 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 394 if (feed_data.get()) | 394 if (feed_data.get()) |
| 395 about_resource = AboutResource::CreateFrom(*feed_data); | 395 about_resource = AboutResource::CreateFrom(*feed_data); |
| 396 | 396 |
| 397 if (!about_resource.get()) { | 397 if (!about_resource.get()) { |
| 398 LoadFromServer(params); | 398 LoadFromServer(params); |
| 399 return; | 399 return; |
| 400 } | 400 } |
| 401 | 401 |
| 402 bool changes_detected = true; | 402 bool changes_detected = true; |
| 403 int64 largest_changestamp = about_resource->largest_change_id(); | 403 int64 largest_changestamp = about_resource->largest_change_id(); |
| 404 directory_service_->InitializeRootEntry(about_resource->root_folder_id()); | 404 resource_metadata_->InitializeRootEntry(about_resource->root_folder_id()); |
| 405 | 405 |
| 406 if (local_changestamp >= largest_changestamp) { | 406 if (local_changestamp >= largest_changestamp) { |
| 407 if (local_changestamp > largest_changestamp) { | 407 if (local_changestamp > largest_changestamp) { |
| 408 LOG(WARNING) << "Cached client feed is fresher than server, client = " | 408 LOG(WARNING) << "Cached client feed is fresher than server, client = " |
| 409 << local_changestamp | 409 << local_changestamp |
| 410 << ", server = " | 410 << ", server = " |
| 411 << largest_changestamp; | 411 << largest_changestamp; |
| 412 } | 412 } |
| 413 // If our cache holds the latest state from the server, change the | 413 // If our cache holds the latest state from the server, change the |
| 414 // state to FROM_SERVER. | 414 // state to FROM_SERVER. |
| 415 directory_service_->set_origin( | 415 resource_metadata_->set_origin( |
| 416 initial_origin == FROM_CACHE ? FROM_SERVER : initial_origin); | 416 initial_origin == FROM_CACHE ? FROM_SERVER : initial_origin); |
| 417 changes_detected = false; | 417 changes_detected = false; |
| 418 } | 418 } |
| 419 | 419 |
| 420 // No changes detected, tell the client that the loading was successful. | 420 // No changes detected, tell the client that the loading was successful. |
| 421 if (!changes_detected) { | 421 if (!changes_detected) { |
| 422 if (!callback.is_null()) | 422 if (!callback.is_null()) |
| 423 callback.Run(GDATA_FILE_OK); | 423 callback.Run(GDATA_FILE_OK); |
| 424 return; | 424 return; |
| 425 } | 425 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 base::TimeTicks::Now() - start_time); | 566 base::TimeTicks::Now() - start_time); |
| 567 } | 567 } |
| 568 | 568 |
| 569 GDataFileError error = util::GDataToGDataFileError(status); | 569 GDataFileError error = util::GDataToGDataFileError(status); |
| 570 if (error == GDATA_FILE_OK && | 570 if (error == GDATA_FILE_OK && |
| 571 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { | 571 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { |
| 572 error = GDATA_FILE_ERROR_FAILED; | 572 error = GDATA_FILE_ERROR_FAILED; |
| 573 } | 573 } |
| 574 | 574 |
| 575 if (error != GDATA_FILE_OK) { | 575 if (error != GDATA_FILE_OK) { |
| 576 directory_service_->set_origin(initial_origin); | 576 resource_metadata_->set_origin(initial_origin); |
| 577 callback.Run(params, error); | 577 callback.Run(params, error); |
| 578 return; | 578 return; |
| 579 } | 579 } |
| 580 | 580 |
| 581 GURL next_feed_url; | 581 GURL next_feed_url; |
| 582 scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data)); | 582 scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data)); |
| 583 if (!current_feed.get()) { | 583 if (!current_feed.get()) { |
| 584 callback.Run(params, GDATA_FILE_ERROR_FAILED); | 584 callback.Run(params, GDATA_FILE_ERROR_FAILED); |
| 585 return; | 585 return; |
| 586 } | 586 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 base::TimeTicks::Now() - start_time); | 679 base::TimeTicks::Now() - start_time); |
| 680 } | 680 } |
| 681 | 681 |
| 682 GDataFileError error = util::GDataToGDataFileError(status); | 682 GDataFileError error = util::GDataToGDataFileError(status); |
| 683 if (error == GDATA_FILE_OK && | 683 if (error == GDATA_FILE_OK && |
| 684 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { | 684 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { |
| 685 error = GDATA_FILE_ERROR_FAILED; | 685 error = GDATA_FILE_ERROR_FAILED; |
| 686 } | 686 } |
| 687 | 687 |
| 688 if (error != GDATA_FILE_OK) { | 688 if (error != GDATA_FILE_OK) { |
| 689 directory_service_->set_origin(initial_origin); | 689 resource_metadata_->set_origin(initial_origin); |
| 690 callback.Run(params, error); | 690 callback.Run(params, error); |
| 691 return; | 691 return; |
| 692 } | 692 } |
| 693 | 693 |
| 694 GURL next_feed_url; | 694 GURL next_feed_url; |
| 695 scoped_ptr<ChangeList> current_feed(ChangeList::CreateFrom(*data)); | 695 scoped_ptr<ChangeList> current_feed(ChangeList::CreateFrom(*data)); |
| 696 if (!current_feed.get()) { | 696 if (!current_feed.get()) { |
| 697 callback.Run(params, GDATA_FILE_ERROR_FAILED); | 697 callback.Run(params, GDATA_FILE_ERROR_FAILED); |
| 698 return; | 698 return; |
| 699 } | 699 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 void GDataWapiFeedLoader::LoadFromCache( | 819 void GDataWapiFeedLoader::LoadFromCache( |
| 820 bool should_load_from_server, | 820 bool should_load_from_server, |
| 821 const FileOperationCallback& callback) { | 821 const FileOperationCallback& callback) { |
| 822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 823 | 823 |
| 824 LoadRootFeedParams* params = new LoadRootFeedParams(should_load_from_server, | 824 LoadRootFeedParams* params = new LoadRootFeedParams(should_load_from_server, |
| 825 callback); | 825 callback); |
| 826 FilePath path = cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META); | 826 FilePath path = cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META); |
| 827 if (UseLevelDB()) { | 827 if (UseLevelDB()) { |
| 828 path = path.Append(kResourceMetadataDBFile); | 828 path = path.Append(kResourceMetadataDBFile); |
| 829 directory_service_->InitFromDB(path, blocking_task_runner_, | 829 resource_metadata_->InitFromDB(path, blocking_task_runner_, |
| 830 base::Bind( | 830 base::Bind( |
| 831 &GDataWapiFeedLoader::ContinueWithInitializedDirectoryService, | 831 &GDataWapiFeedLoader::ContinueWithInitializedDirectoryService, |
| 832 weak_ptr_factory_.GetWeakPtr(), | 832 weak_ptr_factory_.GetWeakPtr(), |
| 833 base::Owned(params))); | 833 base::Owned(params))); |
| 834 } else { | 834 } else { |
| 835 path = path.Append(kFilesystemProtoFile); | 835 path = path.Append(kFilesystemProtoFile); |
| 836 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, | 836 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, |
| 837 base::Bind(&LoadProtoOnBlockingPool, path, params), | 837 base::Bind(&LoadProtoOnBlockingPool, path, params), |
| 838 base::Bind(&GDataWapiFeedLoader::OnProtoLoaded, | 838 base::Bind(&GDataWapiFeedLoader::OnProtoLoaded, |
| 839 weak_ptr_factory_.GetWeakPtr(), | 839 weak_ptr_factory_.GetWeakPtr(), |
| 840 base::Owned(params))); | 840 base::Owned(params))); |
| 841 } | 841 } |
| 842 } | 842 } |
| 843 | 843 |
| 844 void GDataWapiFeedLoader::OnProtoLoaded(LoadRootFeedParams* params) { | 844 void GDataWapiFeedLoader::OnProtoLoaded(LoadRootFeedParams* params) { |
| 845 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 845 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 846 | 846 |
| 847 // If we have already received updates from the server, bail out. | 847 // If we have already received updates from the server, bail out. |
| 848 if (directory_service_->origin() == FROM_SERVER) | 848 if (resource_metadata_->origin() == FROM_SERVER) |
| 849 return; | 849 return; |
| 850 | 850 |
| 851 // Update directory structure only if everything is OK and we haven't yet | 851 // Update directory structure only if everything is OK and we haven't yet |
| 852 // received the feed from the server yet. | 852 // received the feed from the server yet. |
| 853 if (params->load_error == GDATA_FILE_OK) { | 853 if (params->load_error == GDATA_FILE_OK) { |
| 854 DVLOG(1) << "ParseFromString"; | 854 DVLOG(1) << "ParseFromString"; |
| 855 if (directory_service_->ParseFromString(params->proto)) { | 855 if (resource_metadata_->ParseFromString(params->proto)) { |
| 856 directory_service_->set_last_serialized(params->last_modified); | 856 resource_metadata_->set_last_serialized(params->last_modified); |
| 857 directory_service_->set_serialized_size(params->proto.size()); | 857 resource_metadata_->set_serialized_size(params->proto.size()); |
| 858 } else { | 858 } else { |
| 859 params->load_error = GDATA_FILE_ERROR_FAILED; | 859 params->load_error = GDATA_FILE_ERROR_FAILED; |
| 860 LOG(WARNING) << "Parse of cached proto file failed"; | 860 LOG(WARNING) << "Parse of cached proto file failed"; |
| 861 } | 861 } |
| 862 } | 862 } |
| 863 | 863 |
| 864 ContinueWithInitializedDirectoryService(params, params->load_error); | 864 ContinueWithInitializedDirectoryService(params, params->load_error); |
| 865 } | 865 } |
| 866 | 866 |
| 867 void GDataWapiFeedLoader::ContinueWithInitializedDirectoryService( | 867 void GDataWapiFeedLoader::ContinueWithInitializedDirectoryService( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 886 | 886 |
| 887 if (!params->should_load_from_server) | 887 if (!params->should_load_from_server) |
| 888 return; | 888 return; |
| 889 | 889 |
| 890 // Decide the |initial_origin| to pass to ReloadFromServerIfNeeded(). | 890 // Decide the |initial_origin| to pass to ReloadFromServerIfNeeded(). |
| 891 // This is used to restore directory content origin to its initial value when | 891 // This is used to restore directory content origin to its initial value when |
| 892 // we fail to retrieve the feed from server. | 892 // we fail to retrieve the feed from server. |
| 893 // By default, if directory content is not yet initialized, restore content | 893 // By default, if directory content is not yet initialized, restore content |
| 894 // origin to UNINITIALIZED in case of failure. | 894 // origin to UNINITIALIZED in case of failure. |
| 895 ContentOrigin initial_origin = UNINITIALIZED; | 895 ContentOrigin initial_origin = UNINITIALIZED; |
| 896 if (directory_service_->origin() != INITIALIZING) { | 896 if (resource_metadata_->origin() != INITIALIZING) { |
| 897 // If directory content is already initialized, restore content origin | 897 // If directory content is already initialized, restore content origin |
| 898 // to FROM_CACHE in case of failure. | 898 // to FROM_CACHE in case of failure. |
| 899 initial_origin = FROM_CACHE; | 899 initial_origin = FROM_CACHE; |
| 900 directory_service_->set_origin(REFRESHING); | 900 resource_metadata_->set_origin(REFRESHING); |
| 901 } | 901 } |
| 902 | 902 |
| 903 // Kick off the retrieval of the feed from server. If we have previously | 903 // Kick off the retrieval of the feed from server. If we have previously |
| 904 // |reported| to the original callback, then we just need to refresh the | 904 // |reported| to the original callback, then we just need to refresh the |
| 905 // content without continuing search upon operation completion. | 905 // content without continuing search upon operation completion. |
| 906 ReloadFromServerIfNeeded(initial_origin, | 906 ReloadFromServerIfNeeded(initial_origin, |
| 907 directory_service_->largest_changestamp(), | 907 resource_metadata_->largest_changestamp(), |
| 908 callback); | 908 callback); |
| 909 } | 909 } |
| 910 | 910 |
| 911 void GDataWapiFeedLoader::SaveFileSystem() { | 911 void GDataWapiFeedLoader::SaveFileSystem() { |
| 912 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 912 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 913 | 913 |
| 914 if (!ShouldSerializeFileSystemNow(directory_service_->serialized_size(), | 914 if (!ShouldSerializeFileSystemNow(resource_metadata_->serialized_size(), |
| 915 directory_service_->last_serialized())) { | 915 resource_metadata_->last_serialized())) { |
| 916 return; | 916 return; |
| 917 } | 917 } |
| 918 | 918 |
| 919 if (UseLevelDB()) { | 919 if (UseLevelDB()) { |
| 920 directory_service_->SaveToDB(); | 920 resource_metadata_->SaveToDB(); |
| 921 } else { | 921 } else { |
| 922 const FilePath path = | 922 const FilePath path = |
| 923 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( | 923 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( |
| 924 kFilesystemProtoFile); | 924 kFilesystemProtoFile); |
| 925 scoped_ptr<std::string> serialized_proto(new std::string()); | 925 scoped_ptr<std::string> serialized_proto(new std::string()); |
| 926 directory_service_->SerializeToString(serialized_proto.get()); | 926 resource_metadata_->SerializeToString(serialized_proto.get()); |
| 927 directory_service_->set_last_serialized(base::Time::Now()); | 927 resource_metadata_->set_last_serialized(base::Time::Now()); |
| 928 directory_service_->set_serialized_size(serialized_proto->size()); | 928 resource_metadata_->set_serialized_size(serialized_proto->size()); |
| 929 util::PostBlockingPoolSequencedTask( | 929 util::PostBlockingPoolSequencedTask( |
| 930 FROM_HERE, | 930 FROM_HERE, |
| 931 blocking_task_runner_, | 931 blocking_task_runner_, |
| 932 base::Bind(&SaveProtoOnBlockingPool, path, | 932 base::Bind(&SaveProtoOnBlockingPool, path, |
| 933 base::Passed(serialized_proto.Pass()))); | 933 base::Passed(serialized_proto.Pass()))); |
| 934 } | 934 } |
| 935 } | 935 } |
| 936 | 936 |
| 937 GDataFileError GDataWapiFeedLoader::UpdateFromFeed( | 937 GDataFileError GDataWapiFeedLoader::UpdateFromFeed( |
| 938 const std::vector<DocumentFeed*>& feed_list, | 938 const std::vector<DocumentFeed*>& feed_list, |
| 939 int64 start_changestamp, | 939 int64 start_changestamp, |
| 940 int64 root_feed_changestamp) { | 940 int64 root_feed_changestamp) { |
| 941 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 941 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 942 DVLOG(1) << "Updating directory with a feed"; | 942 DVLOG(1) << "Updating directory with a feed"; |
| 943 | 943 |
| 944 std::set<FilePath> changed_dirs; | 944 std::set<FilePath> changed_dirs; |
| 945 | 945 |
| 946 GDataWapiFeedProcessor feed_processor(directory_service_); | 946 GDataWapiFeedProcessor feed_processor(resource_metadata_); |
| 947 const GDataFileError error = feed_processor.ApplyFeeds( | 947 const GDataFileError error = feed_processor.ApplyFeeds( |
| 948 feed_list, | 948 feed_list, |
| 949 start_changestamp, | 949 start_changestamp, |
| 950 root_feed_changestamp, | 950 root_feed_changestamp, |
| 951 &changed_dirs); | 951 &changed_dirs); |
| 952 | 952 |
| 953 // Don't send directory content change notification while performing | 953 // Don't send directory content change notification while performing |
| 954 // the initial content retrieval. | 954 // the initial content retrieval. |
| 955 const bool should_notify_directory_changed = (start_changestamp != 0); | 955 const bool should_notify_directory_changed = (start_changestamp != 0); |
| 956 if (should_notify_directory_changed) { | 956 if (should_notify_directory_changed) { |
| 957 for (std::set<FilePath>::iterator dir_iter = changed_dirs.begin(); | 957 for (std::set<FilePath>::iterator dir_iter = changed_dirs.begin(); |
| 958 dir_iter != changed_dirs.end(); ++dir_iter) { | 958 dir_iter != changed_dirs.end(); ++dir_iter) { |
| 959 FOR_EACH_OBSERVER(Observer, observers_, | 959 FOR_EACH_OBSERVER(Observer, observers_, |
| 960 OnDirectoryChanged(*dir_iter)); | 960 OnDirectoryChanged(*dir_iter)); |
| 961 } | 961 } |
| 962 } | 962 } |
| 963 | 963 |
| 964 return error; | 964 return error; |
| 965 } | 965 } |
| 966 | 966 |
| 967 } // namespace gdata | 967 } // namespace gdata |
| OLD | NEW |