1 // Copyright 2014 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/update_client.h"
13 #include "base/bind.h"
14 #include "base/bind_helpers.h"
15 #include "base/callback.h"
16 #include "base/compiler_specific.h"
17 #include "base/location.h"
18 #include "base/logging.h"
19 #include "base/macros.h"
20 #include "base/observer_list.h"
21 #include "base/sequenced_task_runner.h"
22 #include "base/single_thread_task_runner.h"
23 #include "base/thread_task_runner_handle.h"
24 #include "base/threading/sequenced_worker_pool.h"
25 #include "base/threading/thread_checker.h"
26 #include "components/update_client/configurator.h"
27 #include "components/update_client/crx_update_item.h"
28 #include "components/update_client/ping_manager.h"
29 #include "components/update_client/task_update.h"
30 #include "components/update_client/update_checker.h"
31 #include "components/update_client/update_client_internal.h"
32 #include "components/update_client/update_engine.h"
33 #include "components/update_client/update_response.h"
34 #include "components/update_client/utils.h"
37 namespace update_client
{
39 CrxUpdateItem::CrxUpdateItem()
42 diff_update_failed(false),
46 diff_error_category(0),
51 CrxUpdateItem::~CrxUpdateItem() {
54 CrxComponent::CrxComponent() : allow_background_download(true) {
57 CrxComponent::~CrxComponent() {
60 // It is important that an instance of the UpdateClient binds an unretained
61 // pointer to itself. Otherwise, a life time circular dependency between this
62 // instance and its inner members prevents the destruction of this instance.
63 // Using unretained references is allowed in this case since the life time of
64 // the UpdateClient instance exceeds the life time of its inner members,
65 // including any thread objects that might execute callbacks bound to it.
66 UpdateClientImpl::UpdateClientImpl(
67 const scoped_refptr
<Configurator
>& config
,
68 scoped_ptr
<PingManager
> ping_manager
,
69 UpdateChecker::Factory update_checker_factory
,
70 CrxDownloader::Factory crx_downloader_factory
)
72 ping_manager_(ping_manager
.Pass()),
74 new UpdateEngine(config
,
75 update_checker_factory
,
76 crx_downloader_factory
,
78 base::Bind(&UpdateClientImpl::NotifyObservers
,
79 base::Unretained(this)))) {
82 UpdateClientImpl::~UpdateClientImpl() {
83 DCHECK(thread_checker_
.CalledOnValidThread());
87 void UpdateClientImpl::Install(const std::string
& id
,
88 const CrxDataCallback
& crx_data_callback
,
89 const CompletionCallback
& completion_callback
) {
90 DCHECK(thread_checker_
.CalledOnValidThread());
92 if (update_engine_
->IsUpdating(id
)) {
93 completion_callback
.Run(Error::ERROR_UPDATE_IN_PROGRESS
);
97 std::vector
<std::string
> ids
;
100 // Partially applies |completion_callback| to OnTaskComplete, so this
101 // argument is available when the task completes, along with the task itself.
102 const auto callback
=
103 base::Bind(&UpdateClientImpl::OnTaskComplete
, this, completion_callback
);
104 scoped_ptr
<TaskUpdate
> task(new TaskUpdate(update_engine_
.get(), true, ids
,
105 crx_data_callback
, callback
));
107 auto it
= tasks_
.insert(task
.release()).first
;
111 void UpdateClientImpl::Update(const std::vector
<std::string
>& ids
,
112 const CrxDataCallback
& crx_data_callback
,
113 const CompletionCallback
& completion_callback
) {
114 DCHECK(thread_checker_
.CalledOnValidThread());
116 const auto callback
=
117 base::Bind(&UpdateClientImpl::OnTaskComplete
, this, completion_callback
);
118 scoped_ptr
<TaskUpdate
> task(new TaskUpdate(update_engine_
.get(), false, ids
,
119 crx_data_callback
, callback
));
121 if (tasks_
.empty()) {
122 auto it
= tasks_
.insert(task
.release()).first
;
125 task_queue_
.push(task
.release());
129 void UpdateClientImpl::RunTask(Task
* task
) {
130 DCHECK(thread_checker_
.CalledOnValidThread());
131 base::ThreadTaskRunnerHandle::Get()->PostTask(
132 FROM_HERE
, base::Bind(&Task::Run
, base::Unretained(task
)));
135 void UpdateClientImpl::OnTaskComplete(
136 const CompletionCallback
& completion_callback
,
139 DCHECK(thread_checker_
.CalledOnValidThread());
142 base::ThreadTaskRunnerHandle::Get()->PostTask(
143 FROM_HERE
, base::Bind(completion_callback
, error
));
148 if (!task_queue_
.empty()) {
149 RunTask(task_queue_
.front());
154 void UpdateClientImpl::AddObserver(Observer
* observer
) {
155 DCHECK(thread_checker_
.CalledOnValidThread());
156 observer_list_
.AddObserver(observer
);
159 void UpdateClientImpl::RemoveObserver(Observer
* observer
) {
160 DCHECK(thread_checker_
.CalledOnValidThread());
161 observer_list_
.RemoveObserver(observer
);
164 void UpdateClientImpl::NotifyObservers(Observer::Events event
,
165 const std::string
& id
) {
166 DCHECK(thread_checker_
.CalledOnValidThread());
167 FOR_EACH_OBSERVER(Observer
, observer_list_
, OnEvent(event
, id
));
170 bool UpdateClientImpl::GetCrxUpdateState(const std::string
& id
,
171 CrxUpdateItem
* update_item
) const {
172 return update_engine_
->GetUpdateState(id
, update_item
);
175 bool UpdateClientImpl::IsUpdating(const std::string
& id
) const {
176 return update_engine_
->IsUpdating(id
);
179 scoped_refptr
<UpdateClient
> UpdateClientFactory(
180 const scoped_refptr
<Configurator
>& config
) {
181 scoped_ptr
<PingManager
> ping_manager(new PingManager(*config
));
182 return new UpdateClientImpl(config
, ping_manager
.Pass(),
183 &UpdateChecker::Create
, &CrxDownloader::Create
);
186 } // namespace update_client