Roll src/third_party/WebKit 9f7fb92:f103b33 (svn 202621:202622)
[chromium-blink-merge.git] / components / update_client / action.cc
blob3cdce79fbc6814121931ed3069d7ff5845c1fe98
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.h"
7 #include <algorithm>
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "components/update_client/action_update.h"
16 #include "components/update_client/action_wait.h"
17 #include "components/update_client/configurator.h"
18 #include "components/update_client/update_engine.h"
19 #include "components/update_client/utils.h"
21 namespace update_client {
23 using Events = UpdateClient::Observer::Events;
25 namespace {
27 // Returns true if a differential update is available, it has not failed yet,
28 // and the configuration allows this update.
29 bool CanTryDiffUpdate(const CrxUpdateItem* update_item,
30 const scoped_refptr<Configurator>& config) {
31 return HasDiffUpdate(update_item) && !update_item->diff_update_failed &&
32 config->DeltasEnabled();
35 } // namespace
37 ActionImpl::ActionImpl() : update_context_(nullptr) {
40 ActionImpl::~ActionImpl() {
41 DCHECK(thread_checker_.CalledOnValidThread());
44 void ActionImpl::Run(UpdateContext* update_context, Action::Callback callback) {
45 DCHECK(thread_checker_.CalledOnValidThread());
47 update_context_ = update_context;
48 callback_ = callback;
51 CrxUpdateItem* ActionImpl::FindUpdateItemById(const std::string& id) const {
52 DCHECK(thread_checker_.CalledOnValidThread());
54 const auto it(std::find_if(
55 update_context_->update_items.begin(),
56 update_context_->update_items.end(),
57 [&id](const CrxUpdateItem* item) { return item->id == id; }));
59 return it != update_context_->update_items.end() ? *it : nullptr;
62 void ActionImpl::ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::State to) {
63 DCHECK(thread_checker_.CalledOnValidThread());
65 item->state = to;
67 using Events = UpdateClient::Observer::Events;
69 const std::string& id(item->id);
70 switch (to) {
71 case CrxUpdateItem::State::kChecking:
72 NotifyObservers(Events::COMPONENT_CHECKING_FOR_UPDATES, id);
73 break;
74 case CrxUpdateItem::State::kCanUpdate:
75 NotifyObservers(Events::COMPONENT_UPDATE_FOUND, id);
76 break;
77 case CrxUpdateItem::State::kUpdatingDiff:
78 case CrxUpdateItem::State::kUpdating:
79 NotifyObservers(Events::COMPONENT_UPDATE_READY, id);
80 break;
81 case CrxUpdateItem::State::kUpdated:
82 NotifyObservers(Events::COMPONENT_UPDATED, id);
83 break;
84 case CrxUpdateItem::State::kUpToDate:
85 case CrxUpdateItem::State::kNoUpdate:
86 NotifyObservers(Events::COMPONENT_NOT_UPDATED, id);
87 break;
88 case CrxUpdateItem::State::kNew:
89 case CrxUpdateItem::State::kDownloading:
90 case CrxUpdateItem::State::kDownloadingDiff:
91 case CrxUpdateItem::State::kDownloaded:
92 case CrxUpdateItem::State::kLastStatus:
93 // No notification for these states.
94 break;
98 size_t ActionImpl::ChangeAllItemsState(CrxUpdateItem::State from,
99 CrxUpdateItem::State to) {
100 DCHECK(thread_checker_.CalledOnValidThread());
101 size_t count = 0;
102 for (auto item : update_context_->update_items) {
103 if (item->state == from) {
104 ChangeItemState(item, to);
105 ++count;
108 return count;
111 void ActionImpl::NotifyObservers(UpdateClient::Observer::Events event,
112 const std::string& id) {
113 DCHECK(thread_checker_.CalledOnValidThread());
114 update_context_->notify_observers_callback.Run(event, id);
117 void ActionImpl::UpdateCrx() {
118 DCHECK(thread_checker_.CalledOnValidThread());
119 DCHECK(!update_context_->queue.empty());
121 const std::string& id = update_context_->queue.front();
122 CrxUpdateItem* item = FindUpdateItemById(id);
123 DCHECK(item);
125 scoped_ptr<Action> update_action(
126 CanTryDiffUpdate(item, update_context_->config)
127 ? ActionUpdateDiff::Create()
128 : ActionUpdateFull::Create());
130 base::ThreadTaskRunnerHandle::Get()->PostTask(
131 FROM_HERE, base::Bind(&Action::Run, base::Unretained(update_action.get()),
132 update_context_, callback_));
134 update_context_->current_action.reset(update_action.release());
137 void ActionImpl::UpdateCrxComplete(CrxUpdateItem* item) {
138 update_context_->ping_manager->OnUpdateComplete(item);
140 update_context_->queue.pop();
142 if (update_context_->queue.empty()) {
143 UpdateComplete(0);
144 } else {
145 // TODO(sorin): the value of timing interval between CRX updates might have
146 // to be injected at the call site of update_client::UpdateClient::Update.
147 const int wait_sec = update_context_->config->UpdateDelay();
149 scoped_ptr<ActionWait> action_wait(
150 new ActionWait(base::TimeDelta::FromSeconds(wait_sec)));
152 base::ThreadTaskRunnerHandle::Get()->PostTask(
153 FROM_HERE, base::Bind(&Action::Run, base::Unretained(action_wait.get()),
154 update_context_, callback_));
156 update_context_->current_action.reset(action_wait.release());
160 void ActionImpl::UpdateComplete(int error) {
161 DCHECK(thread_checker_.CalledOnValidThread());
163 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
164 base::Bind(callback_, error));
167 } // namespace update_client