| 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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 if (online_url_without_fragment == | 639 if (online_url_without_fragment == |
| 640 id_page_pair.second.url.ReplaceComponents(remove_params)) { | 640 id_page_pair.second.url.ReplaceComponents(remove_params)) { |
| 641 result.push_back(id_page_pair.second); | 641 result.push_back(id_page_pair.second); |
| 642 } | 642 } |
| 643 } | 643 } |
| 644 | 644 |
| 645 callback.Run(result); | 645 callback.Run(result); |
| 646 } | 646 } |
| 647 | 647 |
| 648 void OfflinePageModelImpl::CheckMetadataConsistency() { | 648 void OfflinePageModelImpl::CheckMetadataConsistency() { |
| 649 DCHECK(is_loaded_); | |
| 650 archive_manager_->GetAllArchives( | 649 archive_manager_->GetAllArchives( |
| 651 base::Bind(&OfflinePageModelImpl::CheckMetadataConsistencyForArchivePaths, | 650 base::Bind(&OfflinePageModelImpl::CheckMetadataConsistencyForArchivePaths, |
| 652 weak_ptr_factory_.GetWeakPtr())); | 651 weak_ptr_factory_.GetWeakPtr())); |
| 653 } | 652 } |
| 654 | 653 |
| 655 void OfflinePageModelImpl::ExpirePages( | 654 void OfflinePageModelImpl::ExpirePages( |
| 656 const std::vector<int64_t>& offline_ids, | 655 const std::vector<int64_t>& offline_ids, |
| 657 const base::Time& expiration_time, | 656 const base::Time& expiration_time, |
| 658 const base::Callback<void(bool)>& callback) { | 657 const base::Callback<void(bool)>& callback) { |
| 659 std::vector<base::FilePath> paths_to_delete; | 658 std::vector<base::FilePath> paths_to_delete; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 } else if (status == ItemActionStatus::ALREADY_EXISTS) { | 785 } else if (status == ItemActionStatus::ALREADY_EXISTS) { |
| 787 result = SavePageResult::ALREADY_EXISTS; | 786 result = SavePageResult::ALREADY_EXISTS; |
| 788 } else { | 787 } else { |
| 789 result = SavePageResult::STORE_FAILURE; | 788 result = SavePageResult::STORE_FAILURE; |
| 790 } | 789 } |
| 791 InformSavePageDone(callback, result, offline_page.client_id, | 790 InformSavePageDone(callback, result, offline_page.client_id, |
| 792 offline_page.offline_id); | 791 offline_page.offline_id); |
| 793 if (result == SavePageResult::SUCCESS) { | 792 if (result == SavePageResult::SUCCESS) { |
| 794 DeleteExistingPagesWithSameURL(offline_page); | 793 DeleteExistingPagesWithSameURL(offline_page); |
| 795 } else { | 794 } else { |
| 796 PostClearStorageIfNeededTask(); | 795 PostClearStorageIfNeededTask(false /* delayed */); |
| 797 } | 796 } |
| 798 | 797 |
| 799 DeletePendingArchiver(archiver); | 798 DeletePendingArchiver(archiver); |
| 800 for (Observer& observer : observers_) | 799 for (Observer& observer : observers_) |
| 801 observer.OfflinePageModelChanged(this); | 800 observer.OfflinePageModelChanged(this); |
| 802 } | 801 } |
| 803 | 802 |
| 804 void OfflinePageModelImpl::OnMarkPageAccesseDone( | 803 void OfflinePageModelImpl::OnMarkPageAccesseDone( |
| 805 const OfflinePageItem& offline_page_item, | 804 const OfflinePageItem& offline_page_item, |
| 806 std::unique_ptr<OfflinePagesUpdateResult> result) { | 805 std::unique_ptr<OfflinePagesUpdateResult> result) { |
| 807 // Update the item in the cache only upon success. | 806 // Update the item in the cache only upon success. |
| 808 if (result->updated_items.size() > 0) | 807 if (result->updated_items.size() > 0) |
| 809 offline_pages_[offline_page_item.offline_id] = offline_page_item; | 808 offline_pages_[offline_page_item.offline_id] = offline_page_item; |
| 810 | 809 |
| 811 // No need to fire OfflinePageModelChanged event since updating access info | 810 // No need to fire OfflinePageModelChanged event since updating access info |
| 812 // should not have any impact to the UI. | 811 // should not have any impact to the UI. |
| 813 } | 812 } |
| 814 | 813 |
| 815 void OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone( | 814 void OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone( |
| 816 const base::TimeTicks& start_time) { | 815 const base::TimeTicks& start_time) { |
| 817 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime", | 816 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime", |
| 818 base::TimeTicks::Now() - start_time); | 817 base::TimeTicks::Now() - start_time); |
| 819 | 818 |
| 820 store_->GetOfflinePages(base::Bind(&OfflinePageModelImpl::OnLoadDone, | 819 const int kResetAttemptsLeft = 1; |
| 821 weak_ptr_factory_.GetWeakPtr(), | 820 store_->Initialize(base::Bind(&OfflinePageModelImpl::OnStoreInitialized, |
| 822 start_time)); | 821 weak_ptr_factory_.GetWeakPtr(), start_time, |
| 822 kResetAttemptsLeft)); |
| 823 } | 823 } |
| 824 | 824 |
| 825 void OfflinePageModelImpl::OnLoadDone( | 825 void OfflinePageModelImpl::OnStoreInitialized(const base::TimeTicks& start_time, |
| 826 int reset_attempts_left, |
| 827 bool success) { |
| 828 if (success) { |
| 829 DCHECK_EQ(store_->state(), StoreState::LOADED); |
| 830 store_->GetOfflinePages( |
| 831 base::Bind(&OfflinePageModelImpl::OnInitialGetOfflinePagesDone, |
| 832 weak_ptr_factory_.GetWeakPtr(), start_time)); |
| 833 return; |
| 834 } |
| 835 |
| 836 DCHECK_EQ(store_->state(), StoreState::FAILED_LOADING); |
| 837 // If there are no more reset attempts left, stop here. |
| 838 if (reset_attempts_left == 0) { |
| 839 FinalizeModelLoad(); |
| 840 return; |
| 841 } |
| 842 |
| 843 // Otherwise reduce the remaining attempts counter and reset store. |
| 844 store_->Reset(base::Bind(&OfflinePageModelImpl::OnStoreResetDone, |
| 845 weak_ptr_factory_.GetWeakPtr(), start_time, |
| 846 reset_attempts_left - 1)); |
| 847 } |
| 848 |
| 849 void OfflinePageModelImpl::OnStoreResetDone(const base::TimeTicks& start_time, |
| 850 int reset_attempts_left, |
| 851 bool success) { |
| 852 if (success) { |
| 853 DCHECK_EQ(store_->state(), StoreState::NOT_LOADED); |
| 854 store_->Initialize(base::Bind(&OfflinePageModelImpl::OnStoreInitialized, |
| 855 weak_ptr_factory_.GetWeakPtr(), start_time, |
| 856 reset_attempts_left)); |
| 857 return; |
| 858 } |
| 859 |
| 860 DCHECK_EQ(store_->state(), StoreState::FAILED_RESET); |
| 861 FinalizeModelLoad(); |
| 862 } |
| 863 |
| 864 void OfflinePageModelImpl::OnInitialGetOfflinePagesDone( |
| 826 const base::TimeTicks& start_time, | 865 const base::TimeTicks& start_time, |
| 827 OfflinePageMetadataStore::LoadStatus load_status, | |
| 828 const std::vector<OfflinePageItem>& offline_pages) { | 866 const std::vector<OfflinePageItem>& offline_pages) { |
| 829 DCHECK(!is_loaded_); | 867 DCHECK(!is_loaded_); |
| 830 is_loaded_ = true; | |
| 831 | |
| 832 // TODO(jianli): rebuild the store upon failure. | |
| 833 | |
| 834 if (load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED) | |
| 835 CacheLoadedData(offline_pages); | |
| 836 | 868 |
| 837 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ConstructionToLoadedEventTime", | 869 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ConstructionToLoadedEventTime", |
| 838 base::TimeTicks::Now() - start_time); | 870 base::TimeTicks::Now() - start_time); |
| 839 | 871 |
| 840 // Create Storage Manager. | 872 CacheLoadedData(offline_pages); |
| 841 storage_manager_.reset(new OfflinePageStorageManager( | 873 FinalizeModelLoad(); |
| 842 this, GetPolicyController(), archive_manager_.get())); | 874 |
| 875 // Ensure necessary cleanup operations are started. |
| 876 CheckMetadataConsistency(); |
| 877 } |
| 878 |
| 879 void OfflinePageModelImpl::FinalizeModelLoad() { |
| 880 is_loaded_ = true; |
| 881 |
| 882 // All actions below are meant to be taken regardless of successful load of |
| 883 // the store. |
| 884 |
| 885 // Inform observers the load is done. |
| 886 for (Observer& observer : observers_) |
| 887 observer.OfflinePageModelLoaded(this); |
| 843 | 888 |
| 844 // Run all the delayed tasks. | 889 // Run all the delayed tasks. |
| 845 for (const auto& delayed_task : delayed_tasks_) | 890 for (const auto& delayed_task : delayed_tasks_) |
| 846 delayed_task.Run(); | 891 delayed_task.Run(); |
| 847 delayed_tasks_.clear(); | 892 delayed_tasks_.clear(); |
| 848 | 893 |
| 849 for (Observer& observer : observers_) | 894 // Clear storage. |
| 850 observer.OfflinePageModelLoaded(this); | 895 PostClearStorageIfNeededTask(true /* delayed */); |
| 851 | |
| 852 CheckMetadataConsistency(); | |
| 853 | |
| 854 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 855 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded, | |
| 856 weak_ptr_factory_.GetWeakPtr(), | |
| 857 base::Bind(&OfflinePageModelImpl::OnStorageCleared, | |
| 858 weak_ptr_factory_.GetWeakPtr())), | |
| 859 kStorageManagerStartingDelay); | |
| 860 } | 896 } |
| 861 | 897 |
| 862 void OfflinePageModelImpl::InformSavePageDone(const SavePageCallback& callback, | 898 void OfflinePageModelImpl::InformSavePageDone(const SavePageCallback& callback, |
| 863 SavePageResult result, | 899 SavePageResult result, |
| 864 const ClientId& client_id, | 900 const ClientId& client_id, |
| 865 int64_t offline_id) { | 901 int64_t offline_id) { |
| 866 ReportSavePageResultHistogramAfterSave(client_id, result); | 902 ReportSavePageResultHistogramAfterSave(client_id, result); |
| 867 archive_manager_->GetStorageStats( | 903 archive_manager_->GetStorageStats( |
| 868 base::Bind(&ReportStorageHistogramsAfterSave)); | 904 base::Bind(&ReportStorageHistogramsAfterSave)); |
| 869 callback.Run(result, offline_id); | 905 callback.Run(result, offline_id); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 page_ids_to_delete.push_back(item.offline_id); | 944 page_ids_to_delete.push_back(item.offline_id); |
| 909 DeletePagesByOfflineId( | 945 DeletePagesByOfflineId( |
| 910 page_ids_to_delete, | 946 page_ids_to_delete, |
| 911 base::Bind(&OfflinePageModelImpl::OnDeleteOldPagesWithSameURL, | 947 base::Bind(&OfflinePageModelImpl::OnDeleteOldPagesWithSameURL, |
| 912 weak_ptr_factory_.GetWeakPtr())); | 948 weak_ptr_factory_.GetWeakPtr())); |
| 913 } | 949 } |
| 914 | 950 |
| 915 void OfflinePageModelImpl::OnDeleteOldPagesWithSameURL( | 951 void OfflinePageModelImpl::OnDeleteOldPagesWithSameURL( |
| 916 DeletePageResult result) { | 952 DeletePageResult result) { |
| 917 // TODO(romax) Add UMAs for failure cases. | 953 // TODO(romax) Add UMAs for failure cases. |
| 918 PostClearStorageIfNeededTask(); | 954 PostClearStorageIfNeededTask(false /* delayed */); |
| 919 } | 955 } |
| 920 | 956 |
| 921 void OfflinePageModelImpl::DeletePendingArchiver( | 957 void OfflinePageModelImpl::DeletePendingArchiver( |
| 922 OfflinePageArchiver* archiver) { | 958 OfflinePageArchiver* archiver) { |
| 923 pending_archivers_.erase(std::find(pending_archivers_.begin(), | 959 pending_archivers_.erase(std::find(pending_archivers_.begin(), |
| 924 pending_archivers_.end(), archiver)); | 960 pending_archivers_.end(), archiver)); |
| 925 } | 961 } |
| 926 | 962 |
| 927 void OfflinePageModelImpl::OnDeleteArchiveFilesDone( | 963 void OfflinePageModelImpl::OnDeleteArchiveFilesDone( |
| 928 const std::vector<int64_t>& offline_ids, | 964 const std::vector<int64_t>& offline_ids, |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 | 1083 |
| 1048 void OfflinePageModelImpl::CacheLoadedData( | 1084 void OfflinePageModelImpl::CacheLoadedData( |
| 1049 const std::vector<OfflinePageItem>& offline_pages) { | 1085 const std::vector<OfflinePageItem>& offline_pages) { |
| 1050 offline_pages_.clear(); | 1086 offline_pages_.clear(); |
| 1051 for (const auto& offline_page : offline_pages) | 1087 for (const auto& offline_page : offline_pages) |
| 1052 offline_pages_[offline_page.offline_id] = offline_page; | 1088 offline_pages_[offline_page.offline_id] = offline_page; |
| 1053 } | 1089 } |
| 1054 | 1090 |
| 1055 void OfflinePageModelImpl::ClearStorageIfNeeded( | 1091 void OfflinePageModelImpl::ClearStorageIfNeeded( |
| 1056 const ClearStorageCallback& callback) { | 1092 const ClearStorageCallback& callback) { |
| 1093 // Create Storage Manager if necessary. |
| 1094 if (!storage_manager_) { |
| 1095 storage_manager_.reset(new OfflinePageStorageManager( |
| 1096 this, GetPolicyController(), archive_manager_.get())); |
| 1097 } |
| 1057 storage_manager_->ClearPagesIfNeeded(callback); | 1098 storage_manager_->ClearPagesIfNeeded(callback); |
| 1058 } | 1099 } |
| 1059 | 1100 |
| 1060 void OfflinePageModelImpl::OnStorageCleared(size_t expired_page_count, | 1101 void OfflinePageModelImpl::OnStorageCleared(size_t expired_page_count, |
| 1061 ClearStorageResult result) { | 1102 ClearStorageResult result) { |
| 1062 UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearStorageResult", | 1103 UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearStorageResult", |
| 1063 static_cast<int>(result), | 1104 static_cast<int>(result), |
| 1064 static_cast<int>(ClearStorageResult::RESULT_COUNT)); | 1105 static_cast<int>(ClearStorageResult::RESULT_COUNT)); |
| 1065 if (expired_page_count > 0) { | 1106 if (expired_page_count > 0) { |
| 1066 UMA_HISTOGRAM_COUNTS("OfflinePages.ExpirePage.BatchSize", | 1107 UMA_HISTOGRAM_COUNTS("OfflinePages.ExpirePage.BatchSize", |
| 1067 static_cast<int32_t>(expired_page_count)); | 1108 static_cast<int32_t>(expired_page_count)); |
| 1068 } | 1109 } |
| 1069 } | 1110 } |
| 1070 | 1111 |
| 1071 void OfflinePageModelImpl::PostClearStorageIfNeededTask() { | 1112 void OfflinePageModelImpl::PostClearStorageIfNeededTask(bool delayed) { |
| 1072 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1113 base::TimeDelta delay = |
| 1114 delayed ? kStorageManagerStartingDelay : base::TimeDelta(); |
| 1115 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 1073 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded, | 1116 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded, |
| 1074 weak_ptr_factory_.GetWeakPtr(), | 1117 weak_ptr_factory_.GetWeakPtr(), |
| 1075 base::Bind(&OfflinePageModelImpl::OnStorageCleared, | 1118 base::Bind(&OfflinePageModelImpl::OnStorageCleared, |
| 1076 weak_ptr_factory_.GetWeakPtr()))); | 1119 weak_ptr_factory_.GetWeakPtr())), |
| 1120 delay); |
| 1077 } | 1121 } |
| 1078 | 1122 |
| 1079 bool OfflinePageModelImpl::IsRemovedOnCacheReset( | 1123 bool OfflinePageModelImpl::IsRemovedOnCacheReset( |
| 1080 const OfflinePageItem& offline_page) const { | 1124 const OfflinePageItem& offline_page) const { |
| 1081 return policy_controller_->IsRemovedOnCacheReset( | 1125 return policy_controller_->IsRemovedOnCacheReset( |
| 1082 offline_page.client_id.name_space); | 1126 offline_page.client_id.name_space); |
| 1083 } | 1127 } |
| 1084 | 1128 |
| 1085 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) { | 1129 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) { |
| 1086 if (!is_loaded_) { | 1130 if (!is_loaded_) { |
| 1087 delayed_tasks_.push_back(task); | 1131 delayed_tasks_.push_back(task); |
| 1088 return; | 1132 return; |
| 1089 } | 1133 } |
| 1090 | 1134 |
| 1091 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); | 1135 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); |
| 1092 } | 1136 } |
| 1093 | 1137 |
| 1094 base::Time OfflinePageModelImpl::GetCurrentTime() const { | 1138 base::Time OfflinePageModelImpl::GetCurrentTime() const { |
| 1095 return testing_clock_ ? testing_clock_->Now() : base::Time::Now(); | 1139 return testing_clock_ ? testing_clock_->Now() : base::Time::Now(); |
| 1096 } | 1140 } |
| 1097 | 1141 |
| 1098 } // namespace offline_pages | 1142 } // namespace offline_pages |
| OLD | NEW |