[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / component_updater / component_updater_service.cc
1 // Copyright 2014 The Chromium Authors
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/component_updater/component_updater_service.h"
6
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/check.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/functional/bind.h"
17 #include "base/functional/callback.h"
18 #include "base/functional/callback_helpers.h"
19 #include "base/logging.h"
20 #include "base/metrics/histogram_macros.h"
21 #include "base/ranges/algorithm.h"
22 #include "base/sequence_checker.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/task/sequenced_task_runner.h"
25 #include "base/time/time.h"
26 #include "base/timer/timer.h"
27 #include "components/component_updater/component_installer.h"
28 #include "components/component_updater/component_updater_service_internal.h"
29 #include "components/component_updater/component_updater_utils.h"
30 #include "components/component_updater/pref_names.h"
31 #include "components/prefs/pref_registry_simple.h"
32 #include "components/prefs/pref_service.h"
33 #include "components/update_client/configurator.h"
34 #include "components/update_client/crx_update_item.h"
35 #include "components/update_client/update_client.h"
36 #include "components/update_client/update_client_errors.h"
37 #include "components/update_client/utils.h"
38 #include "third_party/abseil-cpp/absl/types/optional.h"
39 #include "url/gurl.h"
40
41 using CrxInstaller = update_client::CrxInstaller;
42 using UpdateClient = update_client::UpdateClient;
43
44 namespace {
45
46 enum UpdateType {
47   UPDATE_TYPE_MANUAL = 0,
48   UPDATE_TYPE_AUTOMATIC,
49   UPDATE_TYPE_COUNT,
50 };
51
52 }  // namespace
53
54 namespace component_updater {
55
56 ComponentInfo::ComponentInfo(const std::string& id,
57                              const std::string& fingerprint,
58                              const std::u16string& name,
59                              const base::Version& version,
60                              const std::string& cohort_id)
61     : id(id),
62       fingerprint(fingerprint),
63       name(name),
64       version(version),
65       cohort_id(cohort_id) {}
66 ComponentInfo::ComponentInfo(const ComponentInfo& other) = default;
67 ComponentInfo& ComponentInfo::operator=(const ComponentInfo& other) = default;
68 ComponentInfo::ComponentInfo(ComponentInfo&& other) = default;
69 ComponentInfo& ComponentInfo::operator=(ComponentInfo&& other) = default;
70 ComponentInfo::~ComponentInfo() = default;
71
72 ComponentRegistration::ComponentRegistration(
73     const std::string& app_id,
74     const std::string& name,
75     std::vector<uint8_t> public_key_hash,
76     const base::Version& version,
77     const std::string& fingerprint,
78     std::map<std::string, std::string> installer_attributes,
79     scoped_refptr<update_client::ActionHandler> action_handler,
80     scoped_refptr<update_client::CrxInstaller> installer,
81     bool requires_network_encryption,
82     bool supports_group_policy_enable_component_updates)
83     : app_id(app_id),
84       name(name),
85       public_key_hash(public_key_hash),
86       version(version),
87       fingerprint(fingerprint),
88       installer_attributes(installer_attributes),
89       action_handler(action_handler),
90       installer(installer),
91       requires_network_encryption(requires_network_encryption),
92       supports_group_policy_enable_component_updates(
93           supports_group_policy_enable_component_updates) {}
94 ComponentRegistration::ComponentRegistration(
95     const ComponentRegistration& other) = default;
96 ComponentRegistration& ComponentRegistration::operator=(
97     const ComponentRegistration& other) = default;
98 ComponentRegistration::ComponentRegistration(ComponentRegistration&& other) =
99     default;
100 ComponentRegistration& ComponentRegistration::operator=(
101     ComponentRegistration&& other) = default;
102 ComponentRegistration::~ComponentRegistration() = default;
103
104 CrxUpdateService::CrxUpdateService(scoped_refptr<Configurator> config,
105                                    std::unique_ptr<UpdateScheduler> scheduler,
106                                    scoped_refptr<UpdateClient> update_client,
107                                    const std::string& brand)
108     : config_(config),
109       scheduler_(std::move(scheduler)),
110       update_client_(update_client),
111       brand_(brand) {
112   AddObserver(this);
113 }
114
115 CrxUpdateService::~CrxUpdateService() {
116   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
117
118   for (auto& item : ready_callbacks_) {
119     std::move(item.second).Run();
120   }
121
122   RemoveObserver(this);
123
124   Stop();
125 }
126
127 void CrxUpdateService::AddObserver(Observer* observer) {
128   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
129   update_client_->AddObserver(observer);
130 }
131
132 void CrxUpdateService::RemoveObserver(Observer* observer) {
133   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
134   update_client_->RemoveObserver(observer);
135 }
136
137 base::Version CrxUpdateService::GetRegisteredVersion(
138     const std::string& app_id) {
139   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
140   base::Version registered_version =
141       std::make_unique<update_client::PersistedData>(
142           config_->GetPrefService(), config_->GetActivityDataService())
143           ->GetProductVersion(app_id);
144
145   return (registered_version.IsValid()) ? registered_version
146                                         : base::Version(kNullVersion);
147 }
148
149 void CrxUpdateService::Start() {
150   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
151   VLOG(1) << "CrxUpdateService starting up. "
152           << "First update attempt will take place in "
153           << config_->InitialDelay() << " seconds. "
154           << "Next update attempt will take place in "
155           << config_->NextCheckDelay() << " seconds. ";
156
157   scheduler_->Schedule(
158       config_->InitialDelay(), config_->NextCheckDelay(),
159       base::BindRepeating(
160           base::IgnoreResult(&CrxUpdateService::CheckForUpdates),
161           base::Unretained(this)),
162       base::DoNothing());
163 }
164
165 // Stops the update loop. In flight operations will be completed.
166 void CrxUpdateService::Stop() {
167   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
168   VLOG(1) << "CrxUpdateService stopping";
169   scheduler_->Stop();
170   update_client_->Stop();
171 }
172
173 // Adds a component to be checked for upgrades. If the component exists it
174 // it will be replaced.
175 bool CrxUpdateService::RegisterComponent(
176     const ComponentRegistration& component) {
177   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
178   if (component.app_id.empty() || !component.version.IsValid() ||
179       !component.installer) {
180     return false;
181   }
182
183   // Update the registration data if the component has been registered before.
184   auto it = components_.find(component.app_id);
185   if (it != components_.end()) {
186     it->second = component;
187     return true;
188   }
189
190   components_.insert(std::make_pair(component.app_id, component));
191   components_order_.push_back(component.app_id);
192
193   // Create an initial state for this component. The state is mutated in
194   // response to events from the UpdateClient instance.
195   CrxUpdateItem item;
196   item.id = component.app_id;
197   item.component = ToCrxComponent(component);
198   const auto inserted =
199       component_states_.insert(std::make_pair(component.app_id, item));
200   DCHECK(inserted.second);
201
202   // Start the timer if this is the first component registered. The first timer
203   // event occurs after an interval defined by the component update
204   // configurator. The subsequent timer events are repeated with a period
205   // defined by the same configurator.
206   if (components_.size() == 1)
207     Start();
208
209   return true;
210 }
211
212 bool CrxUpdateService::UnregisterComponent(const std::string& id) {
213   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
214   auto it = components_.find(id);
215   if (it == components_.end())
216     return false;
217
218   DCHECK_EQ(id, it->first);
219
220   // Delay the uninstall of the component if the component is being updated.
221   if (update_client_->IsUpdating(id)) {
222     components_pending_unregistration_.push_back(id);
223     return true;
224   }
225
226   return DoUnregisterComponent(id);
227 }
228
229 bool CrxUpdateService::DoUnregisterComponent(const std::string& id) {
230   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
231
232   DCHECK(ready_callbacks_.find(id) == ready_callbacks_.end());
233
234   const bool result = components_.find(id)->second.installer->Uninstall();
235
236   const auto pos = base::ranges::find(components_order_, id);
237   if (pos != components_order_.end())
238     components_order_.erase(pos);
239
240   components_.erase(id);
241   component_states_.erase(id);
242
243   return result;
244 }
245
246 std::vector<std::string> CrxUpdateService::GetComponentIDs() const {
247   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
248   std::vector<std::string> ids;
249   for (const auto& it : components_)
250     ids.push_back(it.first);
251   return ids;
252 }
253
254 std::vector<ComponentInfo> CrxUpdateService::GetComponents() const {
255   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
256   std::vector<ComponentInfo> result;
257   auto data = std::make_unique<update_client::PersistedData>(
258       config_->GetPrefService(), config_->GetActivityDataService());
259   for (const auto& it : components_) {
260     result.push_back(ComponentInfo(
261         it.first, it.second.fingerprint, base::UTF8ToUTF16(it.second.name),
262         it.second.version, data->GetCohort(it.second.app_id)));
263   }
264   return result;
265 }
266
267 OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() {
268   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
269   return *this;
270 }
271
272 update_client::CrxComponent CrxUpdateService::ToCrxComponent(
273     const ComponentRegistration& component) const {
274   update_client::CrxComponent crx;
275   crx.pk_hash = component.public_key_hash;
276   crx.app_id = component.app_id;
277   crx.installer = component.installer;
278   crx.action_handler = component.action_handler;
279   crx.version = component.version;
280   crx.fingerprint = component.fingerprint;
281   crx.name = component.name;
282   crx.installer_attributes = component.installer_attributes;
283   crx.requires_network_encryption = component.requires_network_encryption;
284
285   crx.brand = brand_;
286   crx.crx_format_requirement =
287       crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF;
288   crx.updates_enabled =
289       !component.supports_group_policy_enable_component_updates ||
290       config_->GetPrefService()->GetBoolean(prefs::kComponentUpdatesEnabled);
291
292   return crx;
293 }
294
295 absl::optional<ComponentRegistration> CrxUpdateService::GetComponent(
296     const std::string& id) const {
297   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
298   return component_updater::GetComponent(components_, id);
299 }
300
301 const CrxUpdateItem* CrxUpdateService::GetComponentState(
302     const std::string& id) const {
303   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
304   const auto it(component_states_.find(id));
305   return it != component_states_.end() ? &it->second : nullptr;
306 }
307
308 void CrxUpdateService::MaybeThrottle(const std::string& id,
309                                      base::OnceClosure callback) {
310   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
311   const auto it = components_.find(id);
312   if (it != components_.end()) {
313     DCHECK_EQ(it->first, id);
314     if (OnDemandUpdateWithCooldown(id)) {
315       ready_callbacks_.insert(std::make_pair(id, std::move(callback)));
316       return;
317     }
318   }
319
320   // Unblock the request if the request can't be throttled.
321   std::move(callback).Run();
322 }
323
324 void CrxUpdateService::OnDemandUpdate(const std::string& id,
325                                       Priority priority,
326                                       Callback callback) {
327   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
328
329   if (!GetComponent(id)) {
330     if (!callback.is_null()) {
331       base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
332           FROM_HERE, base::BindOnce(std::move(callback),
333                                     update_client::Error::INVALID_ARGUMENT));
334     }
335     return;
336   }
337
338   OnDemandUpdateInternal(id, priority, std::move(callback));
339 }
340
341 bool CrxUpdateService::OnDemandUpdateWithCooldown(const std::string& id) {
342   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
343
344   DCHECK(GetComponent(id));
345
346   // Check if the request is too soon.
347   const auto* component_state(GetComponentState(id));
348   if (component_state && !component_state->last_check.is_null()) {
349     base::TimeDelta delta =
350         base::TimeTicks::Now() - component_state->last_check;
351     if (delta < config_->OnDemandDelay())
352       return false;
353   }
354
355   OnDemandUpdateInternal(id, Priority::FOREGROUND, Callback());
356   return true;
357 }
358
359 void CrxUpdateService::OnDemandUpdateInternal(const std::string& id,
360                                               Priority priority,
361                                               Callback callback) {
362   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
363
364   UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.Calls", UPDATE_TYPE_MANUAL,
365                             UPDATE_TYPE_COUNT);
366
367   auto crx_data_callback = base::BindOnce(&CrxUpdateService::GetCrxComponents,
368                                           base::Unretained(this));
369   auto update_complete_callback = base::BindOnce(
370       &CrxUpdateService::OnUpdateComplete, base::Unretained(this),
371       std::move(callback), base::TimeTicks::Now());
372
373   if (priority == Priority::FOREGROUND)
374     update_client_->Install(id, std::move(crx_data_callback), {},
375                             std::move(update_complete_callback));
376   else if (priority == Priority::BACKGROUND)
377     update_client_->Update({id}, std::move(crx_data_callback), {}, false,
378                            std::move(update_complete_callback));
379   else
380     NOTREACHED();
381 }
382
383 bool CrxUpdateService::CheckForUpdates(
384     UpdateScheduler::OnFinishedCallback on_finished) {
385   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
386
387   UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.Calls", UPDATE_TYPE_AUTOMATIC,
388                             UPDATE_TYPE_COUNT);
389
390   if (components_order_.empty()) {
391     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
392         FROM_HERE, std::move(on_finished));
393     return true;
394   }
395
396   update_client_->Update(
397       components_order_,
398       base::BindOnce(&CrxUpdateService::GetCrxComponents,
399                      base::Unretained(this)),
400       {}, false,
401       base::BindOnce(&CrxUpdateService::OnUpdateComplete,
402                      base::Unretained(this),
403                      base::BindOnce(
404                          [](UpdateScheduler::OnFinishedCallback on_finished,
405                             update_client::Error /*error*/) {
406                            std::move(on_finished).Run();
407                          },
408                          std::move(on_finished)),
409                      base::TimeTicks::Now()));
410   return true;
411 }
412
413 bool CrxUpdateService::GetComponentDetails(const std::string& id,
414                                            CrxUpdateItem* item) const {
415   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
416
417   // First, if this component is currently being updated, return its state from
418   // the update client.
419   if (update_client_->GetCrxUpdateState(id, item))
420     return true;
421
422   // Otherwise, return the last seen state of the component, if such a
423   // state exists.
424   const auto component_states_it = component_states_.find(id);
425   if (component_states_it != component_states_.end()) {
426     *item = component_states_it->second;
427     return true;
428   }
429
430   return false;
431 }
432
433 void CrxUpdateService::GetCrxComponents(
434     const std::vector<std::string>& ids,
435     base::OnceCallback<void(const std::vector<absl::optional<CrxComponent>>&)>
436         callback) {
437   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
438   std::vector<absl::optional<CrxComponent>> crxs;
439   for (absl::optional<ComponentRegistration> item :
440        component_updater::GetCrxComponents(components_, ids)) {
441     crxs.push_back(item ? absl::optional<CrxComponent>{ToCrxComponent(*item)}
442                         : absl::nullopt);
443   }
444   std::move(callback).Run(crxs);
445 }
446
447 void CrxUpdateService::OnUpdateComplete(Callback callback,
448                                         const base::TimeTicks& start_time,
449                                         update_client::Error error) {
450   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
451   VLOG(1) << "Update completed with error " << static_cast<int>(error);
452
453   UMA_HISTOGRAM_BOOLEAN("ComponentUpdater.UpdateCompleteResult",
454                         error != update_client::Error::NONE);
455   UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.UpdateCompleteError", error,
456                             update_client::Error::MAX_VALUE);
457   UMA_HISTOGRAM_LONG_TIMES_100("ComponentUpdater.UpdateCompleteTime",
458                                base::TimeTicks::Now() - start_time);
459
460   for (const auto& id : components_pending_unregistration_) {
461     if (!update_client_->IsUpdating(id)) {
462       const auto component = GetComponent(id);
463       if (component)
464         DoUnregisterComponent(id);
465     }
466   }
467
468   if (!callback.is_null()) {
469     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
470         FROM_HERE, base::BindOnce(std::move(callback), error));
471   }
472 }
473
474 void CrxUpdateService::OnEvent(Events event, const std::string& id) {
475   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
476
477   // Unblock all throttles for the component.
478   if (event == Observer::Events::COMPONENT_UPDATED ||
479       event == Observer::Events::COMPONENT_ALREADY_UP_TO_DATE ||
480       event == Observer::Events::COMPONENT_UPDATE_ERROR) {
481     auto callbacks = ready_callbacks_.equal_range(id);
482     for (auto it = callbacks.first; it != callbacks.second; ++it) {
483       std::move(it->second).Run();
484     }
485     ready_callbacks_.erase(id);
486   }
487
488   CrxUpdateItem update_item;
489   if (!update_client_->GetCrxUpdateState(id, &update_item))
490     return;
491
492   // Update the state of the item.
493   const auto state_it = component_states_.find(id);
494   if (state_it != component_states_.end())
495     state_it->second = update_item;
496
497   // Update the component registration with the new version.
498   if (event == Observer::Events::COMPONENT_UPDATED) {
499     const auto component_it = components_.find(id);
500     if (component_it != components_.end()) {
501       component_it->second.version = update_item.next_version;
502       component_it->second.fingerprint = update_item.next_fp;
503     }
504   }
505 }
506
507 ///////////////////////////////////////////////////////////////////////////////
508
509 // The component update factory. Using the component updater as a singleton
510 // is the job of the browser process.
511 std::unique_ptr<ComponentUpdateService> ComponentUpdateServiceFactory(
512     scoped_refptr<Configurator> config,
513     std::unique_ptr<UpdateScheduler> scheduler,
514     const std::string& brand) {
515   DCHECK(config);
516   DCHECK(scheduler);
517   auto update_client = update_client::UpdateClientFactory(config);
518   return std::make_unique<CrxUpdateService>(config, std::move(scheduler),
519                                             std::move(update_client), brand);
520 }
521
522 // Register prefs required by the component update service.
523 void RegisterComponentUpdateServicePrefs(PrefRegistrySimple* registry) {
524   // The component updates are enabled by default, if the preference is not set.
525   registry->RegisterBooleanPref(prefs::kComponentUpdatesEnabled, true);
526 }
527
528 }  // namespace component_updater