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

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

Issue 2835803002: Refactor the UpdateEngine and its actions in the component updater. (Closed)
Patch Set: Created 3 years, 8 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 2017 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/component.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file_util.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h"
18 #include "components/update_client/configurator.h"
19 #include "components/update_client/update_client.h"
20 #include "components/update_client/update_client_errors.h"
21 #include "components/update_client/update_engine.h"
22 #include "components/update_client/utils.h"
23
24 // The state machine representing how a CRX component changes during an update.
25 //
26 //
27 // on-demand on-demand
28 // +--------------------------> kNew <---------------+-------------+
29 // | | | |
30 // | V | |
31 // | +---------------0----> kChecking -<-------+---|---<-----+ |
32 // | | | | | | |
33 // | | error V no | | | |
34 // kUpdateError <------------- [update?] ->---- kUpToDate kUpdated
35 // ^ | ^
36 // | yes | |
37 // | V |
38 // | kCanUpdate |
39 // | | |
40 // | V no |
41 // | [differential update?]--->----+ |
42 // | | | |
43 // | yes | | |
44 // | V error | |
45 // | kDownloadingDiff --->---------+ |
46 // | | | |
47 // | | | |
48 // | V error | |
49 // | kUpdatingDiff --->--------+-----------+ success
50 // | | |
51 // | error V |
52 // +----------------------------------------- kDownloading |
53 // | | |
54 // | error V |
55 // +------------------------------------------ kUpdating ->----+ success
56
57 namespace update_client {
58
59 namespace {
60
61 using InstallOnBlockingTaskRunnerCompleteCallback =
62 base::Callback<void(int error_category, int error_code, int extra_code1)>;
63
64 CrxInstaller::Result DoInstallOnBlockingTaskRunner(
65 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
66 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
67 const base::FilePath& unpack_path,
68 const std::string& fingerprint,
69 const scoped_refptr<CrxInstaller>& installer,
70 InstallOnBlockingTaskRunnerCompleteCallback callback) {
71 DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
72
73 if (static_cast<int>(fingerprint.size()) !=
74 base::WriteFile(
75 unpack_path.Append(FILE_PATH_LITERAL("manifest.fingerprint")),
76 fingerprint.c_str(), base::checked_cast<int>(fingerprint.size()))) {
77 return CrxInstaller::Result(InstallError::FINGERPRINT_WRITE_FAILED);
78 }
79
80 std::unique_ptr<base::DictionaryValue> manifest = ReadManifest(unpack_path);
81 if (!manifest)
82 return CrxInstaller::Result(InstallError::BAD_MANIFEST);
83
84 return installer->Install(*manifest, unpack_path);
85 }
86
87 void InstallOnBlockingTaskRunner(
88 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
89 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
90 const base::FilePath& unpack_path,
91 const std::string& fingerprint,
92 const scoped_refptr<CrxInstaller>& installer,
93 InstallOnBlockingTaskRunnerCompleteCallback callback) {
94 DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
95
96 const auto result = DoInstallOnBlockingTaskRunner(
97 main_task_runner, blocking_task_runner, unpack_path, fingerprint,
98 installer, callback);
99
100 const ErrorCategory error_category =
101 result.error ? ErrorCategory::kInstallError : ErrorCategory::kErrorNone;
102 main_task_runner->PostTask(
103 FROM_HERE,
104 base::Bind(callback, static_cast<int>(error_category),
105 static_cast<int>(result.error), result.extended_error));
106 }
107
108 void UnpackCompleteOnBlockingTaskRunner(
109 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
110 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
111 const base::FilePath& crx_path,
112 const std::string& fingerprint,
113 const scoped_refptr<CrxInstaller>& installer,
114 InstallOnBlockingTaskRunnerCompleteCallback callback,
115 const ComponentUnpacker::Result& result) {
116 DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
117
118 update_client::DeleteFileAndEmptyParentDirectory(crx_path);
119
120 if (result.error != UnpackerError::kNone) {
121 main_task_runner->PostTask(
122 FROM_HERE,
123 base::Bind(callback, static_cast<int>(ErrorCategory::kUnpackError),
124 static_cast<int>(result.error), result.extended_error));
125 return;
126 }
127
128 blocking_task_runner->PostTask(
129 FROM_HERE, base::Bind(&InstallOnBlockingTaskRunner, main_task_runner,
130 blocking_task_runner, result.unpack_path,
131 fingerprint, installer, callback));
132 }
133
134 void StartInstallOnBlockingTaskRunner(
135 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
136 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
137 const std::vector<uint8_t>& pk_hash,
138 const base::FilePath& crx_path,
139 const std::string& fingerprint,
140 const scoped_refptr<CrxInstaller>& installer,
141 const scoped_refptr<OutOfProcessPatcher>& oop_patcher,
142 InstallOnBlockingTaskRunnerCompleteCallback callback) {
143 DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
144
145 auto unpacker = base::MakeShared<ComponentUnpacker>(
146 pk_hash, crx_path, installer, oop_patcher, blocking_task_runner);
147
148 unpacker->Unpack(base::Bind(&UnpackCompleteOnBlockingTaskRunner,
149 main_task_runner, blocking_task_runner, crx_path,
150 fingerprint, installer, callback));
151 }
152
153 } // namespace
154
155 Component::Component(const UpdateContext& update_context, const std::string& id)
156 : id_(id),
157 state_(base::MakeUnique<StateNew>(this)),
158 update_context_(update_context) {}
159
160 Component::~Component() {}
161
162 void Component::Handle(CallbackHandleComplete callback) {
163 DCHECK(thread_checker_.CalledOnValidThread());
164 DCHECK(state_);
165
166 callback_handle_complete_ = callback;
167
168 state_->Handle(base::Bind(&Component::ChangeState, base::Unretained(this)));
169 }
170
171 void Component::ChangeState(std::unique_ptr<State> next_state) {
172 DCHECK(thread_checker_.CalledOnValidThread());
173
174 if (next_state)
175 state_ = std::move(next_state);
176
177 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
178 callback_handle_complete_);
179 }
180
181 CrxUpdateItem Component::GetCrxUpdateItem() const {
182 DCHECK(thread_checker_.CalledOnValidThread());
183
184 CrxUpdateItem crx_update_item;
185 crx_update_item.state = state_->state();
186 crx_update_item.id = id_;
187 crx_update_item.component = crx_component_;
188 crx_update_item.last_check = last_check_;
189 crx_update_item.next_version = next_version_;
190 crx_update_item.next_fp = next_fp_;
191
192 return crx_update_item;
193 }
194
195 void Component::SetParseResult(const UpdateResponse::Result& result) {
196 DCHECK(thread_checker_.CalledOnValidThread());
197
198 DCHECK_EQ(0, update_check_error_);
199
200 status_ = result.status;
201
202 if (result.manifest.packages.empty())
203 return;
204
205 next_version_ = base::Version(result.manifest.version);
206 const auto& package = result.manifest.packages.front();
207 next_fp_ = package.fingerprint;
208
209 // Resolve the urls by combining the base urls with the package names.
210 for (const auto& crx_url : result.crx_urls) {
211 const GURL url = crx_url.Resolve(package.name);
212 if (url.is_valid())
213 crx_urls_.push_back(url);
214 }
215 for (const auto& crx_diffurl : result.crx_diffurls) {
216 const GURL url = crx_diffurl.Resolve(package.namediff);
217 if (url.is_valid())
218 crx_diffurls_.push_back(url);
219 }
220
221 hash_sha256_ = package.hash_sha256;
222 hashdiff_sha256_ = package.hashdiff_sha256;
223 }
224
225 void Component::Uninstall(const base::Version& version, int reason) {
226 DCHECK(thread_checker_.CalledOnValidThread());
227
228 DCHECK_EQ(ComponentState::kNew, state());
229
230 previous_version_ = version;
231 next_version_ = base::Version("0");
232 extra_code1_ = reason;
233
234 state_ = base::MakeUnique<StateUninstalled>(this);
235 }
236
237 void Component::UpdateCheckComplete() const {
238 DCHECK(thread_checker_.CalledOnValidThread());
239
240 DCHECK_EQ(ComponentState::kChecking, state());
241
242 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
243 update_check_complete_);
244 }
245
246 bool Component::CanDoBackgroundDownload() const {
247 // On demand component updates are always downloaded in foreground.
248 return !on_demand_ && crx_component_.allows_background_download &&
249 update_context_.config->EnabledBackgroundDownloader();
250 }
251
252 void Component::AppendDownloadMetrics(
253 const std::vector<CrxDownloader::DownloadMetrics>& download_metrics) {
254 download_metrics_.insert(download_metrics_.end(), download_metrics.begin(),
255 download_metrics.end());
256 }
257
258 void Component::NotifyObservers(UpdateClient::Observer::Events event) const {
259 DCHECK(thread_checker_.CalledOnValidThread());
260 update_context_.notify_observers_callback.Run(event, id_);
261 }
262
263 base::TimeDelta Component::GetUpdateDuration() const {
264 DCHECK(thread_checker_.CalledOnValidThread());
265
266 if (update_begin_.is_null())
267 return base::TimeDelta();
268
269 const base::TimeDelta update_cost(base::TimeTicks::Now() - update_begin_);
270 DCHECK_GE(update_cost, base::TimeDelta());
271 const base::TimeDelta max_update_delay =
272 base::TimeDelta::FromSeconds(update_context_.config->UpdateDelay());
273 return std::min(update_cost, max_update_delay);
274 }
275
276 Component::State::State(Component* component, ComponentState state)
277 : state_(state), component_(*component) {}
278
279 Component::State::~State() {}
280
281 void Component::State::Handle(CallbackNextState callback) {
282 DCHECK(thread_checker_.CalledOnValidThread());
283
284 callback_ = callback;
285
286 DCHECK(!is_final_);
287 DoHandle();
288 }
289
290 void Component::State::TransitionState(std::unique_ptr<State> next_state) {
291 if (!next_state)
292 is_final_ = true;
293
294 base::ThreadTaskRunnerHandle::Get()->PostTask(
295 FROM_HERE, base::Bind(callback(), base::Passed(&next_state)));
296 }
297
298 Component::StateNew::StateNew(Component* component)
299 : State(component, ComponentState::kNew) {}
300
301 Component::StateNew::~StateNew() {
302 DCHECK(thread_checker_.CalledOnValidThread());
303 }
304
305 void Component::StateNew::DoHandle() {
306 DCHECK(thread_checker_.CalledOnValidThread());
307
308 auto& component = State::component();
309
310 TransitionState(base::MakeUnique<StateChecking>(&component));
311 }
312
313 Component::StateChecking::StateChecking(Component* component)
314 : State(component, ComponentState::kChecking) {}
315
316 Component::StateChecking::~StateChecking() {
317 DCHECK(thread_checker_.CalledOnValidThread());
318 }
319
320 // Unlike how other states are handled, this function does not change the
321 // state right away. The state transition happens when the UpdateChecker
322 // calls Component::UpdateCheckComplete and |update_check_complete_| is invoked.
323 // This is an artifact of how multiple components must be checked for updates
324 // together but the state machine defines the transitions for one component
325 // at a time.
326 void Component::StateChecking::DoHandle() {
327 DCHECK(thread_checker_.CalledOnValidThread());
328
329 auto& component = State::component();
330
331 component.last_check_ = base::TimeTicks::Now();
332 component.update_check_complete_ = base::Bind(
333 &Component::StateChecking::UpdateCheckComplete, base::Unretained(this));
334
335 component.NotifyObservers(Events::COMPONENT_CHECKING_FOR_UPDATES);
336 }
337
338 void Component::StateChecking::UpdateCheckComplete() {
339 DCHECK(thread_checker_.CalledOnValidThread());
340 auto& component = State::component();
341 if (!component.update_check_error_) {
342 if (component.status_ == "ok") {
343 TransitionState(base::MakeUnique<StateCanUpdate>(&component));
344 return;
345 }
346
347 if (component.status_ == "noupdate") {
348 TransitionState(base::MakeUnique<StateUpToDate>(&component));
349 return;
350 }
351 }
352
353 TransitionState(base::MakeUnique<StateUpdateError>(&component));
354 }
355
356 Component::StateUpdateError::StateUpdateError(Component* component)
357 : State(component, ComponentState::kUpdateError) {}
358
359 Component::StateUpdateError::~StateUpdateError() {
360 DCHECK(thread_checker_.CalledOnValidThread());
361 }
362
363 void Component::StateUpdateError::DoHandle() {
364 DCHECK(thread_checker_.CalledOnValidThread());
365
366 auto& component = State::component();
367 TransitionState(nullptr);
368 component.NotifyObservers(Events::COMPONENT_NOT_UPDATED);
369 }
370
371 Component::StateCanUpdate::StateCanUpdate(Component* component)
372 : State(component, ComponentState::kCanUpdate) {}
373
374 Component::StateCanUpdate::~StateCanUpdate() {
375 DCHECK(thread_checker_.CalledOnValidThread());
376 }
377
378 void Component::StateCanUpdate::DoHandle() {
379 DCHECK(thread_checker_.CalledOnValidThread());
380
381 auto& component = State::component();
382
383 component.is_update_available_ = true;
384 component.NotifyObservers(Events::COMPONENT_UPDATE_FOUND);
385
386 if (component.crx_component_.supports_group_policy_enable_component_updates &&
387 !component.update_context_.enabled_component_updates) {
388 component.error_category_ = static_cast<int>(ErrorCategory::kServiceError);
389 component.error_code_ = static_cast<int>(ServiceError::UPDATE_DISABLED);
390 component.extra_code1_ = 0;
391 TransitionState(base::MakeUnique<StateUpdateError>(&component));
392 return;
393 }
394
395 // Start computing the cost of the this update from here on.
396 component.update_begin_ = base::TimeTicks::Now();
397
398 if (CanTryDiffUpdate())
399 TransitionState(base::MakeUnique<StateDownloadingDiff>(&component));
400 else
401 TransitionState(base::MakeUnique<StateDownloading>(&component));
402 }
403
404 // Returns true if a differential update is available, it has not failed yet,
405 // and the configuration allows this update.
406 bool Component::StateCanUpdate::CanTryDiffUpdate() const {
407 const auto& component = Component::State::component();
408 return HasDiffUpdate(component) && !component.diff_error_code_ &&
409 component.update_context_.config->EnabledDeltas();
410 }
411
412 Component::StateUpToDate::StateUpToDate(Component* component)
413 : State(component, ComponentState::kUpToDate) {}
414
415 Component::StateUpToDate::~StateUpToDate() {
416 DCHECK(thread_checker_.CalledOnValidThread());
417 }
418
419 void Component::StateUpToDate::DoHandle() {
420 DCHECK(thread_checker_.CalledOnValidThread());
421
422 auto& component = State::component();
423
424 TransitionState(nullptr);
425 component.NotifyObservers(Events::COMPONENT_NOT_UPDATED);
426 }
427
428 Component::StateDownloadingDiff::StateDownloadingDiff(Component* component)
429 : State(component, ComponentState::kDownloadingDiff) {}
430
431 Component::StateDownloadingDiff::~StateDownloadingDiff() {
432 DCHECK(thread_checker_.CalledOnValidThread());
433 }
434
435 void Component::StateDownloadingDiff::DoHandle() {
436 DCHECK(thread_checker_.CalledOnValidThread());
437
438 const auto& component = Component::State::component();
439 const auto& update_context = component.update_context_;
440
441 crx_downloader_ = update_context.crx_downloader_factory(
442 component.CanDoBackgroundDownload(),
443 update_context.config->RequestContext(),
444 update_context.blocking_task_runner);
445
446 const auto& id = component.id_;
447 crx_downloader_->set_progress_callback(
448 base::Bind(&Component::StateDownloadingDiff::DownloadProgress,
449 base::Unretained(this), id));
450 crx_downloader_->StartDownload(
451 component.crx_diffurls_, component.hashdiff_sha256_,
452 base::Bind(&Component::StateDownloadingDiff::DownloadComplete,
453 base::Unretained(this), id));
454
455 component.NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
456 }
457
458 // Called when progress is being made downloading a CRX. The progress may
459 // not monotonically increase due to how the CRX downloader switches between
460 // different downloaders and fallback urls.
461 void Component::StateDownloadingDiff::DownloadProgress(
462 const std::string& id,
463 const CrxDownloader::Result& download_result) {
464 DCHECK(thread_checker_.CalledOnValidThread());
465
466 component().NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
467 }
468
469 void Component::StateDownloadingDiff::DownloadComplete(
470 const std::string& id,
471 const CrxDownloader::Result& download_result) {
472 DCHECK(thread_checker_.CalledOnValidThread());
473
474 auto& component = Component::State::component();
475
476 component.AppendDownloadMetrics(crx_downloader_->download_metrics());
477
478 crx_downloader_.reset();
479
480 if (download_result.error) {
481 component.diff_error_category_ =
482 static_cast<int>(ErrorCategory::kNetworkError);
483 component.diff_error_code_ = download_result.error;
484
485 TransitionState(base::MakeUnique<StateDownloading>(&component));
486 return;
487 }
488
489 component.crx_path_ = download_result.response;
490
491 TransitionState(base::MakeUnique<StateUpdatingDiff>(&component));
492 }
493
494 Component::StateDownloading::StateDownloading(Component* component)
495 : State(component, ComponentState::kDownloading) {}
496
497 Component::StateDownloading::~StateDownloading() {
498 DCHECK(thread_checker_.CalledOnValidThread());
499 }
500
501 void Component::StateDownloading::DoHandle() {
502 DCHECK(thread_checker_.CalledOnValidThread());
503
504 const auto& component = Component::State::component();
505 const auto& update_context = component.update_context_;
506
507 crx_downloader_ = update_context.crx_downloader_factory(
508 component.CanDoBackgroundDownload(),
509 update_context.config->RequestContext(),
510 update_context.blocking_task_runner);
511
512 const auto& id = component.id_;
513 crx_downloader_->set_progress_callback(
514 base::Bind(&Component::StateDownloading::DownloadProgress,
515 base::Unretained(this), id));
516 crx_downloader_->StartDownload(
517 component.crx_urls_, component.hash_sha256_,
518 base::Bind(&Component::StateDownloading::DownloadComplete,
519 base::Unretained(this), id));
520
521 component.NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
522 }
523
524 // Called when progress is being made downloading a CRX. The progress may
525 // not monotonically increase due to how the CRX downloader switches between
526 // different downloaders and fallback urls.
527 void Component::StateDownloading::DownloadProgress(
528 const std::string& id,
529 const CrxDownloader::Result& download_result) {
530 DCHECK(thread_checker_.CalledOnValidThread());
531
532 component().NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
533 }
534
535 void Component::StateDownloading::DownloadComplete(
536 const std::string& id,
537 const CrxDownloader::Result& download_result) {
538 DCHECK(thread_checker_.CalledOnValidThread());
539
540 auto& component = Component::State::component();
541
542 component.AppendDownloadMetrics(crx_downloader_->download_metrics());
543
544 crx_downloader_.reset();
545
546 if (download_result.error) {
547 component.error_category_ = static_cast<int>(ErrorCategory::kNetworkError);
548 component.error_code_ = download_result.error;
549
550 TransitionState(base::MakeUnique<StateUpdateError>(&component));
551 return;
552 }
553
554 component.crx_path_ = download_result.response;
555
556 TransitionState(base::MakeUnique<StateUpdating>(&component));
557 }
558
559 Component::StateUpdatingDiff::StateUpdatingDiff(Component* component)
560 : State(component, ComponentState::kUpdatingDiff) {}
561
562 Component::StateUpdatingDiff::~StateUpdatingDiff() {
563 DCHECK(thread_checker_.CalledOnValidThread());
564 }
565
566 void Component::StateUpdatingDiff::DoHandle() {
567 DCHECK(thread_checker_.CalledOnValidThread());
568
569 const auto& component = Component::State::component();
570 const auto& update_context = component.update_context_;
571
572 component.NotifyObservers(Events::COMPONENT_UPDATE_READY);
573
574 update_context.blocking_task_runner->PostTask(
575 FROM_HERE,
576 base::Bind(&update_client::StartInstallOnBlockingTaskRunner,
577 base::ThreadTaskRunnerHandle::Get(),
578 update_context.blocking_task_runner,
579 component.crx_component_.pk_hash, component.crx_path_,
580 component.next_fp_, component.crx_component_.installer,
581 update_context.config->CreateOutOfProcessPatcher(),
582 base::Bind(&Component::StateUpdatingDiff::InstallComplete,
583 base::Unretained(this))));
584 }
585
586 void Component::StateUpdatingDiff::InstallComplete(int error_category,
587 int error_code,
588 int extra_code1) {
589 DCHECK(thread_checker_.CalledOnValidThread());
590
591 auto& component = Component::State::component();
592
593 component.diff_error_category_ = error_category;
594 component.diff_error_code_ = error_code;
595 component.diff_extra_code1_ = extra_code1;
596
597 if (component.diff_error_code_ != 0) {
598 TransitionState(base::MakeUnique<StateDownloading>(&component));
599 return;
600 }
601
602 DCHECK_EQ(static_cast<int>(ErrorCategory::kErrorNone),
603 component.diff_error_category_);
604 DCHECK_EQ(0, component.diff_error_code_);
605 DCHECK_EQ(0, component.diff_extra_code1_);
606
607 DCHECK_EQ(static_cast<int>(ErrorCategory::kErrorNone),
608 component.error_category_);
609 DCHECK_EQ(0, component.error_code_);
610 DCHECK_EQ(0, component.extra_code1_);
611
612 TransitionState(base::MakeUnique<StateUpdated>(&component));
613 }
614
615 Component::StateUpdating::StateUpdating(Component* component)
616 : State(component, ComponentState::kUpdating),
617 main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
618
619 Component::StateUpdating::~StateUpdating() {
620 DCHECK(thread_checker_.CalledOnValidThread());
621 }
622
623 void Component::StateUpdating::DoHandle() {
624 DCHECK(thread_checker_.CalledOnValidThread());
625
626 const auto& component = Component::State::component();
627 const auto& update_context = component.update_context_;
628
629 component.NotifyObservers(Events::COMPONENT_UPDATE_READY);
630
631 update_context.blocking_task_runner->PostTask(
632 FROM_HERE,
633 base::Bind(&update_client::StartInstallOnBlockingTaskRunner,
634 base::ThreadTaskRunnerHandle::Get(),
635 update_context.blocking_task_runner,
636 component.crx_component_.pk_hash, component.crx_path_,
637 component.next_fp_, component.crx_component_.installer,
638 update_context.config->CreateOutOfProcessPatcher(),
639 base::Bind(&Component::StateUpdating::InstallComplete,
640 base::Unretained(this))));
641 }
642
643 void Component::StateUpdating::InstallComplete(int error_category,
644 int error_code,
645 int extra_code1) {
646 DCHECK(thread_checker_.CalledOnValidThread());
647
648 auto& component = Component::State::component();
649
650 component.error_category_ = error_category;
651 component.error_code_ = error_code;
652 component.extra_code1_ = extra_code1;
653
654 if (component.error_code_ != 0) {
655 TransitionState(base::MakeUnique<StateUpdateError>(&component));
656 return;
657 }
658
659 DCHECK_EQ(static_cast<int>(ErrorCategory::kErrorNone),
660 component.error_category_);
661 DCHECK_EQ(0, component.error_code_);
662 DCHECK_EQ(0, component.extra_code1_);
663
664 TransitionState(base::MakeUnique<StateUpdated>(&component));
665 }
666
667 Component::StateUpdated::StateUpdated(Component* component)
668 : State(component, ComponentState::kUpdated) {
669 DCHECK(thread_checker_.CalledOnValidThread());
670 }
671
672 Component::StateUpdated::~StateUpdated() {
673 DCHECK(thread_checker_.CalledOnValidThread());
674 }
675
676 void Component::StateUpdated::DoHandle() {
677 DCHECK(thread_checker_.CalledOnValidThread());
678
679 auto& component = State::component();
680 component.crx_component_.version = component.next_version_;
681 component.crx_component_.fingerprint = component.next_fp_;
682
683 TransitionState(nullptr);
684 component.NotifyObservers(Events::COMPONENT_UPDATED);
685 }
686
687 Component::StateUninstalled::StateUninstalled(Component* component)
688 : State(component, ComponentState::kUninstalled) {
689 DCHECK(thread_checker_.CalledOnValidThread());
690 }
691
692 Component::StateUninstalled::~StateUninstalled() {
693 DCHECK(thread_checker_.CalledOnValidThread());
694 }
695
696 void Component::StateUninstalled::DoHandle() {
697 DCHECK(thread_checker_.CalledOnValidThread());
698 TransitionState(nullptr);
699 }
700
701 } // namespace update_client
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698