Stack sampling profiler: add fire-and-forget interface
[chromium-blink-merge.git] / components / offline_pages / offline_page_model.cc
blob09633fba864e242b8e89af110278bf929d0a284a
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
3 // found in the LICENSE file.
5 #include "components/offline_pages/offline_page_model.h"
7 #include <algorithm>
9 #include "base/bind.h"
10 #include "base/files/file_util.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/sequenced_task_runner.h"
14 #include "components/offline_pages/offline_page_item.h"
15 #include "components/offline_pages/offline_page_metadata_store.h"
16 #include "url/gurl.h"
18 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult;
19 using SavePageResult = offline_pages::OfflinePageModel::SavePageResult;
21 namespace offline_pages {
23 namespace {
25 SavePageResult ToSavePageResult(ArchiverResult archiver_result) {
26 SavePageResult result;
27 switch (archiver_result) {
28 case ArchiverResult::SUCCESSFULLY_CREATED:
29 result = SavePageResult::SUCCESS;
30 break;
31 case ArchiverResult::ERROR_DEVICE_FULL:
32 result = SavePageResult::DEVICE_FULL;
33 break;
34 case ArchiverResult::ERROR_CONTENT_UNAVAILABLE:
35 result = SavePageResult::CONTENT_UNAVAILABLE;
36 break;
37 case ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED:
38 result = SavePageResult::ARCHIVE_CREATION_FAILED;
39 break;
40 case ArchiverResult::ERROR_CANCELED:
41 result = SavePageResult::CANCELLED;
42 break;
43 default:
44 NOTREACHED();
45 result = SavePageResult::CONTENT_UNAVAILABLE;
47 return result;
50 } // namespace
52 OfflinePageModel::OfflinePageModel(
53 scoped_ptr<OfflinePageMetadataStore> store,
54 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
55 : store_(store.Pass()),
56 task_runner_(task_runner),
57 weak_ptr_factory_(this) {
60 OfflinePageModel::~OfflinePageModel() {
63 void OfflinePageModel::Shutdown() {
66 void OfflinePageModel::SavePage(
67 const GURL& url,
68 scoped_ptr<OfflinePageArchiver> archiver,
69 const SavePageCallback& callback) {
70 DCHECK(archiver.get());
71 archiver->CreateArchive(base::Bind(&OfflinePageModel::OnCreateArchiveDone,
72 weak_ptr_factory_.GetWeakPtr(), url,
73 callback));
74 pending_archivers_.push_back(archiver.Pass());
77 void OfflinePageModel::DeletePage(const GURL& url,
78 const DeletePageCallback& callback) {
79 // First we have to load all entries in order to find out the file path
80 // for the page to be deleted.
81 store_->Load(base::Bind(&OfflinePageModel::OnLoadDoneForDeletion,
82 weak_ptr_factory_.GetWeakPtr(), url, callback));
85 void OfflinePageModel::LoadAllPages(const LoadAllPagesCallback& callback) {
86 store_->Load(base::Bind(&OfflinePageModel::OnLoadDone,
87 weak_ptr_factory_.GetWeakPtr(), callback));
90 OfflinePageMetadataStore* OfflinePageModel::GetStoreForTesting() {
91 return store_.get();
94 void OfflinePageModel::OnCreateArchiveDone(
95 const GURL& requested_url,
96 const SavePageCallback& callback,
97 OfflinePageArchiver* archiver,
98 ArchiverResult archiver_result,
99 const GURL& url,
100 const base::string16& title,
101 const base::FilePath& file_path,
102 int64 file_size) {
103 if (requested_url != url) {
104 DVLOG(1) << "Saved URL does not match requested URL.";
105 // TODO(fgorski): We have created an archive for a wrong URL. It should be
106 // deleted from here, once archiver has the right functionality.
107 InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED);
108 DeletePendingArchiver(archiver);
109 return;
112 if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) {
113 SavePageResult result = ToSavePageResult(archiver_result);
114 InformSavePageDone(callback, result);
115 DeletePendingArchiver(archiver);
116 return;
119 OfflinePageItem offline_page_item(url, title, file_path, file_size,
120 base::Time::Now());
121 store_->AddOfflinePage(
122 offline_page_item,
123 base::Bind(&OfflinePageModel::OnAddOfflinePageDone,
124 weak_ptr_factory_.GetWeakPtr(), archiver, callback));
127 void OfflinePageModel::OnAddOfflinePageDone(OfflinePageArchiver* archiver,
128 const SavePageCallback& callback,
129 bool success) {
130 SavePageResult result =
131 success ? SavePageResult::SUCCESS : SavePageResult::STORE_FAILURE;
132 InformSavePageDone(callback, result);
133 DeletePendingArchiver(archiver);
136 void OfflinePageModel::OnLoadDone(
137 const LoadAllPagesCallback& callback,
138 bool success,
139 const std::vector<OfflinePageItem>& offline_pages) {
140 // TODO(fgorski): Cache the values here, if we are comfortable with that
141 // model. This will require extra handling of parallel loads.
142 LoadResult result =
143 success ? LoadResult::SUCCESS : LoadResult::STORE_FAILURE;
144 callback.Run(result, offline_pages);
147 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback,
148 SavePageResult result) {
149 callback.Run(result);
152 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) {
153 pending_archivers_.erase(std::find(
154 pending_archivers_.begin(), pending_archivers_.end(), archiver));
157 void OfflinePageModel::OnLoadDoneForDeletion(
158 const GURL& url,
159 const DeletePageCallback& callback,
160 bool success,
161 const std::vector<OfflinePageItem>& offline_pages) {
162 if (!success) {
163 callback.Run(DeletePageResult::STORE_FAILURE);
164 return;
167 for (const auto& page : offline_pages) {
168 if (page.url == url) {
169 bool* success = new bool(false);
170 task_runner_->PostTaskAndReply(
171 FROM_HERE,
172 base::Bind(&OfflinePageModel::DeleteArchiverFile,
173 weak_ptr_factory_.GetWeakPtr(),
174 page.file_path,
175 success),
176 base::Bind(&OfflinePageModel::OnDeleteArchiverFileDone,
177 weak_ptr_factory_.GetWeakPtr(),
178 url,
179 callback,
180 base::Owned(success)));
181 return;
185 callback.Run(DeletePageResult::NOT_FOUND);
188 void OfflinePageModel::DeleteArchiverFile(const base::FilePath& file_path,
189 bool* success) {
190 DCHECK(success);
191 DCHECK(task_runner_->RunsTasksOnCurrentThread());
193 *success = base::DeleteFile(file_path, false);
196 void OfflinePageModel::OnDeleteArchiverFileDone(
197 const GURL& url,
198 const DeletePageCallback& callback,
199 const bool* success) {
200 DCHECK(success);
202 if (!*success) {
203 callback.Run(DeletePageResult::DEVICE_FAILURE);
204 return;
207 store_->RemoveOfflinePage(
208 url,
209 base::Bind(&OfflinePageModel::OnRemoveOfflinePageDone,
210 weak_ptr_factory_.GetWeakPtr(), callback));
213 void OfflinePageModel::OnRemoveOfflinePageDone(
214 const DeletePageCallback& callback, bool success) {
215 callback.Run(
216 success ? DeletePageResult::SUCCESS : DeletePageResult::STORE_FAILURE);
219 } // namespace offline_pages