Update V8 to version 4.6.68.
[chromium-blink-merge.git] / components / offline_pages / offline_page_model.cc
blob0460b6be61a9a2daef0c9fc88337a2ee9d03f01f
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 is_loaded_(false),
57 task_runner_(task_runner),
58 weak_ptr_factory_(this) {
59 store_->Load(base::Bind(&OfflinePageModel::OnLoadDone,
60 weak_ptr_factory_.GetWeakPtr()));
63 OfflinePageModel::~OfflinePageModel() {
66 void OfflinePageModel::Shutdown() {
69 void OfflinePageModel::AddObserver(Observer* observer) {
70 observers_.AddObserver(observer);
73 void OfflinePageModel::RemoveObserver(Observer* observer) {
74 observers_.RemoveObserver(observer);
77 void OfflinePageModel::SavePage(const GURL& url,
78 int64 bookmark_id,
79 scoped_ptr<OfflinePageArchiver> archiver,
80 const SavePageCallback& callback) {
81 DCHECK(is_loaded_);
82 DCHECK(archiver.get());
83 archiver->CreateArchive(base::Bind(&OfflinePageModel::OnCreateArchiveDone,
84 weak_ptr_factory_.GetWeakPtr(), url,
85 bookmark_id, callback));
86 pending_archivers_.push_back(archiver.Pass());
89 void OfflinePageModel::DeletePage(const GURL& url,
90 const DeletePageCallback& callback) {
91 DCHECK(is_loaded_);
93 for (const auto& page : offline_pages_) {
94 if (page.url == url) {
95 bool* success = new bool(false);
96 task_runner_->PostTaskAndReply(
97 FROM_HERE,
98 base::Bind(&OfflinePageModel::DeleteArchiverFile,
99 weak_ptr_factory_.GetWeakPtr(),
100 page.file_path,
101 success),
102 base::Bind(&OfflinePageModel::OnDeleteArchiverFileDone,
103 weak_ptr_factory_.GetWeakPtr(),
104 url,
105 callback,
106 base::Owned(success)));
107 return;
111 callback.Run(DeletePageResult::NOT_FOUND);
114 const std::vector<OfflinePageItem>& OfflinePageModel::GetAllPages() const {
115 DCHECK(is_loaded_);
116 return offline_pages_;
119 OfflinePageMetadataStore* OfflinePageModel::GetStoreForTesting() {
120 return store_.get();
123 void OfflinePageModel::OnCreateArchiveDone(const GURL& requested_url,
124 int64 bookmark_id,
125 const SavePageCallback& callback,
126 OfflinePageArchiver* archiver,
127 ArchiverResult archiver_result,
128 const GURL& url,
129 const base::FilePath& file_path,
130 int64 file_size) {
131 if (requested_url != url) {
132 DVLOG(1) << "Saved URL does not match requested URL.";
133 // TODO(fgorski): We have created an archive for a wrong URL. It should be
134 // deleted from here, once archiver has the right functionality.
135 InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED);
136 DeletePendingArchiver(archiver);
137 return;
140 if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) {
141 SavePageResult result = ToSavePageResult(archiver_result);
142 InformSavePageDone(callback, result);
143 DeletePendingArchiver(archiver);
144 return;
147 OfflinePageItem offline_page_item(url, bookmark_id, file_path, file_size,
148 base::Time::Now());
149 store_->AddOfflinePage(
150 offline_page_item,
151 base::Bind(&OfflinePageModel::OnAddOfflinePageDone,
152 weak_ptr_factory_.GetWeakPtr(), archiver, callback,
153 offline_page_item));
156 void OfflinePageModel::OnAddOfflinePageDone(OfflinePageArchiver* archiver,
157 const SavePageCallback& callback,
158 const OfflinePageItem& offline_page,
159 bool success) {
160 SavePageResult result;
161 if (success) {
162 offline_pages_.push_back(offline_page);
163 result = SavePageResult::SUCCESS;
164 } else {
165 result = SavePageResult::STORE_FAILURE;
167 InformSavePageDone(callback, result);
168 DeletePendingArchiver(archiver);
171 void OfflinePageModel::OnLoadDone(
172 bool success,
173 const std::vector<OfflinePageItem>& offline_pages) {
174 DCHECK(!is_loaded_);
175 is_loaded_ = true;
177 // TODO(fgorski): Report the UMA upon failure. Cache should probably start
178 // empty. See if we can do something about it.
179 if (success)
180 offline_pages_ = offline_pages;
182 FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelLoaded(this));
185 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback,
186 SavePageResult result) {
187 callback.Run(result);
190 void OfflinePageModel::DeletePendingArchiver(OfflinePageArchiver* archiver) {
191 pending_archivers_.erase(std::find(
192 pending_archivers_.begin(), pending_archivers_.end(), archiver));
195 void OfflinePageModel::DeleteArchiverFile(const base::FilePath& file_path,
196 bool* success) {
197 DCHECK(success);
198 DCHECK(task_runner_->RunsTasksOnCurrentThread());
200 *success = base::DeleteFile(file_path, false);
203 void OfflinePageModel::OnDeleteArchiverFileDone(
204 const GURL& url,
205 const DeletePageCallback& callback,
206 const bool* success) {
207 DCHECK(success);
209 if (!*success) {
210 callback.Run(DeletePageResult::DEVICE_FAILURE);
211 return;
214 store_->RemoveOfflinePage(
215 url,
216 base::Bind(&OfflinePageModel::OnRemoveOfflinePageDone,
217 weak_ptr_factory_.GetWeakPtr(), url, callback));
220 void OfflinePageModel::OnRemoveOfflinePageDone(
221 const GURL& url,
222 const DeletePageCallback& callback,
223 bool success) {
224 // Delete the offline page from the in memory cache regardless of success in
225 // store.
226 for (auto iter = offline_pages_.begin();
227 iter != offline_pages_.end();
228 ++iter) {
229 if (iter->url == url) {
230 offline_pages_.erase(iter);
231 break;
235 callback.Run(
236 success ? DeletePageResult::SUCCESS : DeletePageResult::STORE_FAILURE);
239 } // namespace offline_pages