Roll src/third_party/skia 99c7c07:4af6580
[chromium-blink-merge.git] / components / update_client / action_update.cc
blob7aefb43d1e90b6b4ac3bb7ca7ee0b9f3edc51dda
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/update_client/action_update.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "base/time/time.h"
17 #include "base/version.h"
18 #include "components/update_client/configurator.h"
19 #include "components/update_client/crx_downloader.h"
20 #include "components/update_client/update_client.h"
21 #include "components/update_client/utils.h"
23 using std::string;
24 using std::vector;
26 namespace update_client {
28 namespace {
30 void AppendDownloadMetrics(
31 const std::vector<CrxDownloader::DownloadMetrics>& source,
32 std::vector<CrxDownloader::DownloadMetrics>* destination) {
33 destination->insert(destination->end(), source.begin(), source.end());
36 Action::ErrorCategory UnpackerErrorToErrorCategory(
37 ComponentUnpacker::Error error) {
38 Action::ErrorCategory error_category = Action::ErrorCategory::kErrorNone;
39 switch (error) {
40 case ComponentUnpacker::kNone:
41 break;
42 case ComponentUnpacker::kInstallerError:
43 error_category = Action::ErrorCategory::kInstallError;
44 break;
45 default:
46 error_category = Action::ErrorCategory::kUnpackError;
47 break;
49 return error_category;
52 } // namespace
54 ActionUpdate::ActionUpdate() {
57 ActionUpdate::~ActionUpdate() {
58 DCHECK(thread_checker_.CalledOnValidThread());
61 void ActionUpdate::Run(UpdateContext* update_context, Callback callback) {
62 DCHECK(thread_checker_.CalledOnValidThread());
63 ActionImpl::Run(update_context, callback);
65 DCHECK(!update_context_->queue.empty());
67 const std::string& id = update_context_->queue.front();
68 CrxUpdateItem* item = FindUpdateItemById(id);
69 DCHECK(item);
71 const bool is_background_download(IsBackgroundDownload(item));
73 scoped_ptr<CrxDownloader> crx_downloader(
74 (*update_context_->crx_downloader_factory)(
75 is_background_download, update_context_->config->RequestContext(),
76 update_context_->blocking_task_runner,
77 update_context_->single_thread_task_runner));
78 crx_downloader->set_progress_callback(
79 base::Bind(&ActionUpdate::DownloadProgress, base::Unretained(this), id));
80 update_context_->crx_downloader.reset(crx_downloader.release());
82 const std::vector<GURL> urls(GetUrls(item));
83 OnDownloadStart(item);
85 update_context_->crx_downloader->StartDownload(
86 urls,
87 base::Bind(&ActionUpdate::DownloadComplete, base::Unretained(this), id));
90 void ActionUpdate::DownloadProgress(
91 const std::string& crx_id,
92 const CrxDownloader::Result& download_result) {
93 DCHECK(thread_checker_.CalledOnValidThread());
94 DCHECK(crx_id == update_context_->queue.front());
96 using Events = UpdateClient::Observer::Events;
97 NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING, crx_id);
100 void ActionUpdate::DownloadComplete(
101 const std::string& crx_id,
102 const CrxDownloader::Result& download_result) {
103 DCHECK(thread_checker_.CalledOnValidThread());
104 DCHECK(crx_id == update_context_->queue.front());
106 CrxUpdateItem* item = FindUpdateItemById(crx_id);
107 DCHECK(item);
109 AppendDownloadMetrics(update_context_->crx_downloader->download_metrics(),
110 &item->download_metrics);
112 if (download_result.error) {
113 OnDownloadError(item, download_result);
114 } else {
115 OnDownloadSuccess(item, download_result);
116 update_context_->main_task_runner->PostDelayedTask(
117 FROM_HERE, base::Bind(&ActionUpdate::Install, base::Unretained(this),
118 crx_id, download_result.response),
119 base::TimeDelta::FromMilliseconds(
120 update_context_->config->StepDelay()));
123 update_context_->crx_downloader.reset();
126 void ActionUpdate::Install(const std::string& crx_id,
127 const base::FilePath& crx_path) {
128 DCHECK(thread_checker_.CalledOnValidThread());
129 DCHECK(crx_id == update_context_->queue.front());
131 CrxUpdateItem* item = FindUpdateItemById(crx_id);
132 DCHECK(item);
134 OnInstallStart(item);
136 update_context_->blocking_task_runner->PostTask(
137 FROM_HERE,
138 base::Bind(&ActionUpdate::DoInstallOnBlockingTaskRunner,
139 base::Unretained(this), update_context_, item, crx_path));
142 void ActionUpdate::DoInstallOnBlockingTaskRunner(
143 UpdateContext* update_context,
144 CrxUpdateItem* item,
145 const base::FilePath& crx_path) {
146 update_context->unpacker = new ComponentUnpacker(
147 item->component.pk_hash, crx_path, item->component.fingerprint,
148 item->component.installer,
149 update_context->config->CreateOutOfProcessPatcher(),
150 update_context->blocking_task_runner);
151 update_context->unpacker->Unpack(
152 base::Bind(&ActionUpdate::EndUnpackingOnBlockingTaskRunner,
153 base::Unretained(this), update_context, item, crx_path));
156 void ActionUpdate::EndUnpackingOnBlockingTaskRunner(
157 UpdateContext* update_context,
158 CrxUpdateItem* item,
159 const base::FilePath& crx_path,
160 ComponentUnpacker::Error error,
161 int extended_error) {
162 update_context->unpacker = nullptr;
163 update_client::DeleteFileAndEmptyParentDirectory(crx_path);
164 update_context->main_task_runner->PostDelayedTask(
165 FROM_HERE,
166 base::Bind(&ActionUpdate::DoneInstalling, base::Unretained(this),
167 item->id, error, extended_error),
168 base::TimeDelta::FromMilliseconds(update_context->config->StepDelay()));
171 void ActionUpdate::DoneInstalling(const std::string& crx_id,
172 ComponentUnpacker::Error error,
173 int extended_error) {
174 DCHECK(thread_checker_.CalledOnValidThread());
175 DCHECK(crx_id == update_context_->queue.front());
177 CrxUpdateItem* item = FindUpdateItemById(crx_id);
178 DCHECK(item);
180 if (error == ComponentUnpacker::kNone)
181 OnInstallSuccess(item);
182 else
183 OnInstallError(item, error, extended_error);
186 ActionUpdateDiff::ActionUpdateDiff() {
189 ActionUpdateDiff::~ActionUpdateDiff() {
190 DCHECK(thread_checker_.CalledOnValidThread());
193 scoped_ptr<Action> ActionUpdateDiff::Create() {
194 return scoped_ptr<Action>(new ActionUpdateDiff);
197 void ActionUpdateDiff::TryUpdateFull() {
198 DCHECK(thread_checker_.CalledOnValidThread());
199 scoped_ptr<Action> update_action(ActionUpdateFull::Create());
201 base::ThreadTaskRunnerHandle::Get()->PostTask(
202 FROM_HERE, base::Bind(&Action::Run, base::Unretained(update_action.get()),
203 update_context_, callback_));
205 update_context_->current_action.reset(update_action.release());
208 bool ActionUpdateDiff::IsBackgroundDownload(const CrxUpdateItem* item) {
209 DCHECK(thread_checker_.CalledOnValidThread());
210 return false;
213 std::vector<GURL> ActionUpdateDiff::GetUrls(const CrxUpdateItem* item) {
214 DCHECK(thread_checker_.CalledOnValidThread());
215 return item->crx_diffurls;
218 void ActionUpdateDiff::OnDownloadStart(CrxUpdateItem* item) {
219 DCHECK(thread_checker_.CalledOnValidThread());
220 DCHECK(item->state == CrxUpdateItem::State::kCanUpdate);
222 ChangeItemState(item, CrxUpdateItem::State::kDownloadingDiff);
225 void ActionUpdateDiff::OnDownloadSuccess(
226 CrxUpdateItem* item,
227 const CrxDownloader::Result& download_result) {
228 DCHECK(thread_checker_.CalledOnValidThread());
229 DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
231 ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
234 void ActionUpdateDiff::OnDownloadError(
235 CrxUpdateItem* item,
236 const CrxDownloader::Result& download_result) {
237 DCHECK(thread_checker_.CalledOnValidThread());
238 DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
240 item->diff_error_category = static_cast<int>(ErrorCategory::kNetworkError);
241 item->diff_error_code = download_result.error;
242 item->diff_update_failed = true;
244 base::ThreadTaskRunnerHandle::Get()->PostTask(
245 FROM_HERE,
246 base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
249 void ActionUpdateDiff::OnInstallStart(CrxUpdateItem* item) {
250 DCHECK(thread_checker_.CalledOnValidThread());
252 ChangeItemState(item, CrxUpdateItem::State::kUpdatingDiff);
255 void ActionUpdateDiff::OnInstallSuccess(CrxUpdateItem* item) {
256 DCHECK(thread_checker_.CalledOnValidThread());
257 DCHECK(item->state == CrxUpdateItem::State::kUpdatingDiff);
259 item->component.version = item->next_version;
260 item->component.fingerprint = item->next_fp;
261 ChangeItemState(item, CrxUpdateItem::State::kUpdated);
263 UpdateCrxComplete(item);
266 void ActionUpdateDiff::OnInstallError(CrxUpdateItem* item,
267 ComponentUnpacker::Error error,
268 int extended_error) {
269 DCHECK(thread_checker_.CalledOnValidThread());
271 item->diff_error_category =
272 static_cast<int>(UnpackerErrorToErrorCategory(error));
273 item->diff_error_code = error;
274 item->diff_extra_code1 = extended_error;
275 item->diff_update_failed = true;
277 base::ThreadTaskRunnerHandle::Get()->PostTask(
278 FROM_HERE,
279 base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
282 ActionUpdateFull::ActionUpdateFull() {
285 ActionUpdateFull::~ActionUpdateFull() {
286 DCHECK(thread_checker_.CalledOnValidThread());
289 scoped_ptr<Action> ActionUpdateFull::Create() {
290 return scoped_ptr<Action>(new ActionUpdateFull);
293 bool ActionUpdateFull::IsBackgroundDownload(const CrxUpdateItem* item) {
294 DCHECK(thread_checker_.CalledOnValidThread());
296 // On demand component updates are always downloaded in foreground.
297 return !item->on_demand && item->component.allow_background_download &&
298 update_context_->config->UseBackgroundDownloader();
301 std::vector<GURL> ActionUpdateFull::GetUrls(const CrxUpdateItem* item) {
302 DCHECK(thread_checker_.CalledOnValidThread());
303 return item->crx_urls;
306 void ActionUpdateFull::OnDownloadStart(CrxUpdateItem* item) {
307 DCHECK(thread_checker_.CalledOnValidThread());
308 DCHECK(item->state == CrxUpdateItem::State::kCanUpdate ||
309 item->diff_update_failed);
311 ChangeItemState(item, CrxUpdateItem::State::kDownloading);
314 void ActionUpdateFull::OnDownloadSuccess(
315 CrxUpdateItem* item,
316 const CrxDownloader::Result& download_result) {
317 DCHECK(thread_checker_.CalledOnValidThread());
318 DCHECK(item->state == CrxUpdateItem::State::kDownloading);
320 ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
323 void ActionUpdateFull::OnDownloadError(
324 CrxUpdateItem* item,
325 const CrxDownloader::Result& download_result) {
326 DCHECK(thread_checker_.CalledOnValidThread());
327 DCHECK(item->state == CrxUpdateItem::State::kDownloading);
329 item->error_category = static_cast<int>(ErrorCategory::kNetworkError);
330 item->error_code = download_result.error;
331 ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
333 UpdateCrxComplete(item);
336 void ActionUpdateFull::OnInstallStart(CrxUpdateItem* item) {
337 DCHECK(thread_checker_.CalledOnValidThread());
338 DCHECK(item->state == CrxUpdateItem::State::kDownloaded);
340 ChangeItemState(item, CrxUpdateItem::State::kUpdating);
343 void ActionUpdateFull::OnInstallSuccess(CrxUpdateItem* item) {
344 DCHECK(thread_checker_.CalledOnValidThread());
345 DCHECK(item->state == CrxUpdateItem::State::kUpdating);
347 item->component.version = item->next_version;
348 item->component.fingerprint = item->next_fp;
349 ChangeItemState(item, CrxUpdateItem::State::kUpdated);
351 UpdateCrxComplete(item);
354 void ActionUpdateFull::OnInstallError(CrxUpdateItem* item,
355 ComponentUnpacker::Error error,
356 int extended_error) {
357 DCHECK(thread_checker_.CalledOnValidThread());
358 DCHECK(item->state == CrxUpdateItem::State::kUpdating);
360 item->error_category = static_cast<int>(UnpackerErrorToErrorCategory(error));
361 item->error_code = error;
362 item->extra_code1 = extended_error;
363 ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
365 UpdateCrxComplete(item);
368 } // namespace update_client