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/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 const int kNumUiUpdateStepsPerFetch = 50; | |
|
satorux1
2012/08/02 08:03:14
With kMaxDocumentsPerFeed = 500 defined elsewhere,
hidehiko
2012/08/02 13:47:05
Done.
| |
| 59 | |
| 58 // Schedule for dumping root file system proto buffers to disk depending its | 60 // Schedule for dumping root file system proto buffers to disk depending its |
| 59 // total protobuffer size in MB. | 61 // total protobuffer size in MB. |
| 60 typedef struct { | 62 typedef struct { |
| 61 double size; | 63 double size; |
| 62 int timeout; | 64 int timeout; |
| 63 } SerializationTimetable; | 65 } SerializationTimetable; |
| 64 | 66 |
| 65 SerializationTimetable kSerializeTimetable[] = { | 67 SerializationTimetable kSerializeTimetable[] = { |
| 66 #ifndef NDEBUG | 68 #ifndef NDEBUG |
| 67 {0.5, 0}, // Less than 0.5MB, dump immediately. | 69 {0.5, 0}, // Less than 0.5MB, dump immediately. |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 const GetEntryInfoWithFilePathCallback& callback, | 605 const GetEntryInfoWithFilePathCallback& callback, |
| 604 const FilePath& path, | 606 const FilePath& path, |
| 605 GDataFileError error, | 607 GDataFileError error, |
| 606 scoped_ptr<GDataEntryProto> entry_proto) { | 608 scoped_ptr<GDataEntryProto> entry_proto) { |
| 607 if (!callback.is_null()) | 609 if (!callback.is_null()) |
| 608 callback.Run(error, path, entry_proto.Pass()); | 610 callback.Run(error, path, entry_proto.Pass()); |
| 609 } | 611 } |
| 610 | 612 |
| 611 } // namespace | 613 } // namespace |
| 612 | 614 |
| 615 // GDataFileSystem::GetDocumentsUIState struct implementation. | |
|
satorux1
2012/08/02 08:03:14
UI -> Ui
hidehiko
2012/08/02 13:47:05
Done.
| |
| 616 // This is a trick to update the number of fetched documents frequently on | |
| 617 // UI. Due to performance reason, we need to fetch a number of files at | |
| 618 // a time. However, it'll take long time, and a user has no way to know | |
| 619 // the current update state. In order to make users confortable, | |
| 620 // we increment the number of fetched documents with more frequent but smaller | |
| 621 // steps than actual fetching. | |
| 622 struct GDataFileSystem::GetDocumentsUIState { | |
| 623 GetDocumentsUIState( | |
| 624 base::TimeTicks start_time, | |
| 625 const base::Callback<void(GetDocumentsUIState*)>& callback) | |
| 626 : num_fetched_documents(0), | |
| 627 num_showing_documents(0), | |
| 628 num_remaining_ui_update(0), | |
| 629 start_time(start_time), | |
| 630 callback(callback), | |
| 631 ui_weak_ptr_factory(this), | |
| 632 ui_weak_ptr(ui_weak_ptr_factory.GetWeakPtr()) { | |
| 633 } | |
| 634 | |
| 635 // Callback trampoline. By introducing this callback, the main procedure | |
| 636 // can cancel the pending events by just deleteing this instance. | |
| 637 void Run() { | |
|
satorux1
2012/08/02 08:03:14
I'm guessing that this method is unnecessary. see
hidehiko
2012/08/02 13:47:05
Done.
| |
| 638 callback.Run(this); | |
| 639 } | |
| 640 | |
| 641 // The number of fetched documents. | |
| 642 int num_fetched_documents; | |
| 643 | |
| 644 // The number documents shown on UI. | |
| 645 int num_showing_documents; | |
| 646 | |
| 647 // How many times the UI will be updated. | |
| 648 int num_remaining_ui_update; | |
| 649 | |
| 650 // When the UI update has started. | |
| 651 base::TimeTicks start_time; | |
| 652 | |
| 653 // How long duration the actual fetching takes in total. | |
| 654 // Heuristically, we use the duration to decide the UI update step period. | |
| 655 base::TimeDelta fetched_duration; | |
| 656 | |
| 657 base::Callback<void(GetDocumentsUIState*)> callback; | |
| 658 base::WeakPtrFactory<GetDocumentsUIState> ui_weak_ptr_factory; | |
| 659 base::WeakPtr<GetDocumentsUIState> ui_weak_ptr; | |
| 660 }; | |
| 661 | |
| 662 | |
| 613 // GDataFileSystem::GetDocumentsParams struct implementation. | 663 // GDataFileSystem::GetDocumentsParams struct implementation. |
| 614 struct GDataFileSystem::GetDocumentsParams { | 664 struct GDataFileSystem::GetDocumentsParams { |
| 615 GetDocumentsParams(int start_changestamp, | 665 GetDocumentsParams(int start_changestamp, |
| 616 int root_feed_changestamp, | 666 int root_feed_changestamp, |
| 617 std::vector<DocumentFeed*>* feed_list, | 667 std::vector<DocumentFeed*>* feed_list, |
| 618 bool should_fetch_multiple_feeds, | 668 bool should_fetch_multiple_feeds, |
| 619 const FilePath& search_file_path, | 669 const FilePath& search_file_path, |
| 620 const std::string& search_query, | 670 const std::string& search_query, |
| 621 const std::string& directory_resource_id, | 671 const std::string& directory_resource_id, |
| 622 const FindEntryCallback& callback); | 672 const FindEntryCallback& callback, |
| 673 GDataFileSystem::GetDocumentsUIState *ui_state); | |
| 623 ~GetDocumentsParams(); | 674 ~GetDocumentsParams(); |
| 624 | 675 |
| 625 // Changestamps are positive numbers in increasing order. The difference | 676 // Changestamps are positive numbers in increasing order. The difference |
| 626 // between two changestamps is proportional equal to number of items in | 677 // between two changestamps is proportional equal to number of items in |
| 627 // delta feed between them - bigger the difference, more likely bigger | 678 // delta feed between them - bigger the difference, more likely bigger |
| 628 // number of items in delta feeds. | 679 // number of items in delta feeds. |
| 629 int start_changestamp; | 680 int start_changestamp; |
| 630 int root_feed_changestamp; | 681 int root_feed_changestamp; |
| 631 scoped_ptr<std::vector<DocumentFeed*> > feed_list; | 682 scoped_ptr<std::vector<DocumentFeed*> > feed_list; |
| 632 // Should we stop after getting first feed chunk, even if there is more | 683 // Should we stop after getting first feed chunk, even if there is more |
| 633 // data. | 684 // data. |
| 634 bool should_fetch_multiple_feeds; | 685 bool should_fetch_multiple_feeds; |
| 635 FilePath search_file_path; | 686 FilePath search_file_path; |
| 636 std::string search_query; | 687 std::string search_query; |
| 637 std::string directory_resource_id; | 688 std::string directory_resource_id; |
| 638 FindEntryCallback callback; | 689 FindEntryCallback callback; |
| 690 scoped_ptr<GDataFileSystem::GetDocumentsUIState> ui_state; | |
| 639 }; | 691 }; |
| 640 | 692 |
| 641 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( | 693 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( |
| 642 int start_changestamp, | 694 int start_changestamp, |
| 643 int root_feed_changestamp, | 695 int root_feed_changestamp, |
| 644 std::vector<DocumentFeed*>* feed_list, | 696 std::vector<DocumentFeed*>* feed_list, |
| 645 bool should_fetch_multiple_feeds, | 697 bool should_fetch_multiple_feeds, |
| 646 const FilePath& search_file_path, | 698 const FilePath& search_file_path, |
| 647 const std::string& search_query, | 699 const std::string& search_query, |
| 648 const std::string& directory_resource_id, | 700 const std::string& directory_resource_id, |
| 649 const FindEntryCallback& callback) | 701 const FindEntryCallback& callback, |
| 702 GDataFileSystem::GetDocumentsUIState *ui_state) | |
| 650 : start_changestamp(start_changestamp), | 703 : start_changestamp(start_changestamp), |
| 651 root_feed_changestamp(root_feed_changestamp), | 704 root_feed_changestamp(root_feed_changestamp), |
| 652 feed_list(feed_list), | 705 feed_list(feed_list), |
| 653 should_fetch_multiple_feeds(should_fetch_multiple_feeds), | 706 should_fetch_multiple_feeds(should_fetch_multiple_feeds), |
| 654 search_file_path(search_file_path), | 707 search_file_path(search_file_path), |
| 655 search_query(search_query), | 708 search_query(search_query), |
| 656 directory_resource_id(directory_resource_id), | 709 directory_resource_id(directory_resource_id), |
| 657 callback(callback) { | 710 callback(callback), |
| 711 ui_state(ui_state) { | |
| 658 } | 712 } |
| 659 | 713 |
| 660 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() { | 714 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() { |
| 661 STLDeleteElements(feed_list.get()); | 715 STLDeleteElements(feed_list.get()); |
| 662 } | 716 } |
| 663 | 717 |
| 664 // GDataFileSystem::CreateDirectoryParams struct implementation. | 718 // GDataFileSystem::CreateDirectoryParams struct implementation. |
| 665 struct GDataFileSystem::CreateDirectoryParams { | 719 struct GDataFileSystem::CreateDirectoryParams { |
| 666 CreateDirectoryParams(const FilePath& created_directory_path, | 720 CreateDirectoryParams(const FilePath& created_directory_path, |
| 667 const FilePath& target_directory_path, | 721 const FilePath& target_directory_path, |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1102 ui_weak_ptr_, | 1156 ui_weak_ptr_, |
| 1103 initial_origin, | 1157 initial_origin, |
| 1104 feed_load_callback, | 1158 feed_load_callback, |
| 1105 base::Owned(new GetDocumentsParams(start_changestamp, | 1159 base::Owned(new GetDocumentsParams(start_changestamp, |
| 1106 root_feed_changestamp, | 1160 root_feed_changestamp, |
| 1107 feed_list.release(), | 1161 feed_list.release(), |
| 1108 should_fetch_multiple_feeds, | 1162 should_fetch_multiple_feeds, |
| 1109 search_file_path, | 1163 search_file_path, |
| 1110 search_query, | 1164 search_query, |
| 1111 directory_resource_id, | 1165 directory_resource_id, |
| 1112 entry_found_callback)), | 1166 entry_found_callback, |
| 1167 NULL)), | |
| 1113 start_time)); | 1168 start_time)); |
| 1114 } | 1169 } |
| 1115 | 1170 |
| 1116 void GDataFileSystem::OnFeedFromServerLoaded(GetDocumentsParams* params, | 1171 void GDataFileSystem::OnFeedFromServerLoaded(GetDocumentsParams* params, |
| 1117 GDataFileError error) { | 1172 GDataFileError error) { |
| 1118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1119 | 1174 |
| 1120 if (error != GDATA_FILE_OK) { | 1175 if (error != GDATA_FILE_OK) { |
| 1121 if (!params->callback.is_null()) | 1176 if (!params->callback.is_null()) |
| 1122 params->callback.Run(error, NULL); | 1177 params->callback.Run(error, NULL); |
| (...skipping 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2842 base::Passed(&data))); | 2897 base::Passed(&data))); |
| 2843 #endif | 2898 #endif |
| 2844 | 2899 |
| 2845 // Add the current feed to the list of collected feeds for this directory. | 2900 // Add the current feed to the list of collected feeds for this directory. |
| 2846 params->feed_list->push_back(current_feed.release()); | 2901 params->feed_list->push_back(current_feed.release()); |
| 2847 | 2902 |
| 2848 // Compute and notify the number of entries fetched so far. | 2903 // Compute and notify the number of entries fetched so far. |
| 2849 int num_accumulated_entries = 0; | 2904 int num_accumulated_entries = 0; |
| 2850 for (size_t i = 0; i < params->feed_list->size(); ++i) | 2905 for (size_t i = 0; i < params->feed_list->size(); ++i) |
| 2851 num_accumulated_entries += params->feed_list->at(i)->entries().size(); | 2906 num_accumulated_entries += params->feed_list->at(i)->entries().size(); |
| 2852 NotifyDocumentFeedFetched(num_accumulated_entries); | |
| 2853 | 2907 |
| 2854 // Check if we need to collect more data to complete the directory list. | 2908 // Check if we need to collect more data to complete the directory list. |
| 2855 if (params->should_fetch_multiple_feeds && has_next_feed_url && | 2909 if (params->should_fetch_multiple_feeds && has_next_feed_url && |
| 2856 !next_feed_url.is_empty()) { | 2910 !next_feed_url.is_empty()) { |
| 2911 | |
| 2912 // Post an UI update event to make the UI smoother. | |
| 2913 GetDocumentsUIState* ui_state = params->ui_state.get(); | |
| 2914 if (ui_state == NULL) { | |
| 2915 ui_state = new GetDocumentsUIState( | |
| 2916 base::TimeTicks::Now(), | |
| 2917 base::Bind(&GDataFileSystem::OnNotifyDocumentFeedFetched, | |
| 2918 ui_weak_ptr_)); | |
|
satorux1
2012/08/02 08:03:14
I have a feeling that this base::Bind() is unneces
satorux1
2012/08/02 08:03:14
I'm guessing that this callback parameter is unnec
hidehiko
2012/08/02 13:47:05
Done.
hidehiko
2012/08/02 13:47:05
Done.
| |
| 2919 params->ui_state.reset(ui_state); | |
| 2920 } | |
| 2921 DCHECK(ui_state != NULL); | |
|
satorux1
2012/08/02 08:03:14
remove != NULL, to be consistent with elsewhere.
hidehiko
2012/08/02 13:47:05
Done.
| |
| 2922 | |
| 2923 if (ui_state->num_remaining_ui_update == 0) { | |
| 2924 // Currently the UI update is stopped. Start UI periodical callback. | |
| 2925 MessageLoop::current()->PostTask( | |
| 2926 FROM_HERE, | |
| 2927 base::Bind(&GetDocumentsUIState::Run, ui_state->ui_weak_ptr)); | |
|
satorux1
2012/08/02 08:03:14
Cannot we just do the following here?
base::Bind
hidehiko
2012/08/02 13:47:05
Done.
| |
| 2928 } | |
| 2929 ui_state->num_fetched_documents = num_accumulated_entries; | |
| 2930 ui_state->num_remaining_ui_update += kNumUiUpdateStepsPerFetch; | |
| 2931 ui_state->fetched_duration = base::TimeTicks::Now() - start_time; | |
| 2932 | |
| 2857 // Kick of the remaining part of the feeds. | 2933 // Kick of the remaining part of the feeds. |
| 2858 documents_service_->GetDocuments( | 2934 documents_service_->GetDocuments( |
| 2859 next_feed_url, | 2935 next_feed_url, |
| 2860 params->start_changestamp, | 2936 params->start_changestamp, |
| 2861 params->search_query, | 2937 params->search_query, |
| 2862 params->directory_resource_id, | 2938 params->directory_resource_id, |
| 2863 base::Bind(&GDataFileSystem::OnGetDocuments, | 2939 base::Bind(&GDataFileSystem::OnGetDocuments, |
| 2864 ui_weak_ptr_, | 2940 ui_weak_ptr_, |
| 2865 initial_origin, | 2941 initial_origin, |
| 2866 callback, | 2942 callback, |
| 2867 base::Owned( | 2943 base::Owned( |
| 2868 new GetDocumentsParams( | 2944 new GetDocumentsParams( |
| 2869 params->start_changestamp, | 2945 params->start_changestamp, |
| 2870 params->root_feed_changestamp, | 2946 params->root_feed_changestamp, |
| 2871 params->feed_list.release(), | 2947 params->feed_list.release(), |
| 2872 params->should_fetch_multiple_feeds, | 2948 params->should_fetch_multiple_feeds, |
| 2873 params->search_file_path, | 2949 params->search_file_path, |
| 2874 params->search_query, | 2950 params->search_query, |
| 2875 params->directory_resource_id, | 2951 params->directory_resource_id, |
| 2876 params->callback)), | 2952 params->callback, |
| 2953 params->ui_state.release())), | |
| 2877 start_time)); | 2954 start_time)); |
| 2878 return; | 2955 return; |
| 2879 } | 2956 } |
| 2957 NotifyDocumentFeedFetched(num_accumulated_entries); | |
| 2880 | 2958 |
| 2881 UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime", | 2959 UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime", |
| 2882 base::TimeTicks::Now() - start_time); | 2960 base::TimeTicks::Now() - start_time); |
| 2883 | 2961 |
| 2884 if (!callback.is_null()) | 2962 if (!callback.is_null()) |
| 2885 callback.Run(params, error); | 2963 callback.Run(params, error); |
| 2886 } | 2964 } |
| 2887 | 2965 |
| 2888 void GDataFileSystem::LoadRootFeedFromCache( | 2966 void GDataFileSystem::LoadRootFeedFromCache( |
| 2889 bool should_load_from_server, | 2967 bool should_load_from_server, |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3596 | 3674 |
| 3597 void GDataFileSystem::NotifyDocumentFeedFetched(int num_accumulated_entries) { | 3675 void GDataFileSystem::NotifyDocumentFeedFetched(int num_accumulated_entries) { |
| 3598 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 3676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 3599 | 3677 |
| 3600 DVLOG(1) << "Document feed fetched: " << num_accumulated_entries; | 3678 DVLOG(1) << "Document feed fetched: " << num_accumulated_entries; |
| 3601 // Notify the observers that a document feed is fetched. | 3679 // Notify the observers that a document feed is fetched. |
| 3602 FOR_EACH_OBSERVER(Observer, observers_, | 3680 FOR_EACH_OBSERVER(Observer, observers_, |
| 3603 OnDocumentFeedFetched(num_accumulated_entries)); | 3681 OnDocumentFeedFetched(num_accumulated_entries)); |
| 3604 } | 3682 } |
| 3605 | 3683 |
| 3684 void GDataFileSystem::OnNotifyDocumentFeedFetched( | |
| 3685 GDataFileSystem::GetDocumentsUIState* ui_state) { | |
| 3686 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 3687 | |
| 3688 base::TimeDelta consumed_duration = | |
| 3689 base::TimeTicks::Now() - ui_state->start_time; | |
| 3690 | |
| 3691 // Split the remaining (i.e. not yet shown on UI) fetched documents evenly | |
| 3692 // to the remaining updates, cumulate one of them to the showing number of | |
| 3693 // fetched documents on UI, and notify it to the observers. | |
| 3694 int update_num_documents = | |
| 3695 (ui_state->num_fetched_documents - ui_state->num_showing_documents) | |
| 3696 / ui_state->num_remaining_ui_update; | |
| 3697 ui_state->num_showing_documents += update_num_documents; | |
| 3698 NotifyDocumentFeedFetched(ui_state->num_showing_documents); | |
| 3699 | |
| 3700 --ui_state->num_remaining_ui_update; | |
| 3701 if (ui_state->num_remaining_ui_update > 0) { | |
| 3702 // Heuristically, we use fetched time duration to calculate the next | |
| 3703 // UI update timing. | |
| 3704 base::TimeDelta remaining_duration = | |
| 3705 ui_state->fetched_duration - consumed_duration; | |
| 3706 MessageLoop::current()->PostDelayedTask( | |
| 3707 FROM_HERE, | |
| 3708 base::Bind(&GetDocumentsUIState::Run, ui_state->ui_weak_ptr), | |
| 3709 remaining_duration / ui_state->num_remaining_ui_update); | |
| 3710 } | |
| 3711 } | |
| 3712 | |
| 3713 | |
| 3606 void GDataFileSystem::RunAndNotifyInitialLoadFinished( | 3714 void GDataFileSystem::RunAndNotifyInitialLoadFinished( |
| 3607 const FindEntryCallback& callback, | 3715 const FindEntryCallback& callback, |
| 3608 GDataFileError error, | 3716 GDataFileError error, |
| 3609 GDataEntry* entry) { | 3717 GDataEntry* entry) { |
| 3610 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 3718 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 3611 | 3719 |
| 3612 DVLOG(1) << "Initial load finished"; | 3720 DVLOG(1) << "Initial load finished"; |
| 3613 if (!callback.is_null()) | 3721 if (!callback.is_null()) |
| 3614 callback.Run(error, entry); | 3722 callback.Run(error, entry); |
| 3615 | 3723 |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4267 } | 4375 } |
| 4268 | 4376 |
| 4269 PlatformFileInfoProto entry_file_info; | 4377 PlatformFileInfoProto entry_file_info; |
| 4270 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); | 4378 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); |
| 4271 *entry_proto->mutable_file_info() = entry_file_info; | 4379 *entry_proto->mutable_file_info() = entry_file_info; |
| 4272 if (!callback.is_null()) | 4380 if (!callback.is_null()) |
| 4273 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); | 4381 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); |
| 4274 } | 4382 } |
| 4275 | 4383 |
| 4276 } // namespace gdata | 4384 } // namespace gdata |
| OLD | NEW |