ExtensionInstallDialogView: fix scrolling behavior on Views (Win,Linux)
[chromium-blink-merge.git] / components / update_client / action_update.cc
blobac565e78b50e2cece73090c7ac2ab2c2e7468282
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/utils.h"
21 using std::string;
22 using std::vector;
24 namespace update_client {
26 namespace {
28 void AppendDownloadMetrics(
29 const std::vector<CrxDownloader::DownloadMetrics>& source,
30 std::vector<CrxDownloader::DownloadMetrics>* destination) {
31 destination->insert(destination->end(), source.begin(), source.end());
34 Action::ErrorCategory UnpackerErrorToErrorCategory(
35 ComponentUnpacker::Error error) {
36 Action::ErrorCategory error_category = Action::ErrorCategory::kErrorNone;
37 switch (error) {
38 case ComponentUnpacker::kNone:
39 break;
40 case ComponentUnpacker::kInstallerError:
41 error_category = Action::ErrorCategory::kInstallError;
42 break;
43 default:
44 error_category = Action::ErrorCategory::kUnpackError;
45 break;
47 return error_category;
50 } // namespace
52 ActionUpdate::ActionUpdate() {
55 ActionUpdate::~ActionUpdate() {
56 DCHECK(thread_checker_.CalledOnValidThread());
59 void ActionUpdate::Run(UpdateContext* update_context, Callback callback) {
60 DCHECK(thread_checker_.CalledOnValidThread());
61 ActionImpl::Run(update_context, callback);
63 DCHECK(!update_context_->queue.empty());
65 const std::string& id = update_context_->queue.front();
66 CrxUpdateItem* item = FindUpdateItemById(id);
67 DCHECK(item);
69 const bool is_background_download(IsBackgroundDownload(item));
71 crx_downloader_.reset(
72 (*update_context_->crx_downloader_factory)(
73 is_background_download, update_context_->config->RequestContext(),
74 update_context_->blocking_task_runner,
75 update_context_->single_thread_task_runner).release());
76 crx_downloader_->set_progress_callback(
77 base::Bind(&ActionUpdate::DownloadProgress, base::Unretained(this), id));
79 OnDownloadStart(item);
81 crx_downloader_->StartDownload(
82 GetUrls(item),
83 base::Bind(&ActionUpdate::DownloadComplete, base::Unretained(this), id));
86 void ActionUpdate::DownloadProgress(
87 const std::string& id,
88 const CrxDownloader::Result& download_result) {
89 DCHECK(thread_checker_.CalledOnValidThread());
90 DCHECK(id == update_context_->queue.front());
92 using Events = UpdateClient::Observer::Events;
93 NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING, id);
96 void ActionUpdate::DownloadComplete(
97 const std::string& id,
98 const CrxDownloader::Result& download_result) {
99 DCHECK(thread_checker_.CalledOnValidThread());
100 DCHECK(id == update_context_->queue.front());
102 CrxUpdateItem* item = FindUpdateItemById(id);
103 DCHECK(item);
105 AppendDownloadMetrics(crx_downloader_->download_metrics(),
106 &item->download_metrics);
108 crx_downloader_.reset();
110 if (download_result.error) {
111 OnDownloadError(item, download_result);
112 } else {
113 OnDownloadSuccess(item, download_result);
114 update_context_->main_task_runner->PostDelayedTask(
115 FROM_HERE, base::Bind(&ActionUpdate::Install, base::Unretained(this),
116 id, download_result.response),
117 base::TimeDelta::FromMilliseconds(
118 update_context_->config->StepDelay()));
122 void ActionUpdate::Install(const std::string& id,
123 const base::FilePath& crx_path) {
124 DCHECK(thread_checker_.CalledOnValidThread());
125 DCHECK(id == update_context_->queue.front());
127 CrxUpdateItem* item = FindUpdateItemById(id);
128 DCHECK(item);
130 OnInstallStart(item);
132 update_context_->blocking_task_runner->PostTask(
133 FROM_HERE,
134 base::Bind(&ActionUpdate::DoInstallOnBlockingTaskRunner,
135 base::Unretained(this), update_context_, item, crx_path));
138 void ActionUpdate::DoInstallOnBlockingTaskRunner(
139 UpdateContext* update_context,
140 CrxUpdateItem* item,
141 const base::FilePath& crx_path) {
142 unpacker_ = new ComponentUnpacker(
143 item->component.pk_hash, crx_path, item->component.fingerprint,
144 item->component.installer,
145 update_context->config->CreateOutOfProcessPatcher(),
146 update_context->blocking_task_runner);
147 unpacker_->Unpack(base::Bind(&ActionUpdate::EndUnpackingOnBlockingTaskRunner,
148 base::Unretained(this), update_context, item,
149 crx_path));
152 void ActionUpdate::EndUnpackingOnBlockingTaskRunner(
153 UpdateContext* update_context,
154 CrxUpdateItem* item,
155 const base::FilePath& crx_path,
156 ComponentUnpacker::Error error,
157 int extended_error) {
158 unpacker_ = nullptr;
159 update_client::DeleteFileAndEmptyParentDirectory(crx_path);
160 update_context->main_task_runner->PostDelayedTask(
161 FROM_HERE,
162 base::Bind(&ActionUpdate::DoneInstalling, base::Unretained(this),
163 item->id, error, extended_error),
164 base::TimeDelta::FromMilliseconds(update_context->config->StepDelay()));
167 void ActionUpdate::DoneInstalling(const std::string& id,
168 ComponentUnpacker::Error error,
169 int extended_error) {
170 DCHECK(thread_checker_.CalledOnValidThread());
171 DCHECK(id == update_context_->queue.front());
173 CrxUpdateItem* item = FindUpdateItemById(id);
174 DCHECK(item);
176 if (error == ComponentUnpacker::kNone)
177 OnInstallSuccess(item);
178 else
179 OnInstallError(item, error, extended_error);
182 ActionUpdateDiff::ActionUpdateDiff() {
185 ActionUpdateDiff::~ActionUpdateDiff() {
186 DCHECK(thread_checker_.CalledOnValidThread());
189 scoped_ptr<Action> ActionUpdateDiff::Create() {
190 return scoped_ptr<Action>(new ActionUpdateDiff);
193 void ActionUpdateDiff::TryUpdateFull() {
194 DCHECK(thread_checker_.CalledOnValidThread());
195 scoped_ptr<Action> update_action(ActionUpdateFull::Create());
197 base::ThreadTaskRunnerHandle::Get()->PostTask(
198 FROM_HERE, base::Bind(&Action::Run, base::Unretained(update_action.get()),
199 update_context_, callback_));
201 update_context_->current_action.reset(update_action.release());
204 bool ActionUpdateDiff::IsBackgroundDownload(const CrxUpdateItem* item) {
205 DCHECK(thread_checker_.CalledOnValidThread());
206 return false;
209 std::vector<GURL> ActionUpdateDiff::GetUrls(const CrxUpdateItem* item) {
210 DCHECK(thread_checker_.CalledOnValidThread());
211 return item->crx_diffurls;
214 void ActionUpdateDiff::OnDownloadStart(CrxUpdateItem* item) {
215 DCHECK(thread_checker_.CalledOnValidThread());
216 DCHECK(item->state == CrxUpdateItem::State::kCanUpdate);
218 ChangeItemState(item, CrxUpdateItem::State::kDownloadingDiff);
221 void ActionUpdateDiff::OnDownloadSuccess(
222 CrxUpdateItem* item,
223 const CrxDownloader::Result& download_result) {
224 DCHECK(thread_checker_.CalledOnValidThread());
225 DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
227 ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
230 void ActionUpdateDiff::OnDownloadError(
231 CrxUpdateItem* item,
232 const CrxDownloader::Result& download_result) {
233 DCHECK(thread_checker_.CalledOnValidThread());
234 DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
236 item->diff_error_category = static_cast<int>(ErrorCategory::kNetworkError);
237 item->diff_error_code = download_result.error;
238 item->diff_update_failed = true;
240 base::ThreadTaskRunnerHandle::Get()->PostTask(
241 FROM_HERE,
242 base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
245 void ActionUpdateDiff::OnInstallStart(CrxUpdateItem* item) {
246 DCHECK(thread_checker_.CalledOnValidThread());
248 ChangeItemState(item, CrxUpdateItem::State::kUpdatingDiff);
251 void ActionUpdateDiff::OnInstallSuccess(CrxUpdateItem* item) {
252 DCHECK(thread_checker_.CalledOnValidThread());
253 DCHECK(item->state == CrxUpdateItem::State::kUpdatingDiff);
255 item->component.version = item->next_version;
256 item->component.fingerprint = item->next_fp;
257 ChangeItemState(item, CrxUpdateItem::State::kUpdated);
259 UpdateCrxComplete(item);
262 void ActionUpdateDiff::OnInstallError(CrxUpdateItem* item,
263 ComponentUnpacker::Error error,
264 int extended_error) {
265 DCHECK(thread_checker_.CalledOnValidThread());
267 item->diff_error_category =
268 static_cast<int>(UnpackerErrorToErrorCategory(error));
269 item->diff_error_code = error;
270 item->diff_extra_code1 = extended_error;
271 item->diff_update_failed = true;
273 base::ThreadTaskRunnerHandle::Get()->PostTask(
274 FROM_HERE,
275 base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
278 ActionUpdateFull::ActionUpdateFull() {
281 ActionUpdateFull::~ActionUpdateFull() {
282 DCHECK(thread_checker_.CalledOnValidThread());
285 scoped_ptr<Action> ActionUpdateFull::Create() {
286 return scoped_ptr<Action>(new ActionUpdateFull);
289 bool ActionUpdateFull::IsBackgroundDownload(const CrxUpdateItem* item) {
290 DCHECK(thread_checker_.CalledOnValidThread());
292 // On demand component updates are always downloaded in foreground.
293 return !item->on_demand && item->component.allow_background_download &&
294 update_context_->config->UseBackgroundDownloader();
297 std::vector<GURL> ActionUpdateFull::GetUrls(const CrxUpdateItem* item) {
298 DCHECK(thread_checker_.CalledOnValidThread());
299 return item->crx_urls;
302 void ActionUpdateFull::OnDownloadStart(CrxUpdateItem* item) {
303 DCHECK(thread_checker_.CalledOnValidThread());
304 DCHECK(item->state == CrxUpdateItem::State::kCanUpdate ||
305 item->diff_update_failed);
307 ChangeItemState(item, CrxUpdateItem::State::kDownloading);
310 void ActionUpdateFull::OnDownloadSuccess(
311 CrxUpdateItem* item,
312 const CrxDownloader::Result& download_result) {
313 DCHECK(thread_checker_.CalledOnValidThread());
314 DCHECK(item->state == CrxUpdateItem::State::kDownloading);
316 ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
319 void ActionUpdateFull::OnDownloadError(
320 CrxUpdateItem* item,
321 const CrxDownloader::Result& download_result) {
322 DCHECK(thread_checker_.CalledOnValidThread());
323 DCHECK(item->state == CrxUpdateItem::State::kDownloading);
325 item->error_category = static_cast<int>(ErrorCategory::kNetworkError);
326 item->error_code = download_result.error;
327 ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
329 UpdateCrxComplete(item);
332 void ActionUpdateFull::OnInstallStart(CrxUpdateItem* item) {
333 DCHECK(thread_checker_.CalledOnValidThread());
334 DCHECK(item->state == CrxUpdateItem::State::kDownloaded);
336 ChangeItemState(item, CrxUpdateItem::State::kUpdating);
339 void ActionUpdateFull::OnInstallSuccess(CrxUpdateItem* item) {
340 DCHECK(thread_checker_.CalledOnValidThread());
341 DCHECK(item->state == CrxUpdateItem::State::kUpdating);
343 item->component.version = item->next_version;
344 item->component.fingerprint = item->next_fp;
345 ChangeItemState(item, CrxUpdateItem::State::kUpdated);
347 UpdateCrxComplete(item);
350 void ActionUpdateFull::OnInstallError(CrxUpdateItem* item,
351 ComponentUnpacker::Error error,
352 int extended_error) {
353 DCHECK(thread_checker_.CalledOnValidThread());
354 DCHECK(item->state == CrxUpdateItem::State::kUpdating);
356 item->error_category = static_cast<int>(UnpackerErrorToErrorCategory(error));
357 item->error_code = error;
358 item->extra_code1 = extended_error;
359 ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
361 UpdateCrxComplete(item);
364 } // namespace update_client