| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/offline_pages/offline_page_model_impl.h" | 5 #include "components/offline_pages/offline_page_model_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 if (online_url_without_fragment == | 640 if (online_url_without_fragment == |
| 641 id_page_pair.second.url.ReplaceComponents(remove_params)) { | 641 id_page_pair.second.url.ReplaceComponents(remove_params)) { |
| 642 result.push_back(id_page_pair.second); | 642 result.push_back(id_page_pair.second); |
| 643 } | 643 } |
| 644 } | 644 } |
| 645 | 645 |
| 646 callback.Run(result); | 646 callback.Run(result); |
| 647 } | 647 } |
| 648 | 648 |
| 649 void OfflinePageModelImpl::CheckMetadataConsistency() { | 649 void OfflinePageModelImpl::CheckMetadataConsistency() { |
| 650 DCHECK(is_loaded_); | |
| 651 archive_manager_->GetAllArchives( | 650 archive_manager_->GetAllArchives( |
| 652 base::Bind(&OfflinePageModelImpl::CheckMetadataConsistencyForArchivePaths, | 651 base::Bind(&OfflinePageModelImpl::CheckMetadataConsistencyForArchivePaths, |
| 653 weak_ptr_factory_.GetWeakPtr())); | 652 weak_ptr_factory_.GetWeakPtr())); |
| 654 } | 653 } |
| 655 | 654 |
| 656 void OfflinePageModelImpl::ExpirePages( | 655 void OfflinePageModelImpl::ExpirePages( |
| 657 const std::vector<int64_t>& offline_ids, | 656 const std::vector<int64_t>& offline_ids, |
| 658 const base::Time& expiration_time, | 657 const base::Time& expiration_time, |
| 659 const base::Callback<void(bool)>& callback) { | 658 const base::Callback<void(bool)>& callback) { |
| 660 std::vector<base::FilePath> paths_to_delete; | 659 std::vector<base::FilePath> paths_to_delete; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 } else if (status == ItemActionStatus::ALREADY_EXISTS) { | 784 } else if (status == ItemActionStatus::ALREADY_EXISTS) { |
| 786 result = SavePageResult::ALREADY_EXISTS; | 785 result = SavePageResult::ALREADY_EXISTS; |
| 787 } else { | 786 } else { |
| 788 result = SavePageResult::STORE_FAILURE; | 787 result = SavePageResult::STORE_FAILURE; |
| 789 } | 788 } |
| 790 InformSavePageDone(callback, result, offline_page.client_id, | 789 InformSavePageDone(callback, result, offline_page.client_id, |
| 791 offline_page.offline_id); | 790 offline_page.offline_id); |
| 792 if (result == SavePageResult::SUCCESS) { | 791 if (result == SavePageResult::SUCCESS) { |
| 793 DeleteExistingPagesWithSameURL(offline_page); | 792 DeleteExistingPagesWithSameURL(offline_page); |
| 794 } else { | 793 } else { |
| 795 PostClearStorageIfNeededTask(); | 794 PostClearStorageIfNeededTask(false /* delayed */); |
| 796 } | 795 } |
| 797 | 796 |
| 798 DeletePendingArchiver(archiver); | 797 DeletePendingArchiver(archiver); |
| 799 for (Observer& observer : observers_) | 798 for (Observer& observer : observers_) |
| 800 observer.OfflinePageModelChanged(this); | 799 observer.OfflinePageModelChanged(this); |
| 801 } | 800 } |
| 802 | 801 |
| 803 void OfflinePageModelImpl::OnMarkPageAccesseDone( | 802 void OfflinePageModelImpl::OnMarkPageAccesseDone( |
| 804 const OfflinePageItem& offline_page_item, | 803 const OfflinePageItem& offline_page_item, |
| 805 std::unique_ptr<OfflinePagesUpdateResult> result) { | 804 std::unique_ptr<OfflinePagesUpdateResult> result) { |
| 806 // Update the item in the cache only upon success. | 805 // Update the item in the cache only upon success. |
| 807 if (result->updated_items.size() > 0) | 806 if (result->updated_items.size() > 0) |
| 808 offline_pages_[offline_page_item.offline_id] = offline_page_item; | 807 offline_pages_[offline_page_item.offline_id] = offline_page_item; |
| 809 | 808 |
| 810 // No need to fire OfflinePageModelChanged event since updating access info | 809 // No need to fire OfflinePageModelChanged event since updating access info |
| 811 // should not have any impact to the UI. | 810 // should not have any impact to the UI. |
| 812 } | 811 } |
| 813 | 812 |
| 814 void OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone( | 813 void OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone( |
| 815 const base::TimeTicks& start_time) { | 814 const base::TimeTicks& start_time) { |
| 816 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime", | 815 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime", |
| 817 base::TimeTicks::Now() - start_time); | 816 base::TimeTicks::Now() - start_time); |
| 818 | 817 |
| 818 store_->Initialize(base::Bind(&OfflinePageModelImpl::OnStoreInitialized, |
| 819 weak_ptr_factory_.GetWeakPtr(), start_time)); |
| 820 } |
| 821 |
| 822 void OfflinePageModelImpl::OnStoreInitialized(const base::TimeTicks& start_time, |
| 823 StoreState state) { |
| 824 if (state == StoreState::FAILED_RESET) { |
| 825 CompleteLoad(); |
| 826 return; |
| 827 } |
| 828 |
| 829 if (state == StoreState::FAILED_LOADING) { |
| 830 store_->Reset(base::Bind(&OfflinePageModelImpl::OnStoreInitialized, |
| 831 weak_ptr_factory_.GetWeakPtr(), start_time)); |
| 832 return; |
| 833 } |
| 834 |
| 835 DCHECK_EQ(state, StoreState::LOADED); |
| 819 store_->GetOfflinePages(base::Bind(&OfflinePageModelImpl::OnLoadDone, | 836 store_->GetOfflinePages(base::Bind(&OfflinePageModelImpl::OnLoadDone, |
| 820 weak_ptr_factory_.GetWeakPtr(), | 837 weak_ptr_factory_.GetWeakPtr(), |
| 821 start_time)); | 838 start_time)); |
| 822 } | 839 } |
| 823 | 840 |
| 824 void OfflinePageModelImpl::OnLoadDone( | 841 void OfflinePageModelImpl::OnLoadDone( |
| 825 const base::TimeTicks& start_time, | 842 const base::TimeTicks& start_time, |
| 826 OfflinePageMetadataStore::LoadStatus load_status, | |
| 827 const std::vector<OfflinePageItem>& offline_pages) { | 843 const std::vector<OfflinePageItem>& offline_pages) { |
| 828 DCHECK(!is_loaded_); | 844 DCHECK(!is_loaded_); |
| 829 is_loaded_ = true; | |
| 830 | |
| 831 // TODO(jianli): rebuild the store upon failure. | |
| 832 | |
| 833 if (load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED) | |
| 834 CacheLoadedData(offline_pages); | |
| 835 | 845 |
| 836 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ConstructionToLoadedEventTime", | 846 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ConstructionToLoadedEventTime", |
| 837 base::TimeTicks::Now() - start_time); | 847 base::TimeTicks::Now() - start_time); |
| 838 | 848 |
| 839 // Create Storage Manager. | 849 CacheLoadedData(offline_pages); |
| 840 storage_manager_.reset(new OfflinePageStorageManager( | 850 CompleteLoad(); |
| 841 this, GetPolicyController(), archive_manager_.get())); | 851 |
| 852 // Ensure necessary cleanup operations are started. |
| 853 CheckMetadataConsistency(); |
| 854 } |
| 855 |
| 856 void OfflinePageModelImpl::CompleteLoad() { |
| 857 is_loaded_ = true; |
| 858 |
| 859 // All actions below are meant to be taken regardless of successful load of |
| 860 // the store. |
| 861 |
| 862 // Inform observers the load is done. |
| 863 for (Observer& observer : observers_) |
| 864 observer.OfflinePageModelLoaded(this); |
| 842 | 865 |
| 843 // Run all the delayed tasks. | 866 // Run all the delayed tasks. |
| 844 for (const auto& delayed_task : delayed_tasks_) | 867 for (const auto& delayed_task : delayed_tasks_) |
| 845 delayed_task.Run(); | 868 delayed_task.Run(); |
| 846 delayed_tasks_.clear(); | 869 delayed_tasks_.clear(); |
| 847 | 870 |
| 848 for (Observer& observer : observers_) | 871 // Clear storage. |
| 849 observer.OfflinePageModelLoaded(this); | 872 PostClearStorageIfNeededTask(true /* delayed */); |
| 850 | |
| 851 CheckMetadataConsistency(); | |
| 852 | |
| 853 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 854 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded, | |
| 855 weak_ptr_factory_.GetWeakPtr(), | |
| 856 base::Bind(&OfflinePageModelImpl::OnStorageCleared, | |
| 857 weak_ptr_factory_.GetWeakPtr())), | |
| 858 kStorageManagerStartingDelay); | |
| 859 } | 873 } |
| 860 | 874 |
| 861 void OfflinePageModelImpl::InformSavePageDone(const SavePageCallback& callback, | 875 void OfflinePageModelImpl::InformSavePageDone(const SavePageCallback& callback, |
| 862 SavePageResult result, | 876 SavePageResult result, |
| 863 const ClientId& client_id, | 877 const ClientId& client_id, |
| 864 int64_t offline_id) { | 878 int64_t offline_id) { |
| 865 ReportSavePageResultHistogramAfterSave(client_id, result); | 879 ReportSavePageResultHistogramAfterSave(client_id, result); |
| 866 archive_manager_->GetStorageStats( | 880 archive_manager_->GetStorageStats( |
| 867 base::Bind(&ReportStorageHistogramsAfterSave)); | 881 base::Bind(&ReportStorageHistogramsAfterSave)); |
| 868 callback.Run(result, offline_id); | 882 callback.Run(result, offline_id); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 page_ids_to_delete.push_back(item.offline_id); | 921 page_ids_to_delete.push_back(item.offline_id); |
| 908 DeletePagesByOfflineId( | 922 DeletePagesByOfflineId( |
| 909 page_ids_to_delete, | 923 page_ids_to_delete, |
| 910 base::Bind(&OfflinePageModelImpl::OnDeleteOldPagesWithSameURL, | 924 base::Bind(&OfflinePageModelImpl::OnDeleteOldPagesWithSameURL, |
| 911 weak_ptr_factory_.GetWeakPtr())); | 925 weak_ptr_factory_.GetWeakPtr())); |
| 912 } | 926 } |
| 913 | 927 |
| 914 void OfflinePageModelImpl::OnDeleteOldPagesWithSameURL( | 928 void OfflinePageModelImpl::OnDeleteOldPagesWithSameURL( |
| 915 DeletePageResult result) { | 929 DeletePageResult result) { |
| 916 // TODO(romax) Add UMAs for failure cases. | 930 // TODO(romax) Add UMAs for failure cases. |
| 917 PostClearStorageIfNeededTask(); | 931 PostClearStorageIfNeededTask(false /* delayed */); |
| 918 } | 932 } |
| 919 | 933 |
| 920 void OfflinePageModelImpl::DeletePendingArchiver( | 934 void OfflinePageModelImpl::DeletePendingArchiver( |
| 921 OfflinePageArchiver* archiver) { | 935 OfflinePageArchiver* archiver) { |
| 922 pending_archivers_.erase(std::find(pending_archivers_.begin(), | 936 pending_archivers_.erase(std::find(pending_archivers_.begin(), |
| 923 pending_archivers_.end(), archiver)); | 937 pending_archivers_.end(), archiver)); |
| 924 } | 938 } |
| 925 | 939 |
| 926 void OfflinePageModelImpl::OnDeleteArchiveFilesDone( | 940 void OfflinePageModelImpl::OnDeleteArchiveFilesDone( |
| 927 const std::vector<int64_t>& offline_ids, | 941 const std::vector<int64_t>& offline_ids, |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 | 1060 |
| 1047 void OfflinePageModelImpl::CacheLoadedData( | 1061 void OfflinePageModelImpl::CacheLoadedData( |
| 1048 const std::vector<OfflinePageItem>& offline_pages) { | 1062 const std::vector<OfflinePageItem>& offline_pages) { |
| 1049 offline_pages_.clear(); | 1063 offline_pages_.clear(); |
| 1050 for (const auto& offline_page : offline_pages) | 1064 for (const auto& offline_page : offline_pages) |
| 1051 offline_pages_[offline_page.offline_id] = offline_page; | 1065 offline_pages_[offline_page.offline_id] = offline_page; |
| 1052 } | 1066 } |
| 1053 | 1067 |
| 1054 void OfflinePageModelImpl::ClearStorageIfNeeded( | 1068 void OfflinePageModelImpl::ClearStorageIfNeeded( |
| 1055 const ClearStorageCallback& callback) { | 1069 const ClearStorageCallback& callback) { |
| 1070 // Create Storage Manager if necessary. |
| 1071 if (!storage_manager_) { |
| 1072 storage_manager_.reset(new OfflinePageStorageManager( |
| 1073 this, GetPolicyController(), archive_manager_.get())); |
| 1074 } |
| 1056 storage_manager_->ClearPagesIfNeeded(callback); | 1075 storage_manager_->ClearPagesIfNeeded(callback); |
| 1057 } | 1076 } |
| 1058 | 1077 |
| 1059 void OfflinePageModelImpl::OnStorageCleared(size_t expired_page_count, | 1078 void OfflinePageModelImpl::OnStorageCleared(size_t expired_page_count, |
| 1060 ClearStorageResult result) { | 1079 ClearStorageResult result) { |
| 1061 UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearStorageResult", | 1080 UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearStorageResult", |
| 1062 static_cast<int>(result), | 1081 static_cast<int>(result), |
| 1063 static_cast<int>(ClearStorageResult::RESULT_COUNT)); | 1082 static_cast<int>(ClearStorageResult::RESULT_COUNT)); |
| 1064 if (expired_page_count > 0) { | 1083 if (expired_page_count > 0) { |
| 1065 UMA_HISTOGRAM_COUNTS("OfflinePages.ExpirePage.BatchSize", | 1084 UMA_HISTOGRAM_COUNTS("OfflinePages.ExpirePage.BatchSize", |
| 1066 static_cast<int32_t>(expired_page_count)); | 1085 static_cast<int32_t>(expired_page_count)); |
| 1067 } | 1086 } |
| 1068 } | 1087 } |
| 1069 | 1088 |
| 1070 void OfflinePageModelImpl::PostClearStorageIfNeededTask() { | 1089 void OfflinePageModelImpl::PostClearStorageIfNeededTask(bool delayed) { |
| 1071 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1090 base::TimeDelta delay = |
| 1091 delayed ? kStorageManagerStartingDelay : base::TimeDelta(); |
| 1092 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 1072 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded, | 1093 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded, |
| 1073 weak_ptr_factory_.GetWeakPtr(), | 1094 weak_ptr_factory_.GetWeakPtr(), |
| 1074 base::Bind(&OfflinePageModelImpl::OnStorageCleared, | 1095 base::Bind(&OfflinePageModelImpl::OnStorageCleared, |
| 1075 weak_ptr_factory_.GetWeakPtr()))); | 1096 weak_ptr_factory_.GetWeakPtr())), |
| 1097 delay); |
| 1076 } | 1098 } |
| 1077 | 1099 |
| 1078 bool OfflinePageModelImpl::IsRemovedOnCacheReset( | 1100 bool OfflinePageModelImpl::IsRemovedOnCacheReset( |
| 1079 const OfflinePageItem& offline_page) const { | 1101 const OfflinePageItem& offline_page) const { |
| 1080 return policy_controller_->IsRemovedOnCacheReset( | 1102 return policy_controller_->IsRemovedOnCacheReset( |
| 1081 offline_page.client_id.name_space); | 1103 offline_page.client_id.name_space); |
| 1082 } | 1104 } |
| 1083 | 1105 |
| 1084 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) { | 1106 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) { |
| 1085 if (!is_loaded_) { | 1107 if (!is_loaded_) { |
| 1086 delayed_tasks_.push_back(task); | 1108 delayed_tasks_.push_back(task); |
| 1087 return; | 1109 return; |
| 1088 } | 1110 } |
| 1089 | 1111 |
| 1090 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); | 1112 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); |
| 1091 } | 1113 } |
| 1092 | 1114 |
| 1093 base::Time OfflinePageModelImpl::GetCurrentTime() const { | 1115 base::Time OfflinePageModelImpl::GetCurrentTime() const { |
| 1094 return testing_clock_ ? testing_clock_->Now() : base::Time::Now(); | 1116 return testing_clock_ ? testing_clock_->Now() : base::Time::Now(); |
| 1095 } | 1117 } |
| 1096 | 1118 |
| 1097 } // namespace offline_pages | 1119 } // namespace offline_pages |
| OLD | NEW |