chromium/android_webview/nonembedded/component_updater/aw_component_updater_configurator.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/nonembedded/component_updater/aw_component_updater_configurator.h"

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "android_webview/nonembedded/net/network_impl.h"
#include "base/android/path_utils.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/version.h"
#include "components/component_updater/component_updater_command_line_config_policy.h"
#include "components/component_updater/configurator_impl.h"
#include "components/prefs/pref_service.h"
#include "components/update_client/crx_downloader_factory.h"
#include "components/update_client/network.h"
#include "components/update_client/patch/in_process_patcher.h"
#include "components/update_client/patcher.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/protocol_handler.h"
#include "components/update_client/unzip/in_process_unzipper.h"
#include "components/update_client/unzipper.h"
#include "components/update_client/update_query_params.h"
#include "components/version_info/android/channel_getter.h"
#include "components/version_info/version_info.h"
#include "components/version_info/version_info_values.h"

namespace android_webview {

AwComponentUpdaterConfigurator::AwComponentUpdaterConfigurator(
    const base::CommandLine* cmdline,
    PrefService* pref_service)
    : configurator_impl_(
          component_updater::ComponentUpdaterCommandLineConfigPolicy(cmdline),
          false),
      pref_service_(pref_service),
      persisted_data_(
          update_client::CreatePersistedData(pref_service, nullptr)) {}

AwComponentUpdaterConfigurator::~AwComponentUpdaterConfigurator() = default;

base::TimeDelta AwComponentUpdaterConfigurator::InitialDelay() const {
  // Initial delay acts as a "registration window" for components, so we should
  // have a reasonable window to allow for all components to complete
  // registration. We are choosing a small window of 10 seconds here because
  // WebView has a short list of components and components registration happens
  // in an android background service so we want to start the update as soon as
  // possible.
  // TODO(crbug.com/40750670): get rid of dependency in initial delay for
  // WebView.
  return base::Seconds(10);
}

base::TimeDelta AwComponentUpdaterConfigurator::NextCheckDelay() const {
  return configurator_impl_.NextCheckDelay();
}

base::TimeDelta AwComponentUpdaterConfigurator::OnDemandDelay() const {
  return configurator_impl_.OnDemandDelay();
}

base::TimeDelta AwComponentUpdaterConfigurator::UpdateDelay() const {
  // No need to have any delays between components updates. In WebView this
  // doesn't run in a browser and shouldn't affect user's experience.
  // Furthermore, this will be a background service that is scheduled by
  // JobScheduler, so we want to do as much work in as little time as possible.
  // However, if we ever invoked installation on-demand, we should be less
  // aggressive here.
  return base::Seconds(0);
}

std::vector<GURL> AwComponentUpdaterConfigurator::UpdateUrl() const {
  return configurator_impl_.UpdateUrl();
}

std::vector<GURL> AwComponentUpdaterConfigurator::PingUrl() const {
  return configurator_impl_.PingUrl();
}

std::string AwComponentUpdaterConfigurator::GetProdId() const {
  return update_client::UpdateQueryParams::GetProdIdString(
      update_client::UpdateQueryParams::ProdId::WEBVIEW);
}

base::Version AwComponentUpdaterConfigurator::GetBrowserVersion() const {
  return configurator_impl_.GetBrowserVersion();
}

std::string AwComponentUpdaterConfigurator::GetChannel() const {
  return std::string(
      version_info::GetChannelString(version_info::android::GetChannel()));
}

std::string AwComponentUpdaterConfigurator::GetLang() const {
  // WebView uses the locale of the embedding app. Components are shared with
  // WebView instances across apps so we don't set a locale.
  return std::string();
}

std::string AwComponentUpdaterConfigurator::GetOSLongName() const {
  return configurator_impl_.GetOSLongName();
}

base::flat_map<std::string, std::string>
AwComponentUpdaterConfigurator::ExtraRequestParams() const {
  return configurator_impl_.ExtraRequestParams();
}

std::string AwComponentUpdaterConfigurator::GetDownloadPreference() const {
  // Hints for the server about caching URLs, "" means let the server decide the
  // best URLs to return according to its policies.
  return configurator_impl_.GetDownloadPreference();
}

scoped_refptr<update_client::NetworkFetcherFactory>
AwComponentUpdaterConfigurator::GetNetworkFetcherFactory() {
  if (!network_fetcher_factory_) {
    network_fetcher_factory_ =
        base::MakeRefCounted<NetworkFetcherFactoryImpl>();
  }
  return network_fetcher_factory_;
}

scoped_refptr<update_client::CrxDownloaderFactory>
AwComponentUpdaterConfigurator::GetCrxDownloaderFactory() {
  if (!crx_downloader_factory_) {
    crx_downloader_factory_ =
        update_client::MakeCrxDownloaderFactory(GetNetworkFetcherFactory());
  }
  return crx_downloader_factory_;
}

scoped_refptr<update_client::UnzipperFactory>
AwComponentUpdaterConfigurator::GetUnzipperFactory() {
  if (!unzip_factory_) {
    unzip_factory_ =
        base::MakeRefCounted<update_client::InProcessUnzipperFactory>();
  }
  return unzip_factory_;
}

scoped_refptr<update_client::PatcherFactory>
AwComponentUpdaterConfigurator::GetPatcherFactory() {
  if (!patch_factory_) {
    patch_factory_ =
        base::MakeRefCounted<update_client::InProcessPatcherFactory>();
  }
  return patch_factory_;
}

bool AwComponentUpdaterConfigurator::EnabledDeltas() const {
  return configurator_impl_.EnabledDeltas();
}

bool AwComponentUpdaterConfigurator::EnabledBackgroundDownloader() const {
  return configurator_impl_.EnabledBackgroundDownloader();
}

bool AwComponentUpdaterConfigurator::EnabledCupSigning() const {
  return configurator_impl_.EnabledCupSigning();
}

PrefService* AwComponentUpdaterConfigurator::GetPrefService() const {
  return pref_service_;
}

update_client::PersistedData* AwComponentUpdaterConfigurator::GetPersistedData()
    const {
  return persisted_data_.get();
}

bool AwComponentUpdaterConfigurator::IsPerUserInstall() const {
  return true;
}

std::unique_ptr<update_client::ProtocolHandlerFactory>
AwComponentUpdaterConfigurator::GetProtocolHandlerFactory() const {
  return configurator_impl_.GetProtocolHandlerFactory();
}

std::optional<bool> AwComponentUpdaterConfigurator::IsMachineExternallyManaged()
    const {
  return std::nullopt;
}

update_client::UpdaterStateProvider
AwComponentUpdaterConfigurator::GetUpdaterStateProvider() const {
  return configurator_impl_.GetUpdaterStateProvider();
}

scoped_refptr<update_client::Configurator> MakeAwComponentUpdaterConfigurator(
    const base::CommandLine* cmdline,
    PrefService* pref_service) {
  return base::MakeRefCounted<AwComponentUpdaterConfigurator>(cmdline,
                                                              pref_service);
}

std::optional<base::FilePath> AwComponentUpdaterConfigurator::GetCrxCachePath()
    const {
  base::FilePath path;
  return base::android::GetCacheDirectory(&path)
             ? std::optional<base::FilePath>(
                   path.AppendASCII(("webview_crx_cache")))
             : std::nullopt;
}

bool AwComponentUpdaterConfigurator::IsConnectionMetered() const {
  return configurator_impl_.IsConnectionMetered();
}

}  // namespace android_webview