Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(326)

Side by Side Diff: components/offline_pages/offline_page_model.cc

Issue 1981093002: [Offline pages] Hooking up Archive Manager to Offline Page Model (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@archive-manager
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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.h" 5 #include "components/offline_pages/offline_page_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/optional.h" 15 #include "base/optional.h"
16 #include "base/rand_util.h" 16 #include "base/rand_util.h"
17 #include "base/sequenced_task_runner.h" 17 #include "base/sequenced_task_runner.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/time/time.h" 20 #include "base/time/time.h"
21 #include "components/offline_pages/archive_manager.h"
21 #include "components/offline_pages/client_policy_controller.h" 22 #include "components/offline_pages/client_policy_controller.h"
22 #include "components/offline_pages/offline_page_item.h" 23 #include "components/offline_pages/offline_page_item.h"
23 #include "components/offline_pages/offline_page_storage_manager.h" 24 #include "components/offline_pages/offline_page_storage_manager.h"
24 #include "components/offline_pages/proto/offline_pages.pb.h" 25 #include "components/offline_pages/proto/offline_pages.pb.h"
25 #include "url/gurl.h" 26 #include "url/gurl.h"
26 27
27 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult; 28 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult;
28 29
29 namespace offline_pages { 30 namespace offline_pages {
30 31
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 case ArchiverResult::ERROR_SECURITY_CERTIFICATE: 72 case ArchiverResult::ERROR_SECURITY_CERTIFICATE:
72 result = SavePageResult::SECURITY_CERTIFICATE_ERROR; 73 result = SavePageResult::SECURITY_CERTIFICATE_ERROR;
73 break; 74 break;
74 default: 75 default:
75 NOTREACHED(); 76 NOTREACHED();
76 result = SavePageResult::CONTENT_UNAVAILABLE; 77 result = SavePageResult::CONTENT_UNAVAILABLE;
77 } 78 }
78 return result; 79 return result;
79 } 80 }
80 81
81 void DeleteArchiveFiles(const std::vector<base::FilePath>& paths_to_delete,
82 bool* success) {
83 DCHECK(success);
84 for (const auto& file_path : paths_to_delete) {
85 // Make sure delete happens on the left of || so that it is always executed.
86 *success = base::DeleteFile(file_path, false) || *success;
87 }
88 }
89
90 void FindPagesMissingArchiveFile(
91 const std::vector<std::pair<int64_t, base::FilePath>>& id_path_pairs,
92 std::vector<int64_t>* ids_of_pages_missing_archive_file) {
93 DCHECK(ids_of_pages_missing_archive_file);
94
95 for (const auto& id_path : id_path_pairs) {
96 if (!base::PathExists(id_path.second) ||
97 base::DirectoryExists(id_path.second)) {
98 ids_of_pages_missing_archive_file->push_back(id_path.first);
99 }
100 }
101 }
102
103 void EnsureArchivesDirCreated(const base::FilePath& archives_dir) {
104 CHECK(base::CreateDirectory(archives_dir));
105 }
106
107 } // namespace 82 } // namespace
108 83
109 // static 84 // static
110 bool OfflinePageModel::CanSavePage(const GURL& url) { 85 bool OfflinePageModel::CanSavePage(const GURL& url) {
111 return url.SchemeIsHTTPOrHTTPS(); 86 return url.SchemeIsHTTPOrHTTPS();
112 } 87 }
113 88
114 // protected 89 // protected
115 OfflinePageModel::OfflinePageModel() 90 OfflinePageModel::OfflinePageModel()
116 : is_loaded_(false), weak_ptr_factory_(this) {} 91 : is_loaded_(false), weak_ptr_factory_(this) {}
117 92
118 OfflinePageModel::OfflinePageModel( 93 OfflinePageModel::OfflinePageModel(
119 std::unique_ptr<OfflinePageMetadataStore> store, 94 std::unique_ptr<OfflinePageMetadataStore> store,
120 const base::FilePath& archives_dir, 95 const base::FilePath& archives_dir,
121 const scoped_refptr<base::SequencedTaskRunner>& task_runner) 96 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
122 : store_(std::move(store)), 97 : store_(std::move(store)),
123 archives_dir_(archives_dir), 98 archives_dir_(archives_dir),
124 is_loaded_(false), 99 is_loaded_(false),
125 task_runner_(task_runner),
126 policy_controller_(new ClientPolicyController()), 100 policy_controller_(new ClientPolicyController()),
101 archive_manager_(new ArchiveManager(archives_dir, task_runner)),
127 weak_ptr_factory_(this) { 102 weak_ptr_factory_(this) {
128 task_runner_->PostTaskAndReply( 103 archive_manager_->EnsureArchivesDirCreated(
129 FROM_HERE, base::Bind(EnsureArchivesDirCreated, archives_dir_),
130 base::Bind(&OfflinePageModel::OnEnsureArchivesDirCreatedDone, 104 base::Bind(&OfflinePageModel::OnEnsureArchivesDirCreatedDone,
131 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())); 105 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()));
132 } 106 }
133 107
134 OfflinePageModel::~OfflinePageModel() { 108 OfflinePageModel::~OfflinePageModel() {
135 } 109 }
136 110
137 void OfflinePageModel::AddObserver(Observer* observer) { 111 void OfflinePageModel::AddObserver(Observer* observer) {
138 observers_.AddObserver(observer); 112 observers_.AddObserver(observer);
139 } 113 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 if (iter != offline_pages_.end()) { 201 if (iter != offline_pages_.end()) {
228 paths_to_delete.push_back(iter->second.file_path); 202 paths_to_delete.push_back(iter->second.file_path);
229 } 203 }
230 } 204 }
231 205
232 if (paths_to_delete.empty()) { 206 if (paths_to_delete.empty()) {
233 InformDeletePageDone(callback, DeletePageResult::NOT_FOUND); 207 InformDeletePageDone(callback, DeletePageResult::NOT_FOUND);
234 return; 208 return;
235 } 209 }
236 210
237 bool* success = new bool(false); 211 archive_manager_->DeleteMultipleArchives(
238 task_runner_->PostTaskAndReply( 212 paths_to_delete,
239 FROM_HERE, base::Bind(&DeleteArchiveFiles, paths_to_delete, success),
240 base::Bind(&OfflinePageModel::OnDeleteArchiveFilesDone, 213 base::Bind(&OfflinePageModel::OnDeleteArchiveFilesDone,
241 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback, 214 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback));
242 base::Owned(success)));
243 } 215 }
244 216
245 void OfflinePageModel::ClearAll(const base::Closure& callback) { 217 void OfflinePageModel::ClearAll(const base::Closure& callback) {
246 DCHECK(is_loaded_); 218 DCHECK(is_loaded_);
247 219
248 std::vector<int64_t> offline_ids; 220 std::vector<int64_t> offline_ids;
249 for (const auto& id_page_pair : offline_pages_) 221 for (const auto& id_page_pair : offline_pages_)
250 offline_ids.push_back(id_page_pair.first); 222 offline_ids.push_back(id_page_pair.first);
251 DeletePagesByOfflineId( 223 DeletePagesByOfflineId(
252 offline_ids, 224 offline_ids,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 base::Bind(&OfflinePageModel::GetOfflineIdsForClientIdWhenLoadDone, 321 base::Bind(&OfflinePageModel::GetOfflineIdsForClientIdWhenLoadDone,
350 weak_ptr_factory_.GetWeakPtr(), client_id, callback)); 322 weak_ptr_factory_.GetWeakPtr(), client_id, callback));
351 } 323 }
352 324
353 void OfflinePageModel::GetOfflineIdsForClientIdWhenLoadDone( 325 void OfflinePageModel::GetOfflineIdsForClientIdWhenLoadDone(
354 const ClientId& client_id, 326 const ClientId& client_id,
355 const MultipleOfflineIdCallback& callback) const { 327 const MultipleOfflineIdCallback& callback) const {
356 callback.Run(MaybeGetOfflineIdsForClientId(client_id)); 328 callback.Run(MaybeGetOfflineIdsForClientId(client_id));
357 } 329 }
358 330
359 // TODO(fgorski): Remove include_deleted, as it no longer makes sense.
360 const std::vector<int64_t> OfflinePageModel::MaybeGetOfflineIdsForClientId( 331 const std::vector<int64_t> OfflinePageModel::MaybeGetOfflineIdsForClientId(
361 const ClientId& client_id) const { 332 const ClientId& client_id) const {
362 DCHECK(is_loaded_); 333 DCHECK(is_loaded_);
363 std::vector<int64_t> results; 334 std::vector<int64_t> results;
364 335
365 // We want only all pages, including those marked for deletion. 336 // We want only all pages, including those marked for deletion.
366 // TODO(bburns): actually use an index rather than linear scan. 337 // TODO(bburns): actually use an index rather than linear scan.
367 for (const auto& id_page_pair : offline_pages_) { 338 for (const auto& id_page_pair : offline_pages_) {
368 if (id_page_pair.second.client_id == client_id) 339 if (id_page_pair.second.client_id == client_id)
369 results.push_back(id_page_pair.second.offline_id); 340 results.push_back(id_page_pair.second.offline_id);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 if (!result || id_page_pair.second.creation_time > result->creation_time) 447 if (!result || id_page_pair.second.creation_time > result->creation_time)
477 result = &(id_page_pair.second); 448 result = &(id_page_pair.second);
478 } 449 }
479 } 450 }
480 return result; 451 return result;
481 } 452 }
482 453
483 void OfflinePageModel::CheckForExternalFileDeletion() { 454 void OfflinePageModel::CheckForExternalFileDeletion() {
484 DCHECK(is_loaded_); 455 DCHECK(is_loaded_);
485 456
486 std::vector<std::pair<int64_t, base::FilePath>> id_path_pairs; 457 archive_manager_->GetAllArchives(
487 for (const auto& id_page_pair : offline_pages_) { 458 base::Bind(&OfflinePageModel::ScanForMissingArchivePaths,
488 id_path_pairs.push_back( 459 weak_ptr_factory_.GetWeakPtr()));
489 std::make_pair(id_page_pair.first, id_page_pair.second.file_path));
490 }
491
492 std::vector<int64_t>* ids_of_pages_missing_archive_file =
493 new std::vector<int64_t>();
494 task_runner_->PostTaskAndReply(
495 FROM_HERE, base::Bind(&FindPagesMissingArchiveFile, id_path_pairs,
496 ids_of_pages_missing_archive_file),
497 base::Bind(&OfflinePageModel::OnFindPagesMissingArchiveFile,
498 weak_ptr_factory_.GetWeakPtr(),
499 base::Owned(ids_of_pages_missing_archive_file)));
500 } 460 }
501 461
502 void OfflinePageModel::RecordStorageHistograms(int64_t total_space_bytes, 462 void OfflinePageModel::RecordStorageHistograms(int64_t total_space_bytes,
503 int64_t free_space_bytes, 463 int64_t free_space_bytes,
504 bool reporting_after_delete) { 464 bool reporting_after_delete) {
505 // Total space taken by offline pages. 465 // Total space taken by offline pages.
506 int64_t total_page_size = 0; 466 int64_t total_page_size = 0;
507 for (const auto& id_page_pair : offline_pages_) { 467 for (const auto& id_page_pair : offline_pages_) {
508 total_page_size += id_page_pair.second.file_size; 468 total_page_size += id_page_pair.second.file_size;
509 } 469 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 } 621 }
662 622
663 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) { 623 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) {
664 pending_archivers_.erase(std::find( 624 pending_archivers_.erase(std::find(
665 pending_archivers_.begin(), pending_archivers_.end(), archiver)); 625 pending_archivers_.begin(), pending_archivers_.end(), archiver));
666 } 626 }
667 627
668 void OfflinePageModel::OnDeleteArchiveFilesDone( 628 void OfflinePageModel::OnDeleteArchiveFilesDone(
669 const std::vector<int64_t>& offline_ids, 629 const std::vector<int64_t>& offline_ids,
670 const DeletePageCallback& callback, 630 const DeletePageCallback& callback,
671 const bool* success) { 631 bool success) {
672 DCHECK(success); 632 if (!success) {
673
674 if (!*success) {
675 InformDeletePageDone(callback, DeletePageResult::DEVICE_FAILURE); 633 InformDeletePageDone(callback, DeletePageResult::DEVICE_FAILURE);
676 return; 634 return;
677 } 635 }
678 636
679 store_->RemoveOfflinePages( 637 store_->RemoveOfflinePages(
680 offline_ids, 638 offline_ids,
681 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone, 639 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone,
682 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback)); 640 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback));
683 } 641 }
684 642
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 void OfflinePageModel::InformDeletePageDone(const DeletePageCallback& callback, 695 void OfflinePageModel::InformDeletePageDone(const DeletePageCallback& callback,
738 DeletePageResult result) { 696 DeletePageResult result) {
739 UMA_HISTOGRAM_ENUMERATION( 697 UMA_HISTOGRAM_ENUMERATION(
740 "OfflinePages.DeletePageResult", 698 "OfflinePages.DeletePageResult",
741 static_cast<int>(result), 699 static_cast<int>(result),
742 static_cast<int>(DeletePageResult::RESULT_COUNT)); 700 static_cast<int>(DeletePageResult::RESULT_COUNT));
743 if (!callback.is_null()) 701 if (!callback.is_null())
744 callback.Run(result); 702 callback.Run(result);
745 } 703 }
746 704
747 void OfflinePageModel::OnFindPagesMissingArchiveFile( 705 void OfflinePageModel::ScanForMissingArchivePaths(
jianli 2016/05/17 21:48:13 nit: ScanForMissingArchiveFiles
fgorski 2016/05/17 22:50:29 Done.
748 const std::vector<int64_t>* ids_of_pages_missing_archive_file) { 706 const std::set<base::FilePath>& archive_paths) {
749 DCHECK(ids_of_pages_missing_archive_file); 707 std::vector<int64_t> ids_of_pages_missing_archive_file;
750 if (ids_of_pages_missing_archive_file->empty())
751 return;
752
753 std::vector<std::pair<int64_t, ClientId>> offline_client_id_pairs; 708 std::vector<std::pair<int64_t, ClientId>> offline_client_id_pairs;
754 for (auto offline_id : *ids_of_pages_missing_archive_file) { 709 for (const auto& id_page_pair : offline_pages_) {
755 // Since we might have deleted pages in between so we have to purge 710 if (archive_paths.count(id_page_pair.second.file_path) == 0UL) {
756 // the list to make sure we still care about them. 711 ids_of_pages_missing_archive_file.push_back(id_page_pair.first);
757 auto iter = offline_pages_.find(offline_id);
758 if (iter != offline_pages_.end()) {
759 offline_client_id_pairs.push_back( 712 offline_client_id_pairs.push_back(
760 std::make_pair(offline_id, iter->second.client_id)); 713 std::make_pair(id_page_pair.first, id_page_pair.second.client_id));
761 } 714 }
762 } 715 }
763 716
764 DeletePageCallback done_callback( 717 // No offline pages missing archive files, we can bail out.
718 if (ids_of_pages_missing_archive_file.empty())
719 return;
720
721 DeletePageCallback remove_pages_done_callback(
765 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone, 722 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone,
766 weak_ptr_factory_.GetWeakPtr(), offline_client_id_pairs)); 723 weak_ptr_factory_.GetWeakPtr(), offline_client_id_pairs));
767 724
768 store_->RemoveOfflinePages( 725 store_->RemoveOfflinePages(
769 *ids_of_pages_missing_archive_file, 726 ids_of_pages_missing_archive_file,
770 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone, 727 base::Bind(&OfflinePageModel::OnRemoveOfflinePagesDone,
771 weak_ptr_factory_.GetWeakPtr(), 728 weak_ptr_factory_.GetWeakPtr(),
772 *ids_of_pages_missing_archive_file, 729 ids_of_pages_missing_archive_file,
773 done_callback)); 730 remove_pages_done_callback));
774 } 731 }
775 732
776 void OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone( 733 void OfflinePageModel::OnRemoveOfflinePagesMissingArchiveFileDone(
777 const std::vector<std::pair<int64_t, ClientId>>& offline_client_id_pairs, 734 const std::vector<std::pair<int64_t, ClientId>>& offline_client_id_pairs,
778 DeletePageResult /* result */) { 735 DeletePageResult /* result */) {
779 for (const auto& id_pair : offline_client_id_pairs) { 736 for (const auto& id_pair : offline_client_id_pairs) {
780 FOR_EACH_OBSERVER(Observer, observers_, 737 FOR_EACH_OBSERVER(Observer, observers_,
781 OfflinePageDeleted(id_pair.first, id_pair.second)); 738 OfflinePageDeleted(id_pair.first, id_pair.second));
782 } 739 }
783 } 740 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 void OfflinePageModel::RunWhenLoaded(const base::Closure& task) { 791 void OfflinePageModel::RunWhenLoaded(const base::Closure& task) {
835 if (!is_loaded_) { 792 if (!is_loaded_) {
836 delayed_tasks_.push_back(task); 793 delayed_tasks_.push_back(task);
837 return; 794 return;
838 } 795 }
839 796
840 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); 797 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
841 } 798 }
842 799
843 } // namespace offline_pages 800 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698