123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/soda/soda_installer_impl_chromeos.h"
- #include <string>
- #include "base/bind.h"
- #include "base/containers/contains.h"
- #include "base/feature_list.h"
- #include "base/metrics/histogram_functions.h"
- #include "base/numerics/safe_conversions.h"
- #include "chromeos/dbus/dlcservice/dlcservice.pb.h"
- #include "chromeos/dbus/dlcservice/dlcservice_client.h"
- #include "components/live_caption/pref_names.h"
- #include "components/prefs/pref_service.h"
- #include "components/soda/pref_names.h"
- #include "components/soda/soda_installer.h"
- #include "media/base/media_switches.h"
- #include "ui/base/l10n/l10n_util.h"
- namespace speech {
- namespace {
- constexpr char kSodaDlcName[] = "libsoda";
- constexpr char kSodaEnglishUsDlcName[] = "libsoda-model-en-us";
- SodaInstaller::ErrorCode DlcCodeToSodaErrorCode(const std::string& code) {
- return (code == dlcservice::kErrorNeedReboot)
- ? SodaInstaller::ErrorCode::kNeedsReboot
- : SodaInstaller::ErrorCode::kUnspecifiedError;
- }
- } // namespace
- SodaInstallerImplChromeOS::SodaInstallerImplChromeOS() = default;
- SodaInstallerImplChromeOS::~SodaInstallerImplChromeOS() = default;
- base::FilePath SodaInstallerImplChromeOS::GetSodaBinaryPath() const {
- return soda_lib_path_;
- }
- base::FilePath SodaInstallerImplChromeOS::GetLanguagePath(
- const std::string& language) const {
- // TODO(crbug.com/1161569): Support multiple languages. Currently only en-US
- // is supported.
- DCHECK_EQ(language, kUsEnglishLocale);
- return language_path_;
- }
- void SodaInstallerImplChromeOS::InstallSoda(PrefService* global_prefs) {
- if (never_download_soda_for_testing_)
- return;
- // Clear cached path in case this is a reinstallation (path could
- // change).
- SetSodaBinaryPath(base::FilePath());
- soda_binary_installed_ = false;
- is_soda_downloading_ = true;
- soda_progress_ = 0.0;
- // Install SODA DLC.
- dlcservice::InstallRequest install_request;
- install_request.set_id(kSodaDlcName);
- chromeos::DlcserviceClient::Get()->Install(
- install_request,
- base::BindOnce(&SodaInstallerImplChromeOS::OnSodaInstalled,
- base::Unretained(this), base::Time::Now()),
- base::BindRepeating(&SodaInstallerImplChromeOS::OnSodaProgress,
- base::Unretained(this)));
- }
- void SodaInstallerImplChromeOS::InstallLanguage(const std::string& language,
- PrefService* global_prefs) {
- if (never_download_soda_for_testing_)
- return;
- // TODO(crbug.com/1161569): SODA is only available for en-US right now.
- DCHECK_EQ(language, kUsEnglishLocale);
- SodaInstaller::RegisterLanguage(language, global_prefs);
- // Clear cached path in case this is a reinstallation (path could
- // change).
- SetLanguagePath(base::FilePath());
- // TODO(crbug.com/1055150): Compare user's language to a list of
- // supported languages and map it to a DLC ID. For now, default to
- // installing the SODA English-US DLC.
- DCHECK_EQ(language, kUsEnglishLocale);
- language_pack_progress_.insert({LanguageCode::kEnUs, 0.0});
- dlcservice::InstallRequest install_request;
- install_request.set_id(kSodaEnglishUsDlcName);
- chromeos::DlcserviceClient::Get()->Install(
- install_request,
- base::BindOnce(&SodaInstallerImplChromeOS::OnLanguageInstalled,
- base::Unretained(this), LanguageCode::kEnUs,
- base::Time::Now()),
- base::BindRepeating(&SodaInstallerImplChromeOS::OnLanguageProgress,
- base::Unretained(this)));
- }
- std::vector<std::string> SodaInstallerImplChromeOS::GetAvailableLanguages()
- const {
- // TODO(crbug.com/1161569): SODA is only available for English right now.
- // Update this to check available languages.
- return {kUsEnglishLocale};
- }
- void SodaInstallerImplChromeOS::UninstallSoda(PrefService* global_prefs) {
- soda_binary_installed_ = false;
- SetSodaBinaryPath(base::FilePath());
- chromeos::DlcserviceClient::Get()->Uninstall(
- kSodaDlcName, base::BindOnce(&SodaInstallerImplChromeOS::OnDlcUninstalled,
- base::Unretained(this), kSodaDlcName));
- installed_languages_.clear();
- language_pack_progress_.clear();
- SodaInstaller::UnregisterLanguages(global_prefs);
- SetLanguagePath(base::FilePath());
- chromeos::DlcserviceClient::Get()->Uninstall(
- kSodaEnglishUsDlcName,
- base::BindOnce(&SodaInstallerImplChromeOS::OnDlcUninstalled,
- base::Unretained(this), kSodaEnglishUsDlcName));
- global_prefs->SetTime(prefs::kSodaScheduledDeletionTime, base::Time());
- }
- void SodaInstallerImplChromeOS::SetSodaBinaryPath(base::FilePath new_path) {
- soda_lib_path_ = new_path;
- }
- void SodaInstallerImplChromeOS::SetLanguagePath(base::FilePath new_path) {
- language_path_ = new_path;
- }
- void SodaInstallerImplChromeOS::OnSodaInstalled(
- const base::Time start_time,
- const chromeos::DlcserviceClient::InstallResult& install_result) {
- is_soda_downloading_ = false;
- if (install_result.error == dlcservice::kErrorNone) {
- soda_binary_installed_ = true;
- SetSodaBinaryPath(base::FilePath(install_result.root_path));
- // TODO(crbug.com/1161569): SODA is only available for English right now.
- // Update this to notify on all installed languages.
- if (IsLanguageInstalled(LanguageCode::kEnUs))
- NotifyOnSodaInstalled(LanguageCode::kEnUs);
- base::UmaHistogramTimes(kSodaBinaryInstallationSuccessTimeTaken,
- base::Time::Now() - start_time);
- } else {
- soda_binary_installed_ = false;
- soda_progress_ = 0.0;
- NotifyOnSodaInstallError(LanguageCode::kNone,
- DlcCodeToSodaErrorCode(install_result.error));
- base::UmaHistogramTimes(kSodaBinaryInstallationFailureTimeTaken,
- base::Time::Now() - start_time);
- }
- base::UmaHistogramBoolean(kSodaBinaryInstallationResult,
- install_result.error == dlcservice::kErrorNone);
- }
- void SodaInstallerImplChromeOS::OnLanguageInstalled(
- const LanguageCode language_code,
- const base::Time start_time,
- const chromeos::DlcserviceClient::InstallResult& install_result) {
- language_pack_progress_.erase(language_code);
- if (install_result.error == dlcservice::kErrorNone) {
- installed_languages_.insert(language_code);
- SetLanguagePath(base::FilePath(install_result.root_path));
- if (soda_binary_installed_) {
- NotifyOnSodaInstalled(language_code);
- }
- base::UmaHistogramTimes(
- GetInstallationSuccessTimeMetricForLanguagePack(language_code),
- base::Time::Now() - start_time);
- } else {
- // TODO: Notify the observer of the specific language pack that failed
- // to install. ChromeOS currently only supports the en-US language pack.
- NotifyOnSodaInstallError(language_code,
- DlcCodeToSodaErrorCode(install_result.error));
- base::UmaHistogramTimes(
- GetInstallationFailureTimeMetricForLanguagePack(language_code),
- base::Time::Now() - start_time);
- }
- base::UmaHistogramBoolean(
- GetInstallationResultMetricForLanguagePack(language_code),
- install_result.error == dlcservice::kErrorNone);
- }
- void SodaInstallerImplChromeOS::OnSodaProgress(double progress) {
- soda_progress_ = progress;
- OnSodaCombinedProgress();
- }
- void SodaInstallerImplChromeOS::OnLanguageProgress(double progress) {
- language_pack_progress_[LanguageCode::kEnUs] = progress;
- OnSodaCombinedProgress();
- }
- void SodaInstallerImplChromeOS::OnSodaCombinedProgress() {
- // TODO(crbug.com/1055150): Consider updating this implementation.
- // e.g.: (1) starting progress from 0% if we are downloading language
- // only (2) weighting download progress proportionally to DLC binary size.
- double language_progress = 0.0;
- if (base::Contains(language_pack_progress_, LanguageCode::kEnUs))
- language_progress = language_pack_progress_[LanguageCode::kEnUs];
- const double progress = (soda_progress_ + language_progress) / 2;
- // TODO: Notify the observer of the specific language pack that is currently
- // being installed. ChromeOS currently only supports the en-US language pack.
- NotifyOnSodaProgress(LanguageCode::kEnUs, base::ClampFloor(100 * progress));
- }
- void SodaInstallerImplChromeOS::OnDlcUninstalled(const std::string& dlc_id,
- const std::string& err) {
- if (err != dlcservice::kErrorNone) {
- LOG(ERROR) << "Failed to uninstall DLC " << dlc_id << ". Error: " << err;
- }
- }
- } // namespace speech
|