blob: 23f1671ca3396bf6d70396d48563b695a40e9c95 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/component_updater/soda_language_pack_component_installer.h"
#include <iterator>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/component_updater/soda_component_installer.h"
#include "components/component_updater/component_updater_service.h"
#include "components/crx_file/id_util.h"
#include "components/prefs/pref_service.h"
#include "components/soda/constants.h"
#include "components/update_client/update_client_errors.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace component_updater {
namespace {
constexpr char kLanguagePackManifestName[] = "SODA %s Models";
} // namespace
SodaLanguagePackComponentInstallerPolicy::
SodaLanguagePackComponentInstallerPolicy(
speech::SodaLanguagePackComponentConfig language_config,
OnSodaLanguagePackComponentReadyCallback on_ready_callback)
: language_config_(language_config),
on_ready_callback_(std::move(on_ready_callback)) {}
SodaLanguagePackComponentInstallerPolicy::
~SodaLanguagePackComponentInstallerPolicy() = default;
std::string SodaLanguagePackComponentInstallerPolicy::GetExtensionId(
speech::LanguageCode language_code) {
std::optional<speech::SodaLanguagePackComponentConfig> config =
speech::GetLanguageComponentConfig(language_code);
if (config) {
return crx_file::id_util::GenerateIdFromHash(config.value().public_key_sha);
}
return std::string();
}
base::flat_set<std::string>
SodaLanguagePackComponentInstallerPolicy::GetExtensionIds() {
base::flat_set<std::string> ids;
for (const speech::SodaLanguagePackComponentConfig& config :
speech::kLanguageComponentConfigs) {
ids.insert(crx_file::id_util::GenerateIdFromHash(config.public_key_sha));
}
return ids;
}
void SodaLanguagePackComponentInstallerPolicy::
UpdateSodaLanguagePackComponentOnDemand(
speech::LanguageCode language_code) {
const std::string crx_id =
SodaLanguagePackComponentInstallerPolicy::GetExtensionId(language_code);
g_browser_process->component_updater()->GetOnDemandUpdater().OnDemandUpdate(
crx_id, OnDemandUpdater::Priority::FOREGROUND,
base::BindOnce([](update_client::Error error) {
if (error != update_client::Error::NONE &&
error != update_client::Error::UPDATE_IN_PROGRESS) {
LOG(ERROR)
<< "On demand update of the SODA language component failed "
"with error: "
<< static_cast<int>(error);
}
}));
}
bool SodaLanguagePackComponentInstallerPolicy::VerifyInstallation(
const base::Value::Dict& manifest,
const base::FilePath& install_dir) const {
return base::PathExists(
install_dir.Append(speech::kSodaLanguagePackDirectoryRelativePath));
}
bool SodaLanguagePackComponentInstallerPolicy::
SupportsGroupPolicyEnabledComponentUpdates() const {
return true;
}
bool SodaLanguagePackComponentInstallerPolicy::RequiresNetworkEncryption()
const {
return true;
}
update_client::CrxInstaller::Result
SodaLanguagePackComponentInstallerPolicy::OnCustomInstall(
const base::Value::Dict& manifest,
const base::FilePath& install_dir) {
return SodaComponentInstallerPolicy::SetComponentDirectoryPermission(
install_dir);
}
void SodaLanguagePackComponentInstallerPolicy::OnCustomUninstall() {}
void SodaLanguagePackComponentInstallerPolicy::ComponentReady(
const base::Version& version,
const base::FilePath& install_dir,
base::Value::Dict manifest) {
VLOG(1) << "Component ready, version " << version.GetString() << " in "
<< install_dir.value();
#if !BUILDFLAG(IS_ANDROID)
// The component updater may post ready tasks during shutdown. Confirm that the
// `BrowserProcess` is still valid before setting the pref.
if (g_browser_process) {
g_browser_process->local_state()->SetFilePath(
language_config_.config_path_pref,
install_dir.Append(speech::kSodaLanguagePackDirectoryRelativePath));
}
#endif //! BUILDFLAG(IS_ANDROID)
if (on_ready_callback_) {
std::move(on_ready_callback_).Run(language_config_.language_code);
}
}
base::FilePath SodaLanguagePackComponentInstallerPolicy::GetRelativeInstallDir()
const {
return base::FilePath(speech::kSodaLanguagePacksRelativePath)
.AppendASCII(language_config_.language_name);
}
void SodaLanguagePackComponentInstallerPolicy::GetHash(
std::vector<uint8_t>* hash) const {
hash->assign(std::begin(language_config_.public_key_sha),
std::end(language_config_.public_key_sha));
}
std::string SodaLanguagePackComponentInstallerPolicy::GetName() const {
return base::StringPrintf(kLanguagePackManifestName,
language_config_.language_name);
}
update_client::InstallerAttributes
SodaLanguagePackComponentInstallerPolicy::GetInstallerAttributes() const {
return update_client::InstallerAttributes();
}
void RegisterSodaLanguagePackComponent(
speech::SodaLanguagePackComponentConfig language_config,
ComponentUpdateService* cus,
OnSodaLanguagePackComponentReadyCallback on_ready_callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auto installer = base::MakeRefCounted<ComponentInstaller>(
std::make_unique<SodaLanguagePackComponentInstallerPolicy>(
language_config, std::move(on_ready_callback)));
installer->Register(
cus, base::BindOnce(&SodaLanguagePackComponentInstallerPolicy::
UpdateSodaLanguagePackComponentOnDemand,
language_config.language_code));
}
} // namespace component_updater