| 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_file_system.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 | 48 |
| 49 const char kEmptyFilePath[] = "/dev/null"; | 49 const char kEmptyFilePath[] = "/dev/null"; |
| 50 | 50 |
| 51 // GData update check interval (in seconds). | 51 // GData update check interval (in seconds). |
| 52 #ifndef NDEBUG | 52 #ifndef NDEBUG |
| 53 const int kGDataUpdateCheckIntervalInSec = 5; | 53 const int kGDataUpdateCheckIntervalInSec = 5; |
| 54 #else | 54 #else |
| 55 const int kGDataUpdateCheckIntervalInSec = 60; | 55 const int kGDataUpdateCheckIntervalInSec = 60; |
| 56 #endif | 56 #endif |
| 57 | 57 |
| 58 // Update the fetch progress UI per every this number of feeds. |
| 59 const int kFetchUiUpdateStep = 10; |
| 60 |
| 58 // Schedule for dumping root file system proto buffers to disk depending its | 61 // Schedule for dumping root file system proto buffers to disk depending its |
| 59 // total protobuffer size in MB. | 62 // total protobuffer size in MB. |
| 60 typedef struct { | 63 typedef struct { |
| 61 double size; | 64 double size; |
| 62 int timeout; | 65 int timeout; |
| 63 } SerializationTimetable; | 66 } SerializationTimetable; |
| 64 | 67 |
| 65 SerializationTimetable kSerializeTimetable[] = { | 68 SerializationTimetable kSerializeTimetable[] = { |
| 66 #ifndef NDEBUG | 69 #ifndef NDEBUG |
| 67 {0.5, 0}, // Less than 0.5MB, dump immediately. | 70 {0.5, 0}, // Less than 0.5MB, dump immediately. |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 void GDataWapiFeedLoader::AddObserver(Observer* observer) { | 581 void GDataWapiFeedLoader::AddObserver(Observer* observer) { |
| 579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 580 observers_.AddObserver(observer); | 583 observers_.AddObserver(observer); |
| 581 } | 584 } |
| 582 | 585 |
| 583 void GDataWapiFeedLoader::RemoveObserver(Observer* observer) { | 586 void GDataWapiFeedLoader::RemoveObserver(Observer* observer) { |
| 584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 587 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 585 observers_.RemoveObserver(observer); | 588 observers_.RemoveObserver(observer); |
| 586 } | 589 } |
| 587 | 590 |
| 591 // Defines set of parameters sent to callback OnNotifyDocumentFeedFetched(). |
| 592 // This is a trick to update the number of fetched documents frequently on |
| 593 // UI. Due to performance reason, we need to fetch a number of files at |
| 594 // a time. However, it'll take long time, and a user has no way to know |
| 595 // the current update state. In order to make users confortable, |
| 596 // we increment the number of fetched documents with more frequent but smaller |
| 597 // steps than actual fetching. |
| 598 struct GetDocumentsUiState { |
| 599 explicit GetDocumentsUiState(base::TimeTicks start_time) |
| 600 : num_fetched_documents(0), |
| 601 num_showing_documents(0), |
| 602 start_time(start_time), |
| 603 weak_ptr_factory(this) { |
| 604 } |
| 605 |
| 606 // The number of fetched documents. |
| 607 int num_fetched_documents; |
| 608 |
| 609 // The number documents shown on UI. |
| 610 int num_showing_documents; |
| 611 |
| 612 // When the UI update has started. |
| 613 base::TimeTicks start_time; |
| 614 |
| 615 // Time elapsed since the feed fetching was started. |
| 616 base::TimeDelta feed_fetching_elapsed_time; |
| 617 |
| 618 base::WeakPtrFactory<GetDocumentsUiState> weak_ptr_factory; |
| 619 }; |
| 620 |
| 588 // Defines set of parameters sent to callback OnGetDocuments(). | 621 // Defines set of parameters sent to callback OnGetDocuments(). |
| 589 // TODO(satorux): Move this to a new file: crbug.com/138268 | 622 // TODO(satorux): Move this to a new file: crbug.com/138268 |
| 590 struct GetDocumentsParams { | 623 struct GetDocumentsParams { |
| 591 GetDocumentsParams(int start_changestamp, | 624 GetDocumentsParams(int start_changestamp, |
| 592 int root_feed_changestamp, | 625 int root_feed_changestamp, |
| 593 std::vector<DocumentFeed*>* feed_list, | 626 std::vector<DocumentFeed*>* feed_list, |
| 594 bool should_fetch_multiple_feeds, | 627 bool should_fetch_multiple_feeds, |
| 595 const FilePath& search_file_path, | 628 const FilePath& search_file_path, |
| 596 const std::string& search_query, | 629 const std::string& search_query, |
| 597 const std::string& directory_resource_id, | 630 const std::string& directory_resource_id, |
| 598 const FindEntryCallback& callback); | 631 const FindEntryCallback& callback, |
| 632 GetDocumentsUiState* ui_state); |
| 599 ~GetDocumentsParams(); | 633 ~GetDocumentsParams(); |
| 600 | 634 |
| 601 // Changestamps are positive numbers in increasing order. The difference | 635 // Changestamps are positive numbers in increasing order. The difference |
| 602 // between two changestamps is proportional equal to number of items in | 636 // between two changestamps is proportional equal to number of items in |
| 603 // delta feed between them - bigger the difference, more likely bigger | 637 // delta feed between them - bigger the difference, more likely bigger |
| 604 // number of items in delta feeds. | 638 // number of items in delta feeds. |
| 605 int start_changestamp; | 639 int start_changestamp; |
| 606 int root_feed_changestamp; | 640 int root_feed_changestamp; |
| 607 scoped_ptr<std::vector<DocumentFeed*> > feed_list; | 641 scoped_ptr<std::vector<DocumentFeed*> > feed_list; |
| 608 // Should we stop after getting first feed chunk, even if there is more | 642 // Should we stop after getting first feed chunk, even if there is more |
| 609 // data. | 643 // data. |
| 610 bool should_fetch_multiple_feeds; | 644 bool should_fetch_multiple_feeds; |
| 611 FilePath search_file_path; | 645 FilePath search_file_path; |
| 612 std::string search_query; | 646 std::string search_query; |
| 613 std::string directory_resource_id; | 647 std::string directory_resource_id; |
| 614 FindEntryCallback callback; | 648 FindEntryCallback callback; |
| 649 scoped_ptr<GetDocumentsUiState> ui_state; |
| 615 }; | 650 }; |
| 616 | 651 |
| 617 GetDocumentsParams::GetDocumentsParams( | 652 GetDocumentsParams::GetDocumentsParams( |
| 618 int start_changestamp, | 653 int start_changestamp, |
| 619 int root_feed_changestamp, | 654 int root_feed_changestamp, |
| 620 std::vector<DocumentFeed*>* feed_list, | 655 std::vector<DocumentFeed*>* feed_list, |
| 621 bool should_fetch_multiple_feeds, | 656 bool should_fetch_multiple_feeds, |
| 622 const FilePath& search_file_path, | 657 const FilePath& search_file_path, |
| 623 const std::string& search_query, | 658 const std::string& search_query, |
| 624 const std::string& directory_resource_id, | 659 const std::string& directory_resource_id, |
| 625 const FindEntryCallback& callback) | 660 const FindEntryCallback& callback, |
| 661 GetDocumentsUiState* ui_state) |
| 626 : start_changestamp(start_changestamp), | 662 : start_changestamp(start_changestamp), |
| 627 root_feed_changestamp(root_feed_changestamp), | 663 root_feed_changestamp(root_feed_changestamp), |
| 628 feed_list(feed_list), | 664 feed_list(feed_list), |
| 629 should_fetch_multiple_feeds(should_fetch_multiple_feeds), | 665 should_fetch_multiple_feeds(should_fetch_multiple_feeds), |
| 630 search_file_path(search_file_path), | 666 search_file_path(search_file_path), |
| 631 search_query(search_query), | 667 search_query(search_query), |
| 632 directory_resource_id(directory_resource_id), | 668 directory_resource_id(directory_resource_id), |
| 633 callback(callback) { | 669 callback(callback), |
| 670 ui_state(ui_state) { |
| 634 } | 671 } |
| 635 | 672 |
| 636 GetDocumentsParams::~GetDocumentsParams() { | 673 GetDocumentsParams::~GetDocumentsParams() { |
| 637 STLDeleteElements(feed_list.get()); | 674 STLDeleteElements(feed_list.get()); |
| 638 } | 675 } |
| 639 | 676 |
| 640 // GDataFileSystem::CreateDirectoryParams struct implementation. | 677 // GDataFileSystem::CreateDirectoryParams struct implementation. |
| 641 struct GDataFileSystem::CreateDirectoryParams { | 678 struct GDataFileSystem::CreateDirectoryParams { |
| 642 CreateDirectoryParams(const FilePath& created_directory_path, | 679 CreateDirectoryParams(const FilePath& created_directory_path, |
| 643 const FilePath& target_directory_path, | 680 const FilePath& target_directory_path, |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 weak_ptr_factory_.GetWeakPtr(), | 1116 weak_ptr_factory_.GetWeakPtr(), |
| 1080 initial_origin, | 1117 initial_origin, |
| 1081 feed_load_callback, | 1118 feed_load_callback, |
| 1082 base::Owned(new GetDocumentsParams(start_changestamp, | 1119 base::Owned(new GetDocumentsParams(start_changestamp, |
| 1083 root_feed_changestamp, | 1120 root_feed_changestamp, |
| 1084 feed_list.release(), | 1121 feed_list.release(), |
| 1085 should_fetch_multiple_feeds, | 1122 should_fetch_multiple_feeds, |
| 1086 search_file_path, | 1123 search_file_path, |
| 1087 search_query, | 1124 search_query, |
| 1088 directory_resource_id, | 1125 directory_resource_id, |
| 1089 entry_found_callback)), | 1126 entry_found_callback, |
| 1127 NULL)), |
| 1090 start_time)); | 1128 start_time)); |
| 1091 } | 1129 } |
| 1092 | 1130 |
| 1093 void GDataWapiFeedLoader::OnFeedFromServerLoaded(GetDocumentsParams* params, | 1131 void GDataWapiFeedLoader::OnFeedFromServerLoaded(GetDocumentsParams* params, |
| 1094 GDataFileError error) { | 1132 GDataFileError error) { |
| 1095 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1096 | 1134 |
| 1097 if (error != GDATA_FILE_OK) { | 1135 if (error != GDATA_FILE_OK) { |
| 1098 if (!params->callback.is_null()) | 1136 if (!params->callback.is_null()) |
| 1099 params->callback.Run(error, NULL); | 1137 params->callback.Run(error, NULL); |
| (...skipping 1727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2827 #endif | 2865 #endif |
| 2828 | 2866 |
| 2829 // Add the current feed to the list of collected feeds for this directory. | 2867 // Add the current feed to the list of collected feeds for this directory. |
| 2830 params->feed_list->push_back(current_feed.release()); | 2868 params->feed_list->push_back(current_feed.release()); |
| 2831 | 2869 |
| 2832 // Compute and notify the number of entries fetched so far. | 2870 // Compute and notify the number of entries fetched so far. |
| 2833 int num_accumulated_entries = 0; | 2871 int num_accumulated_entries = 0; |
| 2834 for (size_t i = 0; i < params->feed_list->size(); ++i) | 2872 for (size_t i = 0; i < params->feed_list->size(); ++i) |
| 2835 num_accumulated_entries += params->feed_list->at(i)->entries().size(); | 2873 num_accumulated_entries += params->feed_list->at(i)->entries().size(); |
| 2836 | 2874 |
| 2837 // Notify the observers that a document feed is fetched. | |
| 2838 FOR_EACH_OBSERVER(Observer, observers_, | |
| 2839 OnDocumentFeedFetched(num_accumulated_entries)); | |
| 2840 | |
| 2841 // Check if we need to collect more data to complete the directory list. | 2875 // Check if we need to collect more data to complete the directory list. |
| 2842 if (params->should_fetch_multiple_feeds && has_next_feed_url && | 2876 if (params->should_fetch_multiple_feeds && has_next_feed_url && |
| 2843 !next_feed_url.is_empty()) { | 2877 !next_feed_url.is_empty()) { |
| 2878 // Post an UI update event to make the UI smoother. |
| 2879 GetDocumentsUiState* ui_state = params->ui_state.get(); |
| 2880 if (ui_state == NULL) { |
| 2881 ui_state = new GetDocumentsUiState(base::TimeTicks::Now()); |
| 2882 params->ui_state.reset(ui_state); |
| 2883 } |
| 2884 DCHECK(ui_state); |
| 2885 |
| 2886 if ((ui_state->num_fetched_documents - ui_state->num_showing_documents) |
| 2887 < kFetchUiUpdateStep) { |
| 2888 // Currently the UI update is stopped. Start UI periodic callback. |
| 2889 MessageLoop::current()->PostTask( |
| 2890 FROM_HERE, |
| 2891 base::Bind(&GDataWapiFeedLoader::OnNotifyDocumentFeedFetched, |
| 2892 weak_ptr_factory_.GetWeakPtr(), |
| 2893 ui_state->weak_ptr_factory.GetWeakPtr())); |
| 2894 } |
| 2895 ui_state->num_fetched_documents = num_accumulated_entries; |
| 2896 ui_state->feed_fetching_elapsed_time = base::TimeTicks::Now() - start_time; |
| 2897 |
| 2844 // Kick of the remaining part of the feeds. | 2898 // Kick of the remaining part of the feeds. |
| 2845 documents_service_->GetDocuments( | 2899 documents_service_->GetDocuments( |
| 2846 next_feed_url, | 2900 next_feed_url, |
| 2847 params->start_changestamp, | 2901 params->start_changestamp, |
| 2848 params->search_query, | 2902 params->search_query, |
| 2849 params->directory_resource_id, | 2903 params->directory_resource_id, |
| 2850 base::Bind(&GDataWapiFeedLoader::OnGetDocuments, | 2904 base::Bind(&GDataWapiFeedLoader::OnGetDocuments, |
| 2851 weak_ptr_factory_.GetWeakPtr(), | 2905 weak_ptr_factory_.GetWeakPtr(), |
| 2852 initial_origin, | 2906 initial_origin, |
| 2853 callback, | 2907 callback, |
| 2854 base::Owned( | 2908 base::Owned( |
| 2855 new GetDocumentsParams( | 2909 new GetDocumentsParams( |
| 2856 params->start_changestamp, | 2910 params->start_changestamp, |
| 2857 params->root_feed_changestamp, | 2911 params->root_feed_changestamp, |
| 2858 params->feed_list.release(), | 2912 params->feed_list.release(), |
| 2859 params->should_fetch_multiple_feeds, | 2913 params->should_fetch_multiple_feeds, |
| 2860 params->search_file_path, | 2914 params->search_file_path, |
| 2861 params->search_query, | 2915 params->search_query, |
| 2862 params->directory_resource_id, | 2916 params->directory_resource_id, |
| 2863 params->callback)), | 2917 params->callback, |
| 2918 params->ui_state.release())), |
| 2864 start_time)); | 2919 start_time)); |
| 2865 return; | 2920 return; |
| 2866 } | 2921 } |
| 2867 | 2922 |
| 2923 // Notify the observers that a document feed is fetched. |
| 2924 FOR_EACH_OBSERVER(Observer, observers_, |
| 2925 OnDocumentFeedFetched(num_accumulated_entries)); |
| 2926 |
| 2868 UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime", | 2927 UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime", |
| 2869 base::TimeTicks::Now() - start_time); | 2928 base::TimeTicks::Now() - start_time); |
| 2870 | 2929 |
| 2871 if (!callback.is_null()) | 2930 if (!callback.is_null()) |
| 2872 callback.Run(params, error); | 2931 callback.Run(params, error); |
| 2873 } | 2932 } |
| 2874 | 2933 |
| 2934 void GDataWapiFeedLoader::OnNotifyDocumentFeedFetched( |
| 2935 base::WeakPtr<GetDocumentsUiState> ui_state) { |
| 2936 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2937 |
| 2938 if (!ui_state) { |
| 2939 // The ui state instance is already released, which means the fetching |
| 2940 // is done and we don't need to update any more. |
| 2941 return; |
| 2942 } |
| 2943 |
| 2944 base::TimeDelta elapsed_time = |
| 2945 base::TimeTicks::Now() - ui_state->start_time; |
| 2946 |
| 2947 if (ui_state->num_showing_documents + kFetchUiUpdateStep <= |
| 2948 ui_state->num_fetched_documents) { |
| 2949 ui_state->num_showing_documents += kFetchUiUpdateStep; |
| 2950 FOR_EACH_OBSERVER(Observer, observers_, |
| 2951 OnDocumentFeedFetched(ui_state->num_showing_documents)); |
| 2952 |
| 2953 int num_remaining_ui_updates = |
| 2954 (ui_state->num_fetched_documents - ui_state->num_showing_documents) |
| 2955 / kFetchUiUpdateStep; |
| 2956 if (num_remaining_ui_updates > 0) { |
| 2957 // Heuristically, we use fetched time duration to calculate the next |
| 2958 // UI update timing. |
| 2959 base::TimeDelta remaining_duration = |
| 2960 ui_state->feed_fetching_elapsed_time - elapsed_time; |
| 2961 MessageLoop::current()->PostDelayedTask( |
| 2962 FROM_HERE, |
| 2963 base::Bind(&GDataWapiFeedLoader::OnNotifyDocumentFeedFetched, |
| 2964 weak_ptr_factory_.GetWeakPtr(), |
| 2965 ui_state->weak_ptr_factory.GetWeakPtr()), |
| 2966 remaining_duration / num_remaining_ui_updates); |
| 2967 } |
| 2968 } |
| 2969 } |
| 2970 |
| 2875 void GDataWapiFeedLoader::LoadFromCache( | 2971 void GDataWapiFeedLoader::LoadFromCache( |
| 2876 bool should_load_from_server, | 2972 bool should_load_from_server, |
| 2877 const FilePath& search_file_path, | 2973 const FilePath& search_file_path, |
| 2878 const FindEntryCallback& callback) { | 2974 const FindEntryCallback& callback) { |
| 2879 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2975 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2880 | 2976 |
| 2881 const FilePath path = | 2977 const FilePath path = |
| 2882 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( | 2978 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( |
| 2883 kFilesystemProtoFile); | 2979 kFilesystemProtoFile); |
| 2884 LoadRootFeedParams* params = new LoadRootFeedParams(search_file_path, | 2980 LoadRootFeedParams* params = new LoadRootFeedParams(search_file_path, |
| (...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4047 } | 4143 } |
| 4048 | 4144 |
| 4049 PlatformFileInfoProto entry_file_info; | 4145 PlatformFileInfoProto entry_file_info; |
| 4050 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); | 4146 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); |
| 4051 *entry_proto->mutable_file_info() = entry_file_info; | 4147 *entry_proto->mutable_file_info() = entry_file_info; |
| 4052 if (!callback.is_null()) | 4148 if (!callback.is_null()) |
| 4053 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); | 4149 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); |
| 4054 } | 4150 } |
| 4055 | 4151 |
| 4056 } // namespace gdata | 4152 } // namespace gdata |
| OLD | NEW |