1 // Copyright 2020 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.
4
5 #include "chrome/browser/component_updater/soda_ja_jp_component_installer.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "build/build_config.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/component_updater/soda_component_installer.h"
12 #include "chrome/common/pref_names.h"
13 #include "components/component_updater/component_updater_service.h"
14 #include "components/crx_file/id_util.h"
15 #include "components/soda/constants.h"
16 #include "components/update_client/update_client_errors.h"
17 #include "content/public/browser/browser_task_traits.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "crypto/sha2.h"
20 #include "media/base/media_switches.h"
21
22 using content::BrowserThread;
23
24 namespace component_updater {
25
26 namespace {
27
28 // The SHA256 of the SubjectPublicKeyInfo used to sign the component.
29 // The component id is: onhpjgkfgajmkkeniaoflicgokpaebfa
30 constexpr uint8_t kSodaJaJpPublicKeySHA256[32] = {
31 0xed, 0x7f, 0x96, 0xa5, 0x60, 0x9c, 0xaa, 0x4d, 0x80, 0xe5, 0xb8,
32 0x26, 0xea, 0xf0, 0x41, 0x50, 0x09, 0x52, 0xa4, 0xb3, 0x1e, 0x6a,
33 0x8e, 0x24, 0x99, 0xde, 0x51, 0x14, 0xc4, 0x3c, 0xfa, 0x48};
34
35 static_assert(base::size(kSodaJaJpPublicKeySHA256) == crypto::kSHA256Length,
36 "Wrong hash length");
37
38 constexpr char kSodaJaJpManifestName[] = "SODA ja-JP Models";
39
40 } // namespace
41
SodaJaJpComponentInstallerPolicy(OnSodaJaJpComponentReadyCallback callback)42 SodaJaJpComponentInstallerPolicy::SodaJaJpComponentInstallerPolicy(
43 OnSodaJaJpComponentReadyCallback callback)
44 : on_component_ready_callback_(callback) {}
45
46 SodaJaJpComponentInstallerPolicy::~SodaJaJpComponentInstallerPolicy() = default;
47
GetExtensionId()48 const std::string SodaJaJpComponentInstallerPolicy::GetExtensionId() {
49 return crx_file::id_util::GenerateIdFromHash(
50 kSodaJaJpPublicKeySHA256, sizeof(kSodaJaJpPublicKeySHA256));
51 }
52
UpdateSodaJaJpComponentOnDemand()53 void SodaJaJpComponentInstallerPolicy::UpdateSodaJaJpComponentOnDemand() {
54 const std::string crx_id =
55 component_updater::SodaJaJpComponentInstallerPolicy::GetExtensionId();
56 g_browser_process->component_updater()->GetOnDemandUpdater().OnDemandUpdate(
57 crx_id, component_updater::OnDemandUpdater::Priority::FOREGROUND,
58 base::BindOnce([](update_client::Error error) {
59 if (error != update_client::Error::NONE &&
60 error != update_client::Error::UPDATE_IN_PROGRESS)
61 LOG(ERROR) << "On demand update of the SODA ja-JP component failed "
62 "with error: "
63 << static_cast<int>(error);
64 }));
65 }
66
VerifyInstallation(const base::DictionaryValue & manifest,const base::FilePath & install_dir) const67 bool SodaJaJpComponentInstallerPolicy::VerifyInstallation(
68 const base::DictionaryValue& manifest,
69 const base::FilePath& install_dir) const {
70 return base::PathExists(
71 install_dir.Append(speech::kSodaLanguagePackDirectoryRelativePath));
72 }
73
74 bool SodaJaJpComponentInstallerPolicy::
SupportsGroupPolicyEnabledComponentUpdates() const75 SupportsGroupPolicyEnabledComponentUpdates() const {
76 return true;
77 }
78
RequiresNetworkEncryption() const79 bool SodaJaJpComponentInstallerPolicy::RequiresNetworkEncryption() const {
80 return true;
81 }
82
83 update_client::CrxInstaller::Result
OnCustomInstall(const base::DictionaryValue & manifest,const base::FilePath & install_dir)84 SodaJaJpComponentInstallerPolicy::OnCustomInstall(
85 const base::DictionaryValue& manifest,
86 const base::FilePath& install_dir) {
87 return SODAComponentInstallerPolicy::SetComponentDirectoryPermission(
88 install_dir);
89 }
90
OnCustomUninstall()91 void SodaJaJpComponentInstallerPolicy::OnCustomUninstall() {}
92
ComponentReady(const base::Version & version,const base::FilePath & install_dir,std::unique_ptr<base::DictionaryValue> manifest)93 void SodaJaJpComponentInstallerPolicy::ComponentReady(
94 const base::Version& version,
95 const base::FilePath& install_dir,
96 std::unique_ptr<base::DictionaryValue> manifest) {
97 VLOG(1) << "Component ready, version " << version.GetString() << " in "
98 << install_dir.value();
99
100 on_component_ready_callback_.Run(install_dir);
101 }
102
GetRelativeInstallDir() const103 base::FilePath SodaJaJpComponentInstallerPolicy::GetRelativeInstallDir() const {
104 return base::FilePath(speech::kSodaJaJpInstallationRelativePath);
105 }
106
GetHash(std::vector<uint8_t> * hash) const107 void SodaJaJpComponentInstallerPolicy::GetHash(
108 std::vector<uint8_t>* hash) const {
109 hash->assign(kSodaJaJpPublicKeySHA256,
110 kSodaJaJpPublicKeySHA256 + base::size(kSodaJaJpPublicKeySHA256));
111 }
112
GetName() const113 std::string SodaJaJpComponentInstallerPolicy::GetName() const {
114 return kSodaJaJpManifestName;
115 }
116
117 update_client::InstallerAttributes
GetInstallerAttributes() const118 SodaJaJpComponentInstallerPolicy::GetInstallerAttributes() const {
119 return update_client::InstallerAttributes();
120 }
121
GetMimeTypes() const122 std::vector<std::string> SodaJaJpComponentInstallerPolicy::GetMimeTypes()
123 const {
124 return std::vector<std::string>();
125 }
126
UpdateSodaJaJpInstallDirPref(PrefService * prefs,const base::FilePath & install_dir)127 void UpdateSodaJaJpInstallDirPref(PrefService* prefs,
128 const base::FilePath& install_dir) {
129 #if !defined(OS_ANDROID)
130 prefs->SetFilePath(
131 prefs::kSodaJaJpConfigPath,
132 install_dir.Append(speech::kSodaLanguagePackDirectoryRelativePath));
133 #endif
134 }
135
RegisterSodaJaJpComponent(ComponentUpdateService * cus,PrefService * prefs,base::OnceClosure callback)136 void RegisterSodaJaJpComponent(ComponentUpdateService* cus,
137 PrefService* prefs,
138 base::OnceClosure callback) {
139 DCHECK_CURRENTLY_ON(BrowserThread::UI);
140 auto installer = base::MakeRefCounted<ComponentInstaller>(
141 std::make_unique<SodaJaJpComponentInstallerPolicy>(base::BindRepeating(
142 [](ComponentUpdateService* cus, PrefService* prefs,
143 const base::FilePath& install_dir) {
144 content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
145 ->PostTask(FROM_HERE,
146 base::BindOnce(&UpdateSodaJaJpInstallDirPref,
147 prefs, install_dir));
148 },
149 cus, prefs)));
150
151 installer->Register(cus, std::move(callback));
152 }
153
154 } // namespace component_updater
155