Chromium Code Reviews| Index: components/offline_pages/offline_page_model.cc |
| diff --git a/components/offline_pages/offline_page_model.cc b/components/offline_pages/offline_page_model.cc |
| index beb622cafba81da6ccb0c704dd381c956dde9c9b..738d8fb4c27ae00b076d345e03516cfd3750b468 100644 |
| --- a/components/offline_pages/offline_page_model.cc |
| +++ b/components/offline_pages/offline_page_model.cc |
| @@ -4,860 +4,18 @@ |
| #include "components/offline_pages/offline_page_model.h" |
| -#include <algorithm> |
| -#include <utility> |
| - |
| -#include "base/bind.h" |
| -#include "base/files/file_util.h" |
| -#include "base/location.h" |
| -#include "base/logging.h" |
| -#include "base/metrics/histogram_macros.h" |
| -#include "base/optional.h" |
| -#include "base/rand_util.h" |
| -#include "base/sequenced_task_runner.h" |
| -#include "base/strings/string_number_conversions.h" |
| -#include "base/threading/thread_task_runner_handle.h" |
| -#include "base/time/time.h" |
| -#include "components/offline_pages/archive_manager.h" |
| -#include "components/offline_pages/client_policy_controller.h" |
| -#include "components/offline_pages/offline_page_item.h" |
| -#include "components/offline_pages/offline_page_storage_manager.h" |
| #include "url/gurl.h" |
| -using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult; |
| - |
| namespace offline_pages { |
| -namespace { |
| - |
| -// This enum is used in an UMA histogram. Hence the entries here shouldn't |
| -// be deleted or re-ordered and new ones should be added to the end. |
| -enum ClearAllStatus { |
| - CLEAR_ALL_SUCCEEDED, |
| - STORE_RESET_FAILED, |
| - STORE_RELOAD_FAILED, |
| - |
| - // NOTE: always keep this entry at the end. |
| - CLEAR_ALL_STATUS_COUNT |
| -}; |
| - |
| -// The maximum histogram size for the metrics that measure time between views of |
| -// a given page. |
| -const base::TimeDelta kMaxOpenedPageHistogramBucket = |
| - base::TimeDelta::FromDays(90); |
| - |
| -SavePageResult ToSavePageResult(ArchiverResult archiver_result) { |
| - SavePageResult result; |
| - switch (archiver_result) { |
| - case ArchiverResult::SUCCESSFULLY_CREATED: |
| - result = SavePageResult::SUCCESS; |
| - break; |
| - case ArchiverResult::ERROR_DEVICE_FULL: |
| - result = SavePageResult::DEVICE_FULL; |
| - break; |
| - case ArchiverResult::ERROR_CONTENT_UNAVAILABLE: |
| - result = SavePageResult::CONTENT_UNAVAILABLE; |
| - break; |
| - case ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED: |
| - result = SavePageResult::ARCHIVE_CREATION_FAILED; |
| - break; |
| - case ArchiverResult::ERROR_CANCELED: |
| - result = SavePageResult::CANCELLED; |
| - break; |
| - case ArchiverResult::ERROR_SECURITY_CERTIFICATE: |
| - result = SavePageResult::SECURITY_CERTIFICATE_ERROR; |
| - break; |
| - default: |
| - NOTREACHED(); |
| - result = SavePageResult::CONTENT_UNAVAILABLE; |
| - } |
| - return result; |
| -} |
| - |
| -std::string AddHistogramSuffix(const ClientId& client_id, |
| - const char* histogram_name) { |
| - if (client_id.name_space.empty()) { |
| - NOTREACHED(); |
| - return histogram_name; |
| - } |
| - std::string adjusted_histogram_name(histogram_name); |
| - adjusted_histogram_name += "."; |
| - adjusted_histogram_name += client_id.name_space; |
| - return adjusted_histogram_name; |
| -} |
| - |
| -void ReportStorageHistogramsAfterSave( |
| - const ArchiveManager::StorageStats& storage_stats) { |
| - const int kMB = 1024 * 1024; |
| - int free_disk_space_mb = |
| - static_cast<int>(storage_stats.free_disk_space / kMB); |
| - UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.SavePage.FreeSpaceMB", |
| - free_disk_space_mb, 1, 500000, 50); |
| - |
| - int total_page_size_mb = |
| - static_cast<int>(storage_stats.total_archives_size / kMB); |
| - UMA_HISTOGRAM_COUNTS_10000("OfflinePages.TotalPageSize", total_page_size_mb); |
| -} |
| - |
| -void ReportStorageHistogramsAfterDelete( |
| - const ArchiveManager::StorageStats& storage_stats) { |
| - const int kMB = 1024 * 1024; |
| - int free_disk_space_mb = |
| - static_cast<int>(storage_stats.free_disk_space / kMB); |
| - UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.DeletePage.FreeSpaceMB", |
| - free_disk_space_mb, 1, 500000, 50); |
| - |
| - int total_page_size_mb = |
| - static_cast<int>(storage_stats.total_archives_size / kMB); |
| - UMA_HISTOGRAM_COUNTS_10000("OfflinePages.TotalPageSize", total_page_size_mb); |
| - |
| - if (storage_stats.free_disk_space > 0) { |
| - int percentage_of_free = static_cast<int>( |
| - 1.0 * storage_stats.total_archives_size / |
| - (storage_stats.total_archives_size + storage_stats.free_disk_space) * |
| - 100); |
| - UMA_HISTOGRAM_PERCENTAGE( |
| - "OfflinePages.DeletePage.TotalPageSizeAsPercentageOfFreeSpace", |
| - percentage_of_free); |
| - } |
| -} |
| - |
| -} // namespace |
| - |
| // static |
| bool OfflinePageModel::CanSavePage(const GURL& url) { |
| return url.SchemeIsHTTPOrHTTPS(); |
| } |
| -// protected |
| -OfflinePageModel::OfflinePageModel() |
| - : is_loaded_(false), weak_ptr_factory_(this) {} |
| - |
| -OfflinePageModel::OfflinePageModel( |
| - std::unique_ptr<OfflinePageMetadataStore> store, |
| - const base::FilePath& archives_dir, |
| - const scoped_refptr<base::SequencedTaskRunner>& task_runner) |
| - : store_(std::move(store)), |
| - archives_dir_(archives_dir), |
| - is_loaded_(false), |
| - policy_controller_(new ClientPolicyController()), |
| - archive_manager_(new ArchiveManager(archives_dir, task_runner)), |
| - weak_ptr_factory_(this) { |
| - archive_manager_->EnsureArchivesDirCreated( |
| - base::Bind(&OfflinePageModel::OnEnsureArchivesDirCreatedDone, |
| - weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())); |
| -} |
| +OfflinePageModel::OfflinePageModel() {} |
| OfflinePageModel::~OfflinePageModel() { |
|
romax
2016/05/26 01:26:48
nit:put the braces on the same line as above?
dougarnett
2016/05/26 16:03:22
Done.
|
| } |
| -void OfflinePageModel::AddObserver(Observer* observer) { |
| - observers_.AddObserver(observer); |
| -} |
| - |
| -void OfflinePageModel::RemoveObserver(Observer* observer) { |
| - observers_.RemoveObserver(observer); |
| -} |
| - |
| -void OfflinePageModel::SavePage(const GURL& url, |
| - const ClientId& client_id, |
| - std::unique_ptr<OfflinePageArchiver> archiver, |
| - const SavePageCallback& callback) { |
| - DCHECK(is_loaded_); |
| - |
| - // Skip saving the page that is not intended to be saved, like local file |
| - // page. |
| - if (url.is_valid() && !CanSavePage(url)) { |
| - InformSavePageDone(callback, SavePageResult::SKIPPED, client_id, |
| - kInvalidOfflineId); |
| - return; |
| - } |
| - |
| - // The web contents is not available if archiver is not created and passed. |
| - if (!archiver.get()) { |
| - InformSavePageDone(callback, SavePageResult::CONTENT_UNAVAILABLE, client_id, |
| - kInvalidOfflineId); |
| - return; |
| - } |
| - |
| - int64_t offline_id = GenerateOfflineId(); |
| - |
| - archiver->CreateArchive( |
| - archives_dir_, |
| - offline_id, |
| - base::Bind(&OfflinePageModel::OnCreateArchiveDone, |
| - weak_ptr_factory_.GetWeakPtr(), url, offline_id, |
| - client_id, base::Time::Now(), callback)); |
| - pending_archivers_.push_back(std::move(archiver)); |
| -} |
| - |
| -void OfflinePageModel::MarkPageAccessed(int64_t offline_id) { |
| - DCHECK(is_loaded_); |
| - auto iter = offline_pages_.find(offline_id); |
| - if (iter == offline_pages_.end()) |
| - return; |
| - |
| - // Make a copy of the cached item and update it. The cached item should only |
| - // be updated upon the successful store operation. |
| - OfflinePageItem offline_page_item = iter->second; |
| - |
| - base::Time now = base::Time::Now(); |
| - base::TimeDelta time_since_last_accessed = |
| - now - offline_page_item.last_access_time; |
| - |
| - // When the access account is still zero, the page is opened for the first |
| - // time since its creation. |
| - UMA_HISTOGRAM_CUSTOM_COUNTS( |
| - AddHistogramSuffix( |
| - offline_page_item.client_id, |
| - (offline_page_item.access_count == 0) ? |
| - "OfflinePages.FirstOpenSinceCreated" : |
| - "OfflinePages.OpenSinceLastOpen").c_str(), |
| - time_since_last_accessed.InMinutes(), 1, |
| - kMaxOpenedPageHistogramBucket.InMinutes(), 50); |
| - |
| - offline_page_item.last_access_time = now; |
| - offline_page_item.access_count++; |
| - |
| - store_->AddOrUpdateOfflinePage( |
| - offline_page_item, |
| - base::Bind(&OfflinePageModel::OnMarkPageAccesseDone, |
| - weak_ptr_factory_.GetWeakPtr(), offline_page_item)); |
| -} |
| - |
| -void OfflinePageModel::DeletePagesByOfflineId( |
| - const std::vector<int64_t>& offline_ids, |
| - const DeletePageCallback& callback) { |
| - if (!is_loaded_) { |
| - delayed_tasks_.push_back( |
| - base::Bind(&OfflinePageModel::DoDeletePagesByOfflineId, |
| - weak_ptr_factory_.GetWeakPtr(), offline_ids, callback)); |
| - |
| - return; |
| - } |
| - DoDeletePagesByOfflineId(offline_ids, callback); |
| -} |
| - |
| -void OfflinePageModel::DoDeletePagesByOfflineId( |
| - const std::vector<int64_t>& offline_ids, |
| - const DeletePageCallback& callback) { |
| - DCHECK(is_loaded_); |
| - |
| - std::vector<base::FilePath> paths_to_delete; |
| - for (const auto& offline_id : offline_ids) { |
| - auto iter = offline_pages_.find(offline_id); |
| - if (iter != offline_pages_.end()) { |
| - paths_to_delete.push_back(iter->second.file_path); |
| - } |
| - } |
| - |
| - if (paths_to_delete.empty()) { |
| - InformDeletePageDone(callback, DeletePageResult::NOT_FOUND); |
| - return; |
| - } |
| - |
| - archive_manager_->DeleteMultipleArchives( |
| - paths_to_delete, |
| - base::Bind(&OfflinePageModel::OnDeleteArchiveFilesDone, |
| - weak_ptr_factory_.GetWeakPtr(), offline_ids, callback)); |
| -} |
| - |
| -void OfflinePageModel::ClearAll(const base::Closure& callback) { |
| - DCHECK(is_loaded_); |
| - |
| - std::vector<int64_t> offline_ids; |
| - for (const auto& id_page_pair : offline_pages_) |
| - offline_ids.push_back(id_page_pair.first); |
| - DeletePagesByOfflineId( |
| - offline_ids, |
| - base::Bind(&OfflinePageModel::OnRemoveAllFilesDoneForClearAll, |
| - weak_ptr_factory_.GetWeakPtr(), callback)); |
| -} |
| - |
| -void OfflinePageModel::DeletePagesByURLPredicate( |
| - const UrlPredicate& predicate, |
| - const DeletePageCallback& callback) { |
| - if (!is_loaded_) { |
| - delayed_tasks_.push_back( |
| - base::Bind(&OfflinePageModel::DoDeletePagesByURLPredicate, |
| - weak_ptr_factory_.GetWeakPtr(), predicate, callback)); |
| - |
| - return; |
| - } |
| - DoDeletePagesByURLPredicate(predicate, callback); |
| -} |
| - |
| -void OfflinePageModel::DoDeletePagesByURLPredicate( |
| - const UrlPredicate& predicate, |
| - const DeletePageCallback& callback) { |
| - DCHECK(is_loaded_); |
| - |
| - std::vector<int64_t> offline_ids; |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (predicate.Run(id_page_pair.second.url)) |
| - offline_ids.push_back(id_page_pair.first); |
| - } |
| - DoDeletePagesByOfflineId(offline_ids, callback); |
| -} |
| - |
| -void OfflinePageModel::HasPages(const std::string& name_space, |
| - const HasPagesCallback& callback) { |
| - RunWhenLoaded(base::Bind(&OfflinePageModel::HasPagesAfterLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), name_space, |
| - callback)); |
| -} |
| - |
| -void OfflinePageModel::HasPagesAfterLoadDone( |
| - const std::string& name_space, |
| - const HasPagesCallback& callback) const { |
| - DCHECK(is_loaded_); |
| - |
| - bool has_pages = false; |
| - |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (id_page_pair.second.client_id.name_space == name_space) { |
| - has_pages = true; |
| - break; |
| - } |
| - } |
| - |
| - callback.Run(has_pages); |
| -} |
| - |
| -void OfflinePageModel::CheckPagesExistOffline( |
| - const std::set<GURL>& urls, |
| - const CheckPagesExistOfflineCallback& callback) { |
| - RunWhenLoaded( |
| - base::Bind(&OfflinePageModel::CheckPagesExistOfflineAfterLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), urls, callback)); |
| -} |
| - |
| -void OfflinePageModel::CheckPagesExistOfflineAfterLoadDone( |
| - const std::set<GURL>& urls, |
| - const CheckPagesExistOfflineCallback& callback) { |
| - DCHECK(is_loaded_); |
| - CheckPagesExistOfflineResult result; |
| - for (const auto& id_page_pair : offline_pages_) { |
| - auto iter = urls.find(id_page_pair.second.url); |
| - if (iter != urls.end()) |
| - result.insert(*iter); |
| - } |
| - callback.Run(result); |
| -} |
| - |
| -void OfflinePageModel::GetAllPages( |
| - const MultipleOfflinePageItemCallback& callback) { |
| - RunWhenLoaded(base::Bind(&OfflinePageModel::GetAllPagesAfterLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), callback)); |
| -} |
| - |
| -void OfflinePageModel::GetAllPagesAfterLoadDone( |
| - const MultipleOfflinePageItemCallback& callback) { |
| - DCHECK(is_loaded_); |
| - |
| - MultipleOfflinePageItemResult offline_pages; |
| - for (const auto& id_page_pair : offline_pages_) |
| - offline_pages.push_back(id_page_pair.second); |
| - |
| - callback.Run(offline_pages); |
| -} |
| - |
| -void OfflinePageModel::GetOfflineIdsForClientId( |
| - const ClientId& client_id, |
| - const MultipleOfflineIdCallback& callback) { |
| - RunWhenLoaded( |
| - base::Bind(&OfflinePageModel::GetOfflineIdsForClientIdWhenLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), client_id, callback)); |
| -} |
| - |
| -void OfflinePageModel::GetOfflineIdsForClientIdWhenLoadDone( |
| - const ClientId& client_id, |
| - const MultipleOfflineIdCallback& callback) const { |
| - callback.Run(MaybeGetOfflineIdsForClientId(client_id)); |
| -} |
| - |
| -const std::vector<int64_t> OfflinePageModel::MaybeGetOfflineIdsForClientId( |
| - const ClientId& client_id) const { |
| - DCHECK(is_loaded_); |
| - std::vector<int64_t> results; |
| - |
| - // We want only all pages, including those marked for deletion. |
| - // TODO(bburns): actually use an index rather than linear scan. |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (id_page_pair.second.client_id == client_id) |
| - results.push_back(id_page_pair.second.offline_id); |
| - } |
| - return results; |
| -} |
| - |
| -void OfflinePageModel::GetPageByOfflineId( |
| - int64_t offline_id, |
| - const SingleOfflinePageItemCallback& callback) { |
| - RunWhenLoaded(base::Bind(&OfflinePageModel::GetPageByOfflineIdWhenLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), offline_id, |
| - callback)); |
| -} |
| - |
| -void OfflinePageModel::GetPageByOfflineIdWhenLoadDone( |
| - int64_t offline_id, |
| - const SingleOfflinePageItemCallback& callback) const { |
| - SingleOfflinePageItemResult result; |
| - const OfflinePageItem* match = MaybeGetPageByOfflineId(offline_id); |
| - if (match != nullptr) |
| - result = *match; |
| - callback.Run(result); |
| -} |
| - |
| -const OfflinePageItem* OfflinePageModel::MaybeGetPageByOfflineId( |
| - int64_t offline_id) const { |
| - const auto iter = offline_pages_.find(offline_id); |
| - return iter != offline_pages_.end() ? &(iter->second) : nullptr; |
| -} |
| - |
| -void OfflinePageModel::GetPageByOfflineURL( |
| - const GURL& offline_url, |
| - const SingleOfflinePageItemCallback& callback) { |
| - RunWhenLoaded(base::Bind(&OfflinePageModel::GetPageByOfflineURLWhenLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), offline_url, |
| - callback)); |
| -} |
| - |
| -void OfflinePageModel::GetPageByOfflineURLWhenLoadDone( |
| - const GURL& offline_url, |
| - const SingleOfflinePageItemCallback& callback) const { |
| - base::Optional<OfflinePageItem> result; |
| - |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (id_page_pair.second.GetOfflineURL() == offline_url) { |
| - callback.Run(base::make_optional(id_page_pair.second)); |
| - return; |
| - } |
| - } |
| - |
| - callback.Run(base::nullopt); |
| -} |
| - |
| -const OfflinePageItem* OfflinePageModel::MaybeGetPageByOfflineURL( |
| - const GURL& offline_url) const { |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (id_page_pair.second.GetOfflineURL() == offline_url) |
| - return &(id_page_pair.second); |
| - } |
| - return nullptr; |
| -} |
| - |
| -void OfflinePageModel::GetBestPageForOnlineURL( |
| - const GURL& online_url, |
| - const SingleOfflinePageItemCallback callback) { |
| - RunWhenLoaded( |
| - base::Bind(&OfflinePageModel::GetBestPageForOnlineURLWhenLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), online_url, callback)); |
| -} |
| - |
| -void OfflinePageModel::GetBestPageForOnlineURLWhenLoadDone( |
| - const GURL& online_url, |
| - const SingleOfflinePageItemCallback& callback) const { |
| - SingleOfflinePageItemResult result; |
| - |
| - const OfflinePageItem* best_page = MaybeGetBestPageForOnlineURL(online_url); |
| - if (best_page != nullptr) |
| - result = *best_page; |
| - |
| - callback.Run(result); |
| -} |
| - |
| -void OfflinePageModel::GetPagesByOnlineURL( |
| - const GURL& online_url, |
| - const MultipleOfflinePageItemCallback& callback) { |
| - RunWhenLoaded(base::Bind(&OfflinePageModel::GetPagesByOnlineURLWhenLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), online_url, |
| - callback)); |
| -} |
| - |
| -void OfflinePageModel::GetPagesByOnlineURLWhenLoadDone( |
| - const GURL& online_url, |
| - const MultipleOfflinePageItemCallback& callback) const { |
| - std::vector<OfflinePageItem> result; |
| - |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (id_page_pair.second.url == online_url) |
| - result.push_back(id_page_pair.second); |
| - } |
| - |
| - callback.Run(result); |
| -} |
| - |
| -const OfflinePageItem* OfflinePageModel::MaybeGetBestPageForOnlineURL( |
| - const GURL& online_url) const { |
| - const OfflinePageItem* result = nullptr; |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (id_page_pair.second.url == online_url) { |
| - if (!result || id_page_pair.second.creation_time > result->creation_time) |
| - result = &(id_page_pair.second); |
| - } |
| - } |
| - return result; |
| -} |
| - |
| -void OfflinePageModel::CheckForExternalFileDeletion() { |
| - DCHECK(is_loaded_); |
| - |
| - archive_manager_->GetAllArchives( |
| - base::Bind(&OfflinePageModel::ScanForMissingArchiveFiles, |
| - weak_ptr_factory_.GetWeakPtr())); |
| -} |
| - |
| -void OfflinePageModel::ExpirePages(const std::vector<int64_t>& offline_ids, |
| - const base::Time& expiration_time) { |
| - for (int64_t offline_id : offline_ids) { |
| - auto iter = offline_pages_.find(offline_id); |
| - if (iter == offline_pages_.end()) |
| - continue; |
| - |
| - OfflinePageItem offline_page = iter->second; |
| - offline_page.expiration_time = expiration_time; |
| - |
| - store_->AddOrUpdateOfflinePage( |
| - offline_page, base::Bind(&OfflinePageModel::OnExpirePageDone, |
| - weak_ptr_factory_.GetWeakPtr(), offline_id, |
| - expiration_time)); |
| - } |
| -} |
| - |
| -void OfflinePageModel::OnExpirePageDone(int64_t offline_id, |
| - const base::Time& expiration_time, |
| - bool success) { |
| - // TODO(romax): Report UMA about successful expiration. |
| - if (success) { |
| - auto iter = offline_pages_.find(offline_id); |
| - if (iter != offline_pages_.end()) |
| - iter->second.expiration_time = expiration_time; |
| - } |
| -} |
| - |
| -ClientPolicyController* OfflinePageModel::GetPolicyController() { |
| - return policy_controller_.get(); |
| -} |
| - |
| -OfflinePageMetadataStore* OfflinePageModel::GetStoreForTesting() { |
| - return store_.get(); |
| -} |
| - |
| -OfflinePageStorageManager* OfflinePageModel::GetStorageManager() { |
| - return storage_manager_.get(); |
| -} |
| - |
| -bool OfflinePageModel::is_loaded() const { |
| - return is_loaded_; |
| -} |
| - |
| -void OfflinePageModel::OnCreateArchiveDone(const GURL& requested_url, |
| - int64_t offline_id, |
| - const ClientId& client_id, |
| - const base::Time& start_time, |
| - const SavePageCallback& callback, |
| - OfflinePageArchiver* archiver, |
| - ArchiverResult archiver_result, |
| - const GURL& url, |
| - const base::FilePath& file_path, |
| - int64_t file_size) { |
| - if (requested_url != url) { |
| - DVLOG(1) << "Saved URL does not match requested URL."; |
| - // TODO(fgorski): We have created an archive for a wrong URL. It should be |
| - // deleted from here, once archiver has the right functionality. |
| - InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED, |
| - client_id, offline_id); |
| - DeletePendingArchiver(archiver); |
| - return; |
| - } |
| - |
| - if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) { |
| - SavePageResult result = ToSavePageResult(archiver_result); |
| - InformSavePageDone(callback, result, client_id, offline_id); |
| - DeletePendingArchiver(archiver); |
| - return; |
| - } |
| - OfflinePageItem offline_page_item(url, offline_id, client_id, file_path, |
| - file_size, start_time); |
| - store_->AddOrUpdateOfflinePage( |
| - offline_page_item, |
| - base::Bind(&OfflinePageModel::OnAddOfflinePageDone, |
| - weak_ptr_factory_.GetWeakPtr(), archiver, callback, |
| - offline_page_item)); |
| -} |
| - |
| -void OfflinePageModel::OnAddOfflinePageDone(OfflinePageArchiver* archiver, |
| - const SavePageCallback& callback, |
| - const OfflinePageItem& offline_page, |
| - bool success) { |
| - SavePageResult result; |
| - if (success) { |
| - offline_pages_[offline_page.offline_id] = offline_page; |
| - result = SavePageResult::SUCCESS; |
| - UMA_HISTOGRAM_TIMES( |
| - AddHistogramSuffix( |
| - offline_page.client_id, "OfflinePages.SavePageTime").c_str(), |
| - base::Time::Now() - offline_page.creation_time); |
| - // 50 buckets capped between 1Kb and 10Mb. |
| - UMA_HISTOGRAM_COUNTS_10000(AddHistogramSuffix( |
| - offline_page.client_id, "OfflinePages.PageSize").c_str(), |
| - offline_page.file_size / 1024); |
| - } else { |
| - result = SavePageResult::STORE_FAILURE; |
| - } |
| - InformSavePageDone(callback, result, offline_page.client_id, |
| - offline_page.offline_id); |
| - DeletePendingArchiver(archiver); |
| - |
| - FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this)); |
| -} |
| - |
| -void OfflinePageModel::OnMarkPageAccesseDone( |
| - const OfflinePageItem& offline_page_item, bool success) { |
| - // Update the item in the cache only upon success. |
| - if (success) |
| - offline_pages_[offline_page_item.offline_id] = offline_page_item; |
| - |
| - // No need to fire OfflinePageModelChanged event since updating access info |
| - // should not have any impact to the UI. |
| -} |
| - |
| -void OfflinePageModel::OnEnsureArchivesDirCreatedDone( |
| - const base::TimeTicks& start_time) { |
| - UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime", |
| - base::TimeTicks::Now() - start_time); |
| - |
| - store_->Load(base::Bind(&OfflinePageModel::OnLoadDone, |
| - weak_ptr_factory_.GetWeakPtr(), start_time)); |
| -} |
| - |
| -void OfflinePageModel::OnLoadDone( |
| - const base::TimeTicks& start_time, |
| - OfflinePageMetadataStore::LoadStatus load_status, |
| - const std::vector<OfflinePageItem>& offline_pages) { |
| - DCHECK(!is_loaded_); |
| - is_loaded_ = true; |
| - |
| - // TODO(jianli): rebuild the store upon failure. |
| - |
| - if (load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED) |
| - CacheLoadedData(offline_pages); |
| - |
| - UMA_HISTOGRAM_TIMES("OfflinePages.Model.ConstructionToLoadedEventTime", |
| - base::TimeTicks::Now() - start_time); |
| - |
| - // Create Storage Manager. |
| - storage_manager_.reset(new OfflinePageStorageManager( |
| - this, GetPolicyController(), archive_manager_.get())); |
| - |
| - // Run all the delayed tasks. |
| - for (const auto& delayed_task : delayed_tasks_) |
| - delayed_task.Run(); |
| - delayed_tasks_.clear(); |
| - |
| - FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this)); |
| - |
| - CheckForExternalFileDeletion(); |
| -} |
| - |
| -void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback, |
| - SavePageResult result, |
| - const ClientId& client_id, |
| - int64_t offline_id) { |
| - UMA_HISTOGRAM_ENUMERATION( |
| - AddHistogramSuffix(client_id, "OfflinePages.SavePageResult").c_str(), |
| - static_cast<int>(result), |
| - static_cast<int>(SavePageResult::RESULT_COUNT)); |
| - archive_manager_->GetStorageStats( |
| - base::Bind(&ReportStorageHistogramsAfterSave)); |
| - callback.Run(result, offline_id); |
| -} |
| - |
| -void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) { |
| - pending_archivers_.erase(std::find( |
| - pending_archivers_.begin(), pending_archivers_.end(), archiver)); |
| -} |
| - |
| -void OfflinePageModel::OnDeleteArchiveFilesDone( |
| - const std::vector<int64_t>& offline_ids, |
| - const DeletePageCallback& callback, |
| - bool success) { |
| - if (!success) { |
| - InformDeletePageDone(callback, DeletePageResult::DEVICE_FAILURE); |
| - return; |
| - } |
| - |
| - store_->RemoveOfflinePages( |
| - offline_ids, |
| - base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone, |
| - weak_ptr_factory_.GetWeakPtr(), offline_ids, callback)); |
| -} |
| - |
| -void OfflinePageModel::OnRemoveOfflinePagesDone( |
| - const std::vector<int64_t>& offline_ids, |
| - const DeletePageCallback& callback, |
| - bool success) { |
| - // Delete the offline page from the in memory cache regardless of success in |
| - // store. |
| - base::Time now = base::Time::Now(); |
| - int64_t total_size = 0; |
| - for (int64_t offline_id : offline_ids) { |
| - auto iter = offline_pages_.find(offline_id); |
| - if (iter == offline_pages_.end()) |
| - continue; |
| - total_size += iter->second.file_size; |
| - ClientId client_id = iter->second.client_id; |
| - UMA_HISTOGRAM_CUSTOM_COUNTS( |
| - AddHistogramSuffix(client_id, "OfflinePages.PageLifetime").c_str(), |
| - (now - iter->second.creation_time).InMinutes(), |
| - 1, |
| - base::TimeDelta::FromDays(365).InMinutes(), |
| - 100); |
| - UMA_HISTOGRAM_CUSTOM_COUNTS( |
| - AddHistogramSuffix( |
| - client_id, "OfflinePages.DeletePage.TimeSinceLastOpen").c_str(), |
| - (now - iter->second.last_access_time).InMinutes(), |
| - 1, |
| - base::TimeDelta::FromDays(365).InMinutes(), |
| - 100); |
| - UMA_HISTOGRAM_CUSTOM_COUNTS( |
| - AddHistogramSuffix( |
| - client_id, "OfflinePages.DeletePage.LastOpenToCreated").c_str(), |
| - (iter->second.last_access_time - iter->second.creation_time). |
| - InMinutes(), |
| - 1, |
| - base::TimeDelta::FromDays(365).InMinutes(), |
| - 100); |
| - UMA_HISTOGRAM_MEMORY_KB( |
| - AddHistogramSuffix( |
| - client_id, "OfflinePages.DeletePage.PageSize").c_str(), |
| - iter->second.file_size / 1024); |
| - UMA_HISTOGRAM_COUNTS( |
| - AddHistogramSuffix( |
| - client_id, "OfflinePages.DeletePage.AccessCount").c_str(), |
| - iter->second.access_count); |
| - FOR_EACH_OBSERVER( |
| - Observer, observers_, |
| - OfflinePageDeleted(iter->second.offline_id, iter->second.client_id)); |
| - offline_pages_.erase(iter); |
| - } |
| - if (offline_ids.size() > 1) { |
| - UMA_HISTOGRAM_COUNTS("OfflinePages.BatchDelete.Count", |
| - static_cast<int32_t>(offline_ids.size())); |
| - UMA_HISTOGRAM_MEMORY_KB( |
| - "OfflinePages.BatchDelete.TotalPageSize", total_size / 1024); |
| - } |
| - // Deleting multiple pages always succeeds when it gets to this point. |
| - InformDeletePageDone(callback, (success || offline_ids.size() > 1) |
| - ? DeletePageResult::SUCCESS |
| - : DeletePageResult::STORE_FAILURE); |
| -} |
| - |
| -void OfflinePageModel::InformDeletePageDone(const DeletePageCallback& callback, |
| - DeletePageResult result) { |
| - UMA_HISTOGRAM_ENUMERATION( |
| - "OfflinePages.DeletePageResult", |
| - static_cast<int>(result), |
| - static_cast<int>(DeletePageResult::RESULT_COUNT)); |
| - archive_manager_->GetStorageStats( |
| - base::Bind(&ReportStorageHistogramsAfterDelete)); |
| - if (!callback.is_null()) |
| - callback.Run(result); |
| -} |
| - |
| -void OfflinePageModel::ScanForMissingArchiveFiles( |
| - const std::set<base::FilePath>& archive_paths) { |
| - std::vector<int64_t> ids_of_pages_missing_archive_file; |
| - std::vector<std::pair<int64_t, ClientId>> offline_client_id_pairs; |
| - for (const auto& id_page_pair : offline_pages_) { |
| - if (archive_paths.count(id_page_pair.second.file_path) == 0UL) { |
| - ids_of_pages_missing_archive_file.push_back(id_page_pair.first); |
| - offline_client_id_pairs.push_back( |
| - std::make_pair(id_page_pair.first, id_page_pair.second.client_id)); |
| - } |
| - } |
| - |
| - // No offline pages missing archive files, we can bail out. |
| - if (ids_of_pages_missing_archive_file.empty()) |
| - return; |
| - |
| - DeletePageCallback remove_pages_done_callback( |
| - base::Bind(&OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone, |
| - weak_ptr_factory_.GetWeakPtr(), offline_client_id_pairs)); |
| - |
| - store_->RemoveOfflinePages( |
| - ids_of_pages_missing_archive_file, |
| - base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone, |
| - weak_ptr_factory_.GetWeakPtr(), |
| - ids_of_pages_missing_archive_file, |
| - remove_pages_done_callback)); |
| -} |
| - |
| -void OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone( |
| - const std::vector<std::pair<int64_t, ClientId>>& offline_client_id_pairs, |
| - DeletePageResult /* result */) { |
| - for (const auto& id_pair : offline_client_id_pairs) { |
| - FOR_EACH_OBSERVER(Observer, observers_, |
| - OfflinePageDeleted(id_pair.first, id_pair.second)); |
| - } |
| -} |
| - |
| -void OfflinePageModel::OnRemoveAllFilesDoneForClearAll( |
| - const base::Closure& callback, |
| - DeletePageResult result) { |
| - store_->Reset(base::Bind(&OfflinePageModel::OnResetStoreDoneForClearAll, |
| - weak_ptr_factory_.GetWeakPtr(), |
| - callback)); |
| -} |
| - |
| -void OfflinePageModel::OnResetStoreDoneForClearAll( |
| - const base::Closure& callback, bool success) { |
| - DCHECK(success); |
| - if (!success) { |
| - UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearAllStatus2", |
| - STORE_RESET_FAILED, |
| - CLEAR_ALL_STATUS_COUNT); |
| - } |
| - |
| - offline_pages_.clear(); |
| - store_->Load(base::Bind(&OfflinePageModel::OnReloadStoreDoneForClearAll, |
| - weak_ptr_factory_.GetWeakPtr(), |
| - callback)); |
| -} |
| - |
| -void OfflinePageModel::OnReloadStoreDoneForClearAll( |
| - const base::Closure& callback, |
| - OfflinePageMetadataStore::LoadStatus load_status, |
| - const std::vector<OfflinePageItem>& offline_pages) { |
| - DCHECK_EQ(OfflinePageMetadataStore::LOAD_SUCCEEDED, load_status); |
| - UMA_HISTOGRAM_ENUMERATION( |
| - "OfflinePages.ClearAllStatus2", |
| - load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED ? |
| - CLEAR_ALL_SUCCEEDED : STORE_RELOAD_FAILED, |
| - CLEAR_ALL_STATUS_COUNT); |
| - |
| - CacheLoadedData(offline_pages); |
| - callback.Run(); |
| -} |
| - |
| -void OfflinePageModel::CacheLoadedData( |
| - const std::vector<OfflinePageItem>& offline_pages) { |
| - offline_pages_.clear(); |
| - for (const auto& offline_page : offline_pages) |
| - offline_pages_[offline_page.offline_id] = offline_page; |
| -} |
| - |
| -int64_t OfflinePageModel::GenerateOfflineId() { |
| - return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; |
| -} |
| - |
| -void OfflinePageModel::RunWhenLoaded(const base::Closure& task) { |
| - if (!is_loaded_) { |
| - delayed_tasks_.push_back(task); |
| - return; |
| - } |
| - |
| - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); |
| -} |
| - |
| } // namespace offline_pages |