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

Side by Side Diff: components/update_client/action_update.cc

Issue 2835803002: Refactor the UpdateEngine and its actions in the component updater. (Closed)
Patch Set: feedback up to #6 Created 3 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
(Empty)
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.
4
5 #include "components/update_client/action_update.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/location.h"
15 #include "base/logging.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "base/time/time.h"
18 #include "base/values.h"
19 #include "base/version.h"
20 #include "components/update_client/component_unpacker.h"
21 #include "components/update_client/configurator.h"
22 #include "components/update_client/update_client_errors.h"
23 #include "components/update_client/utils.h"
24
25 using std::string;
26 using std::vector;
27
28 namespace update_client {
29
30 namespace {
31
32 void AppendDownloadMetrics(
33 const std::vector<CrxDownloader::DownloadMetrics>& source,
34 std::vector<CrxDownloader::DownloadMetrics>* destination) {
35 destination->insert(destination->end(), source.begin(), source.end());
36 }
37
38 } // namespace
39
40 ActionUpdate::ActionUpdate() {
41 }
42
43 ActionUpdate::~ActionUpdate() {
44 DCHECK(thread_checker_.CalledOnValidThread());
45 }
46
47 void ActionUpdate::Run(UpdateContext* update_context, Callback callback) {
48 DCHECK(thread_checker_.CalledOnValidThread());
49 ActionImpl::Run(update_context, callback);
50
51 DCHECK(!update_context_->queue.empty());
52
53 const std::string& id = update_context_->queue.front();
54 CrxUpdateItem* item = FindUpdateItemById(id);
55 DCHECK(item);
56
57 StartDownload(item);
58 }
59
60 void ActionUpdate::StartDownload(CrxUpdateItem* item) {
61 DCHECK(thread_checker_.CalledOnValidThread());
62
63 crx_downloader_.reset((*update_context_->crx_downloader_factory)(
64 IsBackgroundDownload(item),
65 update_context_->config->RequestContext(),
66 update_context_->blocking_task_runner)
67 .release());
68 OnDownloadStart(item);
69
70 const std::string id = item->id;
71 crx_downloader_->set_progress_callback(
72 base::Bind(&ActionUpdate::DownloadProgress, base::Unretained(this), id));
73 crx_downloader_->StartDownload(
74 GetUrls(item), GetHash(item),
75 base::Bind(&ActionUpdate::DownloadComplete, base::Unretained(this), id));
76 }
77
78 void ActionUpdate::DownloadProgress(
79 const std::string& id,
80 const CrxDownloader::Result& download_result) {
81 DCHECK(thread_checker_.CalledOnValidThread());
82 DCHECK(id == update_context_->queue.front());
83
84 using Events = UpdateClient::Observer::Events;
85 NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING, id);
86 }
87
88 void ActionUpdate::DownloadComplete(
89 const std::string& id,
90 const CrxDownloader::Result& download_result) {
91 DCHECK(thread_checker_.CalledOnValidThread());
92 DCHECK(id == update_context_->queue.front());
93
94 CrxUpdateItem* item = FindUpdateItemById(id);
95 DCHECK(item);
96
97 AppendDownloadMetrics(crx_downloader_->download_metrics(),
98 &item->download_metrics);
99
100 crx_downloader_.reset();
101
102 if (download_result.error) {
103 OnDownloadError(item, download_result);
104 } else {
105 OnDownloadSuccess(item, download_result);
106 update_context_->main_task_runner->PostTask(
107 FROM_HERE,
108 base::Bind(&ActionUpdate::StartInstall, base::Unretained(this), item,
109 download_result.response));
110 }
111 }
112
113 void ActionUpdate::StartInstall(CrxUpdateItem* item,
114 const base::FilePath& crx_path) {
115 DCHECK(thread_checker_.CalledOnValidThread());
116 DCHECK(item->id == update_context_->queue.front());
117
118 OnInstallStart(item);
119
120 update_context_->blocking_task_runner->PostTask(
121 FROM_HERE, base::Bind(&ActionUpdate::StartUnpackOnBlockingTaskRunner,
122 base::Unretained(this), item, crx_path));
123 }
124
125 void ActionUpdate::StartUnpackOnBlockingTaskRunner(
126 CrxUpdateItem* item,
127 const base::FilePath& crx_path) {
128 DCHECK(update_context_->blocking_task_runner->RunsTasksOnCurrentThread());
129 unpacker_ = new ComponentUnpacker(
130 item->component.pk_hash, crx_path,
131 item->component.installer,
132 update_context_->config->CreateOutOfProcessPatcher(),
133 update_context_->blocking_task_runner);
134 unpacker_->Unpack(
135 base::Bind(&ActionUpdate::UnpackCompleteOnBlockingTaskRunner,
136 base::Unretained(this), item, crx_path));
137 }
138
139 void ActionUpdate::UnpackCompleteOnBlockingTaskRunner(
140 CrxUpdateItem* item,
141 const base::FilePath& crx_path,
142 const ComponentUnpacker::Result& result) {
143 DCHECK(update_context_->blocking_task_runner->RunsTasksOnCurrentThread());
144 unpacker_ = nullptr;
145
146 if (result.error == UnpackerError::kNone) {
147 update_context_->blocking_task_runner->PostTask(
148 FROM_HERE,
149 base::Bind(&ActionUpdate::StartInstallOnBlockingTaskRunner,
150 base::Unretained(this), item, crx_path, result.unpack_path));
151 } else {
152 update_context_->blocking_task_runner->PostTask(
153 FROM_HERE,
154 base::Bind(&ActionUpdate::InstallCompleteOnBlockingTaskRunner,
155 base::Unretained(this), item, crx_path,
156 ErrorCategory::kUnpackError, static_cast<int>(result.error),
157 result.extended_error));
158 }
159 }
160
161 void ActionUpdate::StartInstallOnBlockingTaskRunner(
162 CrxUpdateItem* item,
163 const base::FilePath& crx_path,
164 const base::FilePath& unpack_path) {
165 DCHECK(update_context_->blocking_task_runner->RunsTasksOnCurrentThread());
166 DCHECK(!unpack_path.empty());
167
168 const auto result = DoInstall(item, crx_path, unpack_path);
169 const ErrorCategory error_category =
170 result.error ? ErrorCategory::kInstallError : ErrorCategory::kErrorNone;
171 update_context_->blocking_task_runner->PostTask(
172 FROM_HERE,
173 base::Bind(&ActionUpdate::InstallCompleteOnBlockingTaskRunner,
174 base::Unretained(this), item, crx_path, error_category,
175 result.error, result.extended_error));
176 }
177
178 void ActionUpdate::InstallCompleteOnBlockingTaskRunner(
179 CrxUpdateItem* item,
180 const base::FilePath& crx_path,
181 ErrorCategory error_category,
182 int error,
183 int extended_error) {
184 update_client::DeleteFileAndEmptyParentDirectory(crx_path);
185 update_context_->main_task_runner->PostTask(
186 FROM_HERE,
187 base::Bind(&ActionUpdate::InstallComplete, base::Unretained(this),
188 item->id, error_category, error, extended_error));
189 }
190
191 CrxInstaller::Result ActionUpdate::DoInstall(
192 CrxUpdateItem* item,
193 const base::FilePath& crx_path,
194 const base::FilePath& unpack_path) {
195 const auto& fingerprint = item->next_fp;
196 if (static_cast<int>(fingerprint.size()) !=
197 base::WriteFile(
198 unpack_path.Append(FILE_PATH_LITERAL("manifest.fingerprint")),
199 fingerprint.c_str(), base::checked_cast<int>(fingerprint.size()))) {
200 return CrxInstaller::Result(InstallError::FINGERPRINT_WRITE_FAILED);
201 }
202
203 std::unique_ptr<base::DictionaryValue> manifest = ReadManifest(unpack_path);
204 if (!manifest.get())
205 return CrxInstaller::Result(InstallError::BAD_MANIFEST);
206
207 return item->component.installer->Install(*manifest, unpack_path);
208 }
209
210 void ActionUpdate::InstallComplete(const std::string& id,
211 ErrorCategory error_category,
212 int error,
213 int extended_error) {
214 DCHECK(thread_checker_.CalledOnValidThread());
215 DCHECK(id == update_context_->queue.front());
216
217 CrxUpdateItem* item = FindUpdateItemById(id);
218 DCHECK(item);
219
220 if (error == 0) {
221 DCHECK_EQ(ErrorCategory::kErrorNone, error_category);
222 DCHECK_EQ(0, extended_error);
223 OnInstallSuccess(item);
224 } else {
225 OnInstallError(item, error_category, error, extended_error);
226 }
227 }
228
229 ActionUpdateDiff::ActionUpdateDiff() {
230 }
231
232 ActionUpdateDiff::~ActionUpdateDiff() {
233 DCHECK(thread_checker_.CalledOnValidThread());
234 }
235
236 std::unique_ptr<Action> ActionUpdateDiff::Create() {
237 return std::unique_ptr<Action>(new ActionUpdateDiff);
238 }
239
240 void ActionUpdateDiff::TryUpdateFull() {
241 DCHECK(thread_checker_.CalledOnValidThread());
242 std::unique_ptr<Action> update_action(ActionUpdateFull::Create());
243
244 base::ThreadTaskRunnerHandle::Get()->PostTask(
245 FROM_HERE, base::Bind(&Action::Run, base::Unretained(update_action.get()),
246 update_context_, callback_));
247
248 update_context_->current_action = std::move(update_action);
249 }
250
251 bool ActionUpdateDiff::IsBackgroundDownload(const CrxUpdateItem* item) {
252 DCHECK(thread_checker_.CalledOnValidThread());
253 return false;
254 }
255
256 std::vector<GURL> ActionUpdateDiff::GetUrls(const CrxUpdateItem* item) {
257 DCHECK(thread_checker_.CalledOnValidThread());
258 return item->crx_diffurls;
259 }
260
261 std::string ActionUpdateDiff::GetHash(const CrxUpdateItem* item) {
262 DCHECK(thread_checker_.CalledOnValidThread());
263 return item->hashdiff_sha256;
264 }
265
266 void ActionUpdateDiff::OnDownloadStart(CrxUpdateItem* item) {
267 DCHECK(thread_checker_.CalledOnValidThread());
268 DCHECK(item->state == CrxUpdateItem::State::kCanUpdate);
269
270 ChangeItemState(item, CrxUpdateItem::State::kDownloadingDiff);
271 }
272
273 void ActionUpdateDiff::OnDownloadSuccess(
274 CrxUpdateItem* item,
275 const CrxDownloader::Result& download_result) {
276 DCHECK(thread_checker_.CalledOnValidThread());
277 DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
278
279 ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
280 }
281
282 void ActionUpdateDiff::OnDownloadError(
283 CrxUpdateItem* item,
284 const CrxDownloader::Result& download_result) {
285 DCHECK(thread_checker_.CalledOnValidThread());
286 DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
287
288 item->diff_error_category = static_cast<int>(ErrorCategory::kNetworkError);
289 item->diff_error_code = download_result.error;
290 item->diff_update_failed = true;
291
292 base::ThreadTaskRunnerHandle::Get()->PostTask(
293 FROM_HERE,
294 base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
295 }
296
297 void ActionUpdateDiff::OnInstallStart(CrxUpdateItem* item) {
298 DCHECK(thread_checker_.CalledOnValidThread());
299
300 ChangeItemState(item, CrxUpdateItem::State::kUpdatingDiff);
301 }
302
303 void ActionUpdateDiff::OnInstallSuccess(CrxUpdateItem* item) {
304 DCHECK(thread_checker_.CalledOnValidThread());
305 DCHECK(item->state == CrxUpdateItem::State::kUpdatingDiff);
306
307 item->component.version = item->next_version;
308 item->component.fingerprint = item->next_fp;
309 ChangeItemState(item, CrxUpdateItem::State::kUpdated);
310
311 UpdateCrxComplete(item);
312 }
313
314 void ActionUpdateDiff::OnInstallError(CrxUpdateItem* item,
315 ErrorCategory error_category,
316 int error,
317 int extended_error) {
318 DCHECK(thread_checker_.CalledOnValidThread());
319
320 item->diff_error_category = static_cast<int>(error_category);
321 item->diff_error_code = error;
322 item->diff_extra_code1 = extended_error;
323 item->diff_update_failed = true;
324
325 base::ThreadTaskRunnerHandle::Get()->PostTask(
326 FROM_HERE,
327 base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
328 }
329
330 ActionUpdateFull::ActionUpdateFull() {
331 }
332
333 ActionUpdateFull::~ActionUpdateFull() {
334 DCHECK(thread_checker_.CalledOnValidThread());
335 }
336
337 std::unique_ptr<Action> ActionUpdateFull::Create() {
338 return std::unique_ptr<Action>(new ActionUpdateFull);
339 }
340
341 bool ActionUpdateFull::IsBackgroundDownload(const CrxUpdateItem* item) {
342 DCHECK(thread_checker_.CalledOnValidThread());
343
344 // On demand component updates are always downloaded in foreground.
345 return !item->on_demand && item->component.allows_background_download &&
346 update_context_->config->EnabledBackgroundDownloader();
347 }
348
349 std::vector<GURL> ActionUpdateFull::GetUrls(const CrxUpdateItem* item) {
350 DCHECK(thread_checker_.CalledOnValidThread());
351 return item->crx_urls;
352 }
353
354 std::string ActionUpdateFull::GetHash(const CrxUpdateItem* item) {
355 DCHECK(thread_checker_.CalledOnValidThread());
356 return item->hash_sha256;
357 }
358
359 void ActionUpdateFull::OnDownloadStart(CrxUpdateItem* item) {
360 DCHECK(thread_checker_.CalledOnValidThread());
361 DCHECK(item->state == CrxUpdateItem::State::kCanUpdate ||
362 item->diff_update_failed);
363
364 ChangeItemState(item, CrxUpdateItem::State::kDownloading);
365 }
366
367 void ActionUpdateFull::OnDownloadSuccess(
368 CrxUpdateItem* item,
369 const CrxDownloader::Result& download_result) {
370 DCHECK(thread_checker_.CalledOnValidThread());
371 DCHECK(item->state == CrxUpdateItem::State::kDownloading);
372
373 ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
374 }
375
376 void ActionUpdateFull::OnDownloadError(
377 CrxUpdateItem* item,
378 const CrxDownloader::Result& download_result) {
379 DCHECK(thread_checker_.CalledOnValidThread());
380 DCHECK(item->state == CrxUpdateItem::State::kDownloading);
381
382 item->error_category = static_cast<int>(ErrorCategory::kNetworkError);
383 item->error_code = download_result.error;
384 ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
385
386 UpdateCrxComplete(item);
387 }
388
389 void ActionUpdateFull::OnInstallStart(CrxUpdateItem* item) {
390 DCHECK(thread_checker_.CalledOnValidThread());
391 DCHECK(item->state == CrxUpdateItem::State::kDownloaded);
392
393 ChangeItemState(item, CrxUpdateItem::State::kUpdating);
394 }
395
396 void ActionUpdateFull::OnInstallSuccess(CrxUpdateItem* item) {
397 DCHECK(thread_checker_.CalledOnValidThread());
398 DCHECK(item->state == CrxUpdateItem::State::kUpdating);
399
400 item->component.version = item->next_version;
401 item->component.fingerprint = item->next_fp;
402 ChangeItemState(item, CrxUpdateItem::State::kUpdated);
403
404 UpdateCrxComplete(item);
405 }
406
407 void ActionUpdateFull::OnInstallError(CrxUpdateItem* item,
408 ErrorCategory error_category,
409 int error,
410 int extended_error) {
411 DCHECK(thread_checker_.CalledOnValidThread());
412 DCHECK(item->state == CrxUpdateItem::State::kUpdating);
413
414 item->error_category = static_cast<int>(error_category);
415 item->error_code = error;
416 item->extra_code1 = extended_error;
417 ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
418
419 UpdateCrxComplete(item);
420 }
421
422 } // namespace update_client
OLDNEW
« no previous file with comments | « components/update_client/action_update.h ('k') | components/update_client/action_update_check.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698