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 kFetchUiUpdateStep = 10; | |
satorux1
2012/08/02 16:31:03
Please put some comment like
// Update the fetch
hidehiko
2012/08/03 09:50:18
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. | |
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 explicit GetDocumentsUiState(base::TimeTicks start_time) | |
624 : num_fetched_documents(0), | |
625 num_showing_documents(0), | |
626 start_time(start_time), | |
627 ui_weak_ptr_factory(this), | |
628 ui_weak_ptr(ui_weak_ptr_factory.GetWeakPtr()) { | |
629 } | |
630 | |
631 // The number of fetched documents. | |
632 int num_fetched_documents; | |
633 | |
634 // The number documents shown on UI. | |
635 int num_showing_documents; | |
636 | |
637 // When the UI update has started. | |
638 base::TimeTicks start_time; | |
639 | |
640 // How long duration the actual fetching takes in total. | |
satorux1
2012/08/02 16:31:03
What about:
// Time elapsed since the the feed fe
hidehiko
2012/08/03 09:50:18
Done.
| |
641 // Heuristically, we use the duration to decide the UI update step period. | |
642 base::TimeDelta fetched_duration; | |
satorux1
2012/08/02 16:31:03
maybe: feed_fetching_elapsed_time ?
hidehiko
2012/08/03 09:50:18
Done.
| |
643 | |
644 base::WeakPtrFactory<GetDocumentsUiState> ui_weak_ptr_factory; | |
645 base::WeakPtr<GetDocumentsUiState> ui_weak_ptr; | |
646 }; | |
647 | |
648 | |
613 // GDataFileSystem::GetDocumentsParams struct implementation. | 649 // GDataFileSystem::GetDocumentsParams struct implementation. |
614 struct GDataFileSystem::GetDocumentsParams { | 650 struct GDataFileSystem::GetDocumentsParams { |
615 GetDocumentsParams(int start_changestamp, | 651 GetDocumentsParams(int start_changestamp, |
616 int root_feed_changestamp, | 652 int root_feed_changestamp, |
617 std::vector<DocumentFeed*>* feed_list, | 653 std::vector<DocumentFeed*>* feed_list, |
618 bool should_fetch_multiple_feeds, | 654 bool should_fetch_multiple_feeds, |
619 const FilePath& search_file_path, | 655 const FilePath& search_file_path, |
620 const std::string& search_query, | 656 const std::string& search_query, |
621 const std::string& directory_resource_id, | 657 const std::string& directory_resource_id, |
622 const FindEntryCallback& callback); | 658 const FindEntryCallback& callback, |
659 GDataFileSystem::GetDocumentsUiState *ui_state); | |
623 ~GetDocumentsParams(); | 660 ~GetDocumentsParams(); |
624 | 661 |
625 // Changestamps are positive numbers in increasing order. The difference | 662 // Changestamps are positive numbers in increasing order. The difference |
626 // between two changestamps is proportional equal to number of items in | 663 // between two changestamps is proportional equal to number of items in |
627 // delta feed between them - bigger the difference, more likely bigger | 664 // delta feed between them - bigger the difference, more likely bigger |
628 // number of items in delta feeds. | 665 // number of items in delta feeds. |
629 int start_changestamp; | 666 int start_changestamp; |
630 int root_feed_changestamp; | 667 int root_feed_changestamp; |
631 scoped_ptr<std::vector<DocumentFeed*> > feed_list; | 668 scoped_ptr<std::vector<DocumentFeed*> > feed_list; |
632 // Should we stop after getting first feed chunk, even if there is more | 669 // Should we stop after getting first feed chunk, even if there is more |
633 // data. | 670 // data. |
634 bool should_fetch_multiple_feeds; | 671 bool should_fetch_multiple_feeds; |
635 FilePath search_file_path; | 672 FilePath search_file_path; |
636 std::string search_query; | 673 std::string search_query; |
637 std::string directory_resource_id; | 674 std::string directory_resource_id; |
638 FindEntryCallback callback; | 675 FindEntryCallback callback; |
676 scoped_ptr<GDataFileSystem::GetDocumentsUiState> ui_state; | |
639 }; | 677 }; |
640 | 678 |
641 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( | 679 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( |
642 int start_changestamp, | 680 int start_changestamp, |
643 int root_feed_changestamp, | 681 int root_feed_changestamp, |
644 std::vector<DocumentFeed*>* feed_list, | 682 std::vector<DocumentFeed*>* feed_list, |
645 bool should_fetch_multiple_feeds, | 683 bool should_fetch_multiple_feeds, |
646 const FilePath& search_file_path, | 684 const FilePath& search_file_path, |
647 const std::string& search_query, | 685 const std::string& search_query, |
648 const std::string& directory_resource_id, | 686 const std::string& directory_resource_id, |
649 const FindEntryCallback& callback) | 687 const FindEntryCallback& callback, |
688 GDataFileSystem::GetDocumentsUiState *ui_state) | |
650 : start_changestamp(start_changestamp), | 689 : start_changestamp(start_changestamp), |
651 root_feed_changestamp(root_feed_changestamp), | 690 root_feed_changestamp(root_feed_changestamp), |
652 feed_list(feed_list), | 691 feed_list(feed_list), |
653 should_fetch_multiple_feeds(should_fetch_multiple_feeds), | 692 should_fetch_multiple_feeds(should_fetch_multiple_feeds), |
654 search_file_path(search_file_path), | 693 search_file_path(search_file_path), |
655 search_query(search_query), | 694 search_query(search_query), |
656 directory_resource_id(directory_resource_id), | 695 directory_resource_id(directory_resource_id), |
657 callback(callback) { | 696 callback(callback), |
697 ui_state(ui_state) { | |
658 } | 698 } |
659 | 699 |
660 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() { | 700 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() { |
661 STLDeleteElements(feed_list.get()); | 701 STLDeleteElements(feed_list.get()); |
662 } | 702 } |
663 | 703 |
664 // GDataFileSystem::CreateDirectoryParams struct implementation. | 704 // GDataFileSystem::CreateDirectoryParams struct implementation. |
665 struct GDataFileSystem::CreateDirectoryParams { | 705 struct GDataFileSystem::CreateDirectoryParams { |
666 CreateDirectoryParams(const FilePath& created_directory_path, | 706 CreateDirectoryParams(const FilePath& created_directory_path, |
667 const FilePath& target_directory_path, | 707 const FilePath& target_directory_path, |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1102 ui_weak_ptr_, | 1142 ui_weak_ptr_, |
1103 initial_origin, | 1143 initial_origin, |
1104 feed_load_callback, | 1144 feed_load_callback, |
1105 base::Owned(new GetDocumentsParams(start_changestamp, | 1145 base::Owned(new GetDocumentsParams(start_changestamp, |
1106 root_feed_changestamp, | 1146 root_feed_changestamp, |
1107 feed_list.release(), | 1147 feed_list.release(), |
1108 should_fetch_multiple_feeds, | 1148 should_fetch_multiple_feeds, |
1109 search_file_path, | 1149 search_file_path, |
1110 search_query, | 1150 search_query, |
1111 directory_resource_id, | 1151 directory_resource_id, |
1112 entry_found_callback)), | 1152 entry_found_callback, |
1153 NULL)), | |
1113 start_time)); | 1154 start_time)); |
1114 } | 1155 } |
1115 | 1156 |
1116 void GDataFileSystem::OnFeedFromServerLoaded(GetDocumentsParams* params, | 1157 void GDataFileSystem::OnFeedFromServerLoaded(GetDocumentsParams* params, |
1117 GDataFileError error) { | 1158 GDataFileError error) { |
1118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1119 | 1160 |
1120 if (error != GDATA_FILE_OK) { | 1161 if (error != GDATA_FILE_OK) { |
1121 if (!params->callback.is_null()) | 1162 if (!params->callback.is_null()) |
1122 params->callback.Run(error, NULL); | 1163 params->callback.Run(error, NULL); |
(...skipping 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2842 base::Passed(&data))); | 2883 base::Passed(&data))); |
2843 #endif | 2884 #endif |
2844 | 2885 |
2845 // Add the current feed to the list of collected feeds for this directory. | 2886 // Add the current feed to the list of collected feeds for this directory. |
2846 params->feed_list->push_back(current_feed.release()); | 2887 params->feed_list->push_back(current_feed.release()); |
2847 | 2888 |
2848 // Compute and notify the number of entries fetched so far. | 2889 // Compute and notify the number of entries fetched so far. |
2849 int num_accumulated_entries = 0; | 2890 int num_accumulated_entries = 0; |
2850 for (size_t i = 0; i < params->feed_list->size(); ++i) | 2891 for (size_t i = 0; i < params->feed_list->size(); ++i) |
2851 num_accumulated_entries += params->feed_list->at(i)->entries().size(); | 2892 num_accumulated_entries += params->feed_list->at(i)->entries().size(); |
2852 NotifyDocumentFeedFetched(num_accumulated_entries); | |
2853 | 2893 |
2854 // Check if we need to collect more data to complete the directory list. | 2894 // Check if we need to collect more data to complete the directory list. |
2855 if (params->should_fetch_multiple_feeds && has_next_feed_url && | 2895 if (params->should_fetch_multiple_feeds && has_next_feed_url && |
2856 !next_feed_url.is_empty()) { | 2896 !next_feed_url.is_empty()) { |
2897 | |
2898 // Post an UI update event to make the UI smoother. | |
2899 GetDocumentsUiState* ui_state = params->ui_state.get(); | |
2900 if (ui_state == NULL) { | |
2901 ui_state = new GetDocumentsUiState(base::TimeTicks::Now()); | |
2902 params->ui_state.reset(ui_state); | |
2903 } | |
2904 DCHECK(ui_state); | |
2905 | |
2906 if ((ui_state->num_fetched_documents - ui_state->num_showing_documents) | |
2907 < kFetchUiUpdateStep) { | |
2908 // Currently the UI update is stopped. Start UI periodical callback. | |
satorux1
2012/08/02 16:31:03
periodic
hidehiko
2012/08/03 09:50:18
Done.
| |
2909 MessageLoop::current()->PostTask( | |
2910 FROM_HERE, | |
2911 base::Bind(&GDataFileSystem::OnNotifyDocumentFeedFetched, | |
2912 ui_weak_ptr_, ui_state->ui_weak_ptr)); | |
2913 } | |
2914 ui_state->num_fetched_documents = num_accumulated_entries; | |
2915 ui_state->fetched_duration = base::TimeTicks::Now() - start_time; | |
2916 | |
2857 // Kick of the remaining part of the feeds. | 2917 // Kick of the remaining part of the feeds. |
2858 documents_service_->GetDocuments( | 2918 documents_service_->GetDocuments( |
2859 next_feed_url, | 2919 next_feed_url, |
2860 params->start_changestamp, | 2920 params->start_changestamp, |
2861 params->search_query, | 2921 params->search_query, |
2862 params->directory_resource_id, | 2922 params->directory_resource_id, |
2863 base::Bind(&GDataFileSystem::OnGetDocuments, | 2923 base::Bind(&GDataFileSystem::OnGetDocuments, |
2864 ui_weak_ptr_, | 2924 ui_weak_ptr_, |
2865 initial_origin, | 2925 initial_origin, |
2866 callback, | 2926 callback, |
2867 base::Owned( | 2927 base::Owned( |
2868 new GetDocumentsParams( | 2928 new GetDocumentsParams( |
2869 params->start_changestamp, | 2929 params->start_changestamp, |
2870 params->root_feed_changestamp, | 2930 params->root_feed_changestamp, |
2871 params->feed_list.release(), | 2931 params->feed_list.release(), |
2872 params->should_fetch_multiple_feeds, | 2932 params->should_fetch_multiple_feeds, |
2873 params->search_file_path, | 2933 params->search_file_path, |
2874 params->search_query, | 2934 params->search_query, |
2875 params->directory_resource_id, | 2935 params->directory_resource_id, |
2876 params->callback)), | 2936 params->callback, |
2937 params->ui_state.release())), | |
2877 start_time)); | 2938 start_time)); |
2878 return; | 2939 return; |
2879 } | 2940 } |
2941 NotifyDocumentFeedFetched(num_accumulated_entries); | |
2880 | 2942 |
2881 UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime", | 2943 UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime", |
2882 base::TimeTicks::Now() - start_time); | 2944 base::TimeTicks::Now() - start_time); |
2883 | 2945 |
2884 if (!callback.is_null()) | 2946 if (!callback.is_null()) |
2885 callback.Run(params, error); | 2947 callback.Run(params, error); |
2886 } | 2948 } |
2887 | 2949 |
2888 void GDataFileSystem::LoadRootFeedFromCache( | 2950 void GDataFileSystem::LoadRootFeedFromCache( |
2889 bool should_load_from_server, | 2951 bool should_load_from_server, |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3596 | 3658 |
3597 void GDataFileSystem::NotifyDocumentFeedFetched(int num_accumulated_entries) { | 3659 void GDataFileSystem::NotifyDocumentFeedFetched(int num_accumulated_entries) { |
3598 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 3660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
3599 | 3661 |
3600 DVLOG(1) << "Document feed fetched: " << num_accumulated_entries; | 3662 DVLOG(1) << "Document feed fetched: " << num_accumulated_entries; |
3601 // Notify the observers that a document feed is fetched. | 3663 // Notify the observers that a document feed is fetched. |
3602 FOR_EACH_OBSERVER(Observer, observers_, | 3664 FOR_EACH_OBSERVER(Observer, observers_, |
3603 OnDocumentFeedFetched(num_accumulated_entries)); | 3665 OnDocumentFeedFetched(num_accumulated_entries)); |
3604 } | 3666 } |
3605 | 3667 |
3668 void GDataFileSystem::OnNotifyDocumentFeedFetched( | |
3669 base::WeakPtr<GDataFileSystem::GetDocumentsUiState> ui_state) { | |
3670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
3671 | |
3672 if (!ui_state) { | |
3673 // The ui state instance is already released, which means the fetching | |
3674 // is done and we don't need to update any more. | |
3675 return; | |
satorux1
2012/08/02 16:31:03
I think managing lifetime of ui_state using weak p
hidehiko
2012/08/02 19:06:33
It looks slightly danger to me, because;
When OnG
satorux1
2012/08/02 19:37:16
Are you are right, can we delete it in OnNotifyDoc
hidehiko
2012/08/02 19:59:06
No, unfortunately, because it's potential memory l
satorux1
2012/08/02 21:14:48
Ah I see. it's complicated. :)
I thought about it
hidehiko
2012/08/03 09:50:18
Done.
| |
3676 } | |
3677 | |
3678 base::TimeDelta consumed_duration = | |
satorux1
2012/08/02 16:31:03
maybe: elapsed_time
hidehiko
2012/08/03 09:50:18
Done.
| |
3679 base::TimeTicks::Now() - ui_state->start_time; | |
3680 | |
3681 if (ui_state->num_showing_documents + kFetchUiUpdateStep <= | |
3682 ui_state->num_fetched_documents) { | |
3683 ui_state->num_showing_documents += kFetchUiUpdateStep; | |
3684 NotifyDocumentFeedFetched(ui_state->num_showing_documents); | |
3685 | |
3686 int num_remaining_ui_update = | |
satorux1
2012/08/02 16:31:03
num_remaining_ui_updates
hidehiko
2012/08/03 09:50:18
Done.
| |
3687 (ui_state->num_fetched_documents - ui_state->num_showing_documents) | |
3688 / kFetchUiUpdateStep; | |
3689 if (num_remaining_ui_update > 0) { | |
3690 // Heuristically, we use fetched time duration to calculate the next | |
3691 // UI update timing. | |
3692 base::TimeDelta remaining_duration = | |
3693 ui_state->fetched_duration - consumed_duration; | |
3694 MessageLoop::current()->PostDelayedTask( | |
3695 FROM_HERE, | |
3696 base::Bind(&GDataFileSystem::OnNotifyDocumentFeedFetched, | |
3697 ui_weak_ptr_, ui_state->ui_weak_ptr), | |
3698 remaining_duration / num_remaining_ui_update); | |
3699 } | |
3700 } | |
3701 } | |
3702 | |
3606 void GDataFileSystem::RunAndNotifyInitialLoadFinished( | 3703 void GDataFileSystem::RunAndNotifyInitialLoadFinished( |
3607 const FindEntryCallback& callback, | 3704 const FindEntryCallback& callback, |
3608 GDataFileError error, | 3705 GDataFileError error, |
3609 GDataEntry* entry) { | 3706 GDataEntry* entry) { |
3610 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 3707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
3611 | 3708 |
3612 DVLOG(1) << "Initial load finished"; | 3709 DVLOG(1) << "Initial load finished"; |
3613 if (!callback.is_null()) | 3710 if (!callback.is_null()) |
3614 callback.Run(error, entry); | 3711 callback.Run(error, entry); |
3615 | 3712 |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4267 } | 4364 } |
4268 | 4365 |
4269 PlatformFileInfoProto entry_file_info; | 4366 PlatformFileInfoProto entry_file_info; |
4270 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); | 4367 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); |
4271 *entry_proto->mutable_file_info() = entry_file_info; | 4368 *entry_proto->mutable_file_info() = entry_file_info; |
4272 if (!callback.is_null()) | 4369 if (!callback.is_null()) |
4273 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); | 4370 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); |
4274 } | 4371 } |
4275 | 4372 |
4276 } // namespace gdata | 4373 } // namespace gdata |
OLD | NEW |