Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(555)

Side by Side Diff: chrome/browser/component_updater/cros_component_installer.cc

Issue 2707063002: Universial component install for chrome os. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/cros_component_installer.h"
6
7 using content::BrowserThread;
8 using content::PluginService;
9
10 namespace component_updater {
11
12 #if defined(OS_CHROMEOS)
13 // CRX hash for Chrome OS.
14 // appid: iibmmgakkjjfeplohmmninjahpefocna
15 const uint8_t kSha2Hash[] = {0x88, 0x1c, 0xc6, 0x0a, 0xa9, 0x95, 0x4f, 0xbe,
16 0x7c, 0xcd, 0x8d, 0x90, 0x7f, 0x45, 0xe2, 0xd0,
17 0xe6, 0x30, 0x8c, 0x37, 0x7d, 0x4e, 0x61, 0x8b,
18 0xe7, 0x08, 0xe6, 0x93, 0x2d, 0x13, 0x5d, 0x8a};
waffles 2017/02/21 21:16:04 Delete these lines.
xiaochu 2017/02/21 21:39:40 Done.
19 #else
20 #endif // defined(OS_CHROMEOS)
21
22 #if defined(OS_CHROMEOS)
23 void LogRegistrationResult(chromeos::DBusMethodCallStatus call_status,
24 bool result) {
25 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
26 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
27 LOG(ERROR) << "Call to imageloader service failed.";
28 return;
29 }
30 if (!result) {
31 LOG(ERROR) << "Component registration failed";
32 return;
33 }
34 }
35 void ImageLoaderRegistration(const std::string& version,
36 const base::FilePath& install_dir,
37 const std::string& name) {
38 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
39 chromeos::ImageLoaderClient* loader =
40 chromeos::DBusThreadManager::Get()->GetImageLoaderClient();
41
42 if (loader) {
43 loader->RegisterComponent(name, version, install_dir.value(),
44 base::Bind(&LogRegistrationResult));
45 } else {
46 LOG(ERROR) << "Failed to get ImageLoaderClient object.";
47 }
48 }
49
50 // Determine whether or not to skip registering this cros component updates.
51 bool SkipCupsRegistration(ComponentUpdateService* cus) {
52 return false;
53 }
54 #endif // defined(OS_CHROMEOS)
55
56 CrOSComponentInstallerTraits::CrOSComponentInstallerTraits(
57 std::string dir_name,
58 std::string name,
59 std::string sha2HashStr)
60 : dir_name(dir_name), name(name) {
61 if (sha2HashStr.length() != 64)
62 return;
63 for (unsigned int i = 0; i < sizeof(kSha2Hash_); i++) {
64 kSha2Hash_[i] = stoul(sha2HashStr.substr(i * 2, 2), nullptr, 16);
65 }
66 }
67
68 bool CrOSComponentInstallerTraits::SupportsGroupPolicyEnabledComponentUpdates()
69 const {
70 return true;
71 }
72
73 bool CrOSComponentInstallerTraits::RequiresNetworkEncryption() const {
74 return false;
75 }
76
77 update_client::CrxInstaller::Result
78 CrOSComponentInstallerTraits::OnCustomInstall(
79 const base::DictionaryValue& manifest,
80 const base::FilePath& install_dir) {
81 #if defined(OS_CHROMEOS)
82 std::string version;
83 if (!manifest.GetString("version", &version)) {
84 return ToInstallerResult(update_client::InstallError::GENERIC_ERROR);
85 }
86 BrowserThread::PostTask(
87 BrowserThread::UI, FROM_HERE,
88 base::Bind(&ImageLoaderRegistration, version, install_dir, name));
89 return update_client::CrxInstaller::Result(update_client::InstallError::NONE);
90 #else
91 return ToInstallerResult(update_client::InstallError::GENERIC_ERROR);
92 #endif // defined(OS_LINUX)
waffles 2017/02/21 21:16:04 OS_LINUX → OS_CHROMEOS
xiaochu 2017/02/21 21:39:39 Done.
93 }
94
95 void CrOSComponentInstallerTraits::ComponentReady(
96 const base::Version& version,
97 const base::FilePath& path,
98 std::unique_ptr<base::DictionaryValue> manifest) {}
99
100 bool CrOSComponentInstallerTraits::VerifyInstallation(
101 const base::DictionaryValue& manifest,
102 const base::FilePath& install_dir) const {
103 // TODO: verify installation.
waffles 2017/02/21 21:16:03 What does verifying the installation look like?
waffles 2017/02/21 21:39:25 Maybe I should be more clear: if there isn't a con
xiaochu 2017/02/21 21:39:40 For adobe flash, it checks the content of the mani
104 return true;
105 }
106
107 base::FilePath CrOSComponentInstallerTraits::GetRelativeInstallDir() const {
108 return base::FilePath(FILE_PATH_LITERAL(dir_name));
109 }
110
111 void CrOSComponentInstallerTraits::GetHash(std::vector<uint8_t>* hash) const {
112 hash->assign(kSha2Hash_, kSha2Hash_ + arraysize(kSha2Hash_));
113 }
114
115 std::string CrOSComponentInstallerTraits::GetName() const {
116 return name;
117 }
118
119 update_client::InstallerAttributes
120 CrOSComponentInstallerTraits::GetInstallerAttributes() const {
121 return update_client::InstallerAttributes();
122 }
123
124 std::vector<std::string> CrOSComponentInstallerTraits::GetMimeTypes() const {
125 std::vector<std::string> mime_types;
126 return mime_types;
127 }
128
129 void ConfigParser::XmlErrorFunc(void* context, const char* message, ...) {
130 va_list args;
131 va_start(args, message);
132 std::string* error = static_cast<std::string*>(context);
133 base::StringAppendV(error, message, args);
134 va_end(args);
135 }
136 bool ConfigParser::TagNameEquals(const xmlNode* node,
137 const char* expected_name) {
138 return 0 == strcmp(expected_name, reinterpret_cast<const char*>(node->name));
139 }
140 std::unique_ptr<std::string> ConfigParser::GetAttributePtr(
141 xmlNode* node,
142 const char* attribute_name) {
143 const xmlChar* name = reinterpret_cast<const xmlChar*>(attribute_name);
144 for (xmlAttr* attr = node->properties; attr != NULL; attr = attr->next) {
145 if (!xmlStrcmp(attr->name, name) && attr->children &&
146 attr->children->content) {
147 return base::MakeUnique<std::string>(
148 reinterpret_cast<const char*>(attr->children->content));
149 }
150 }
151 return nullptr;
152 }
153 void ConfigParser::ParseError(const char* details, ...) {
154 va_list args;
155 va_start(args, details);
156
157 if (!errors_.empty()) {
158 errors_ += "\r\n";
159 }
160
161 base::StringAppendV(&errors_, details, args);
162 va_end(args);
163 }
164
165 bool ConfigParser::IsValidSha256(const std::string& sha2hashstr) {
166 for (unsigned long i = 0; i < sha2hashstr.size(); i++) {
167 char c = sha2hashstr.at(i);
168 if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
169 (c >= 'A' && c <= 'F'))) {
170 return false;
171 }
172 }
173 return true;
174 }
175
176 bool ConfigParser::ParseComponentTag(xmlNode* component,
177 Result* result,
178 std::string* error) {
179 auto name = GetAttributePtr(component, "name");
180 auto dir_name = GetAttributePtr(component, "dir_name");
181 auto sha2hashstr = GetAttributePtr(component, "sha2hashstr");
182 // empty attibute is not allowed.
183 if (name == nullptr || dir_name == nullptr || sha2hashstr == nullptr ||
184 dir_name->size() == 0 || name->size() == 0 || sha2hashstr->size() == 0)
185 return false;
186 // invalid sha2hashstr is not allowed.
187 if (sha2hashstr->size() != 64) {
188 return false;
189 }
190 if (!IsValidSha256(*sha2hashstr)) {
191 return false;
192 }
193 result->name = *name;
194 result->dir_name = *dir_name;
195 result->sha2hashstr = *sha2hashstr;
196 return true;
197 }
198
199 std::vector<xmlNode*> ConfigParser::GetChildren(xmlNode* root,
200 const char* name) {
201 std::vector<xmlNode*> result;
202 for (xmlNode* child = root->children; child != NULL; child = child->next) {
203 if (!TagNameEquals(child, name)) {
204 continue;
205 }
206 result.push_back(child);
207 }
208 return result;
209 }
210
211 bool ConfigParser::Parse(std::string config_xml, std::vector<Result>& results) {
212 if (config_xml.length() < 1) {
213 ParseError("Empty config_xml");
214 return false;
215 }
216
217 std::string xml_errors;
218 ScopedXmlErrorFunc error_func(&xml_errors, &XmlErrorFunc);
219
220 ScopedXmlDocument document(
221 xmlParseDoc(reinterpret_cast<const xmlChar*>(config_xml.c_str())));
222 if (!document.get()) {
223 ParseError("%s", xml_errors.c_str());
224 return false;
225 }
226 xmlNode* root = xmlDocGetRootElement(document.get());
227 if (!root) {
228 ParseError("Missing root node");
229 return false;
230 }
231 if (!TagNameEquals(root, "components")) {
232 ParseError("Missing components tag");
233 return false;
234 }
235 std::vector<xmlNode*> components = GetChildren(root, "component");
236 for (size_t i = 0; i != components.size(); ++i) {
237 Result result;
238 std::string error;
239 if (ParseComponentTag(components[i], &result, &error)) {
240 results.push_back(result);
241 } else {
242 results.clear();
243 ParseError("%s", error.c_str());
244 return false;
245 }
246 }
247 return true;
248 }
249
250 void RegisterCrOSComponent(ComponentUpdateService* cus,
251 ConfigParser::Result& result) {
252 std::unique_ptr<ComponentInstallerTraits> traits(
253 new CrOSComponentInstallerTraits(result.dir_name, result.name,
254 result.sha2hashstr));
255 // |cus| will take ownership of |installer| during
256 // installer->Register(cus).
257 DefaultComponentInstaller* installer =
258 new DefaultComponentInstaller(std::move(traits));
259 installer->Register(cus, base::Closure());
260 }
261
262 bool RegisterCrOSComponent(ComponentUpdateService* cus, std::string name) {
263 #if defined(OS_CHROMEOS)
264 base::FilePath configFilePath("/var/lib/imageloader/cros_dc.config");
265 #else
266 base::FilePath configFilePath("/tmp/cros_dc.config");
267 #endif // OS_CHROMEOS
268 std::string contents;
269 if (base::ReadFileToString(configFilePath, &contents)) {
270 VLOG(1) << "[RegisterCrOSComponents] configuration loaded:" << contents;
271 ConfigParser parser;
272 std::vector<ConfigParser::Result> results;
273 if (parser.Parse(contents, results)) {
274 VLOG(1) << "[RegisterCrOSComponents] xml parse succeeded";
275 for (auto result : results) {
276 if (name.compare(result.name)) {
277 RegisterCrOSComponent(cus, result);
278 return true;
279 }
280 }
281 } else {
282 VLOG(0) << "[RegisterCrOSComponents] xml parse failed";
283 }
284 } else {
285 VLOG(0) << "[RegisterCrOSComponents] configuration not exist.";
286 }
287 return false;
288 }
289
290 bool InstallCrOSComponent(std::string name) {
291 const auto cus = g_browser_process->component_updater();
292 if (RegisterCrOSComponent(cus, name)) {
293 // component registered successfully.
294 // you can wait until component_updater automatically install later;
295 // or you can trigger an on-demand install right-away.
296 // notes: non-block install is suggested; since it gives flexibility to API
297 // callers. API callers can schedule other activities while polling isReady
298 // to learn install progress.
299 // e.g: cus->GetOnDemandUpdater().OnDemandUpdater("");
300 return true;
301 } else {
302 return false;
303 }
304 }
305
306 bool IsReadyCrOSComponent(std::string name) {
307 return false;
308 }
309
310 } // namespace component_updater
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698