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

Side by Side Diff: chrome/browser/component_updater/pnacl/pnacl_component_installer.cc

Issue 12184029: Make pnacl install on demand when it is not already installed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: forward decl Created 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" 5 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
6 6
7 #include <list>
8
7 #include "base/base_paths.h" 9 #include "base/base_paths.h"
8 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback.h"
9 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
10 #include "base/file_path.h" 13 #include "base/file_path.h"
11 #include "base/file_util.h" 14 #include "base/file_util.h"
12 #include "base/json/json_file_value_serializer.h" 15 #include "base/json/json_file_value_serializer.h"
13 #include "base/logging.h" 16 #include "base/logging.h"
14 #include "base/path_service.h" 17 #include "base/path_service.h"
15 #include "base/string_util.h" 18 #include "base/string_util.h"
16 #include "base/values.h" 19 #include "base/values.h"
17 #include "base/version.h" 20 #include "base/version.h"
18 #include "base/win/windows_version.h" 21 #include "base/win/windows_version.h"
19 #include "build/build_config.h" 22 #include "build/build_config.h"
20 #include "chrome/browser/component_updater/component_updater_service.h" 23 #include "chrome/browser/component_updater/component_updater_service.h"
21 #include "chrome/common/chrome_paths.h" 24 #include "chrome/common/chrome_paths.h"
22 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
23 26
24 using content::BrowserThread; 27 using content::BrowserThread;
25 28
26 namespace { 29 namespace {
27 30
28 // If PNaCl isn't installed yet, but a user is running chrome with 31 // Time in seconds to wait for CheckUpdatesForPnacl to complete
29 // --enable-pnacl, this is the amount of time to wait before starting 32 // before considering the update failed.
30 // a background install. 33 int kPnaclInstallerTimeout = 45;
31 const int kInitialDelaySeconds = 10;
32 34
33 // One of the Pnacl component files, for checking that expected files exist. 35 // One of the Pnacl component files, for checking that expected files exist.
34 // TODO(jvoung): perhaps replace this with a list of the expected files in the 36 // TODO(jvoung): perhaps replace this with a list of the expected files in the
35 // manifest.json. Use that to check that everything is unpacked. 37 // manifest.json. Use that to check that everything is unpacked.
36 // However, that would make startup detection even slower (need to check for 38 // However, that would make startup detection even slower (need to check for
37 // more than one file!). 39 // more than one file!).
38 const char kPnaclCompilerFileName[] = "llc_nexe"; 40 const char kPnaclCompilerFileName[] = "llc_nexe";
39 41
40 // Name of the Pnacl component specified in the manifest. 42 // Name of the Pnacl component specified in the manifest.
41 const char kPnaclManifestNamePrefix[] = "PNaCl"; 43 const char kPnaclManifestNamePrefix[] = "PNaCl";
(...skipping 23 matching lines...) Expand all
65 // Sanitize characters given by PnaclArch so that they can be used 67 // Sanitize characters given by PnaclArch so that they can be used
66 // in path names. This should only be characters in the set: [a-z0-9_]. 68 // in path names. This should only be characters in the set: [a-z0-9_].
67 // Keep in sync with chrome/browser/nacl_host/pnacl_file_host. 69 // Keep in sync with chrome/browser/nacl_host/pnacl_file_host.
68 std::string SanitizeForPath(const std::string& input) { 70 std::string SanitizeForPath(const std::string& input) {
69 std::string result; 71 std::string result;
70 ReplaceChars(input, "-", "_", &result); 72 ReplaceChars(input, "-", "_", &result);
71 return result; 73 return result;
72 } 74 }
73 75
74 // Set the component's hash to the arch-specific PNaCl package. 76 // Set the component's hash to the arch-specific PNaCl package.
75 void SetPnaclHash(CrxComponent* component) { 77 void SetPnaclHash(std::vector<uint8>* pk_hash) {
76 #if defined(ARCH_CPU_X86_FAMILY) 78 #if defined(ARCH_CPU_X86_FAMILY)
77 // Define both x86_32 and x86_64, and choose below. 79 // Define both x86_32 and x86_64, and choose below.
78 static const uint8 x86_sha256_hash[][32] = { 80 static const uint8 x86_sha256_hash[][32] = {
79 { // This corresponds to AppID (x86-32): aealhdcgieaiikaifafholmmeooeeioj 81 { // This corresponds to AppID (x86-32): aealhdcgieaiikaifafholmmeooeeioj
80 0x04, 0x0b, 0x73, 0x26, 0x84, 0x08, 0x8a, 0x08, 0x50, 0x57, 82 0x04, 0x0b, 0x73, 0x26, 0x84, 0x08, 0x8a, 0x08, 0x50, 0x57,
81 0xeb, 0xcc, 0x4e, 0xe4, 0x48, 0xe9, 0x44, 0x2c, 0xc8, 0xa6, 0xd6, 83 0xeb, 0xcc, 0x4e, 0xe4, 0x48, 0xe9, 0x44, 0x2c, 0xc8, 0xa6, 0xd6,
82 0x96, 0x11, 0xd4, 0x2a, 0xc5, 0x26, 0x64, 0x34, 0x76, 0x3d, 0x14}, 84 0x96, 0x11, 0xd4, 0x2a, 0xc5, 0x26, 0x64, 0x34, 0x76, 0x3d, 0x14},
83 { // This corresponds to AppID (x86-64): knlfebnofcjjnkpkapbgfphaagefndik 85 { // This corresponds to AppID (x86-64): knlfebnofcjjnkpkapbgfphaagefndik
84 0xad, 0xb5, 0x41, 0xde, 0x52, 0x99, 0xda, 0xfa, 0x0f, 0x16, 86 0xad, 0xb5, 0x41, 0xde, 0x52, 0x99, 0xda, 0xfa, 0x0f, 0x16,
85 0x5f, 0x70, 0x06, 0x45, 0xd3, 0x8a, 0x32, 0x20, 0x84, 0x57, 0x5c, 87 0x5f, 0x70, 0x06, 0x45, 0xd3, 0x8a, 0x32, 0x20, 0x84, 0x57, 0x5c,
86 0x1f, 0xef, 0xb4, 0x42, 0x32, 0xce, 0x4a, 0x3c, 0x2d, 0x7e, 0x3a} 88 0x1f, 0xef, 0xb4, 0x42, 0x32, 0xce, 0x4a, 0x3c, 0x2d, 0x7e, 0x3a}
87 }; 89 };
88 90
89 #if defined(ARCH_CPU_X86_64) 91 #if defined(ARCH_CPU_X86_64)
90 component->pk_hash.assign( 92 pk_hash->assign(
91 x86_sha256_hash[1], 93 x86_sha256_hash[1],
92 &x86_sha256_hash[1][sizeof(x86_sha256_hash[1])]); 94 &x86_sha256_hash[1][sizeof(x86_sha256_hash[1])]);
93 #elif defined(OS_WIN) 95 #elif defined(OS_WIN)
94 bool x86_64 = (base::win::OSInfo::GetInstance()->wow64_status() == 96 bool x86_64 = (base::win::OSInfo::GetInstance()->wow64_status() ==
95 base::win::OSInfo::WOW64_ENABLED); 97 base::win::OSInfo::WOW64_ENABLED);
96 if (x86_64) { 98 if (x86_64) {
97 component->pk_hash.assign( 99 pk_hash->assign(
98 x86_sha256_hash[1], 100 x86_sha256_hash[1],
99 &x86_sha256_hash[1][sizeof(x86_sha256_hash[1])]); 101 &x86_sha256_hash[1][sizeof(x86_sha256_hash[1])]);
100 } else { 102 } else {
101 component->pk_hash.assign( 103 pk_hash->assign(
102 x86_sha256_hash[0], 104 x86_sha256_hash[0],
103 &x86_sha256_hash[0][sizeof(x86_sha256_hash[0])]); 105 &x86_sha256_hash[0][sizeof(x86_sha256_hash[0])]);
104 } 106 }
105 #else 107 #else
106 component->pk_hash.assign( 108 pk_hash->assign(
107 x86_sha256_hash[0], 109 x86_sha256_hash[0],
108 &x86_sha256_hash[0][sizeof(x86_sha256_hash[0])]); 110 &x86_sha256_hash[0][sizeof(x86_sha256_hash[0])]);
109 #endif 111 #endif
110 #elif defined(ARCH_CPU_ARMEL) 112 #elif defined(ARCH_CPU_ARMEL)
111 // This corresponds to AppID: jgobdlakdbanalhiagkdgcnofkbebejj 113 // This corresponds to AppID: jgobdlakdbanalhiagkdgcnofkbebejj
112 static const uint8 arm_sha256_hash[] = { 114 static const uint8 arm_sha256_hash[] = {
113 0x96, 0xe1, 0x3b, 0x0a, 0x31, 0x0d, 0x0b, 0x78, 0x06, 0xa3, 115 0x96, 0xe1, 0x3b, 0x0a, 0x31, 0x0d, 0x0b, 0x78, 0x06, 0xa3,
114 0x62, 0xde, 0x5a, 0x14, 0x14, 0x99, 0xd4, 0xd9, 0x01, 0x85, 0xc6, 116 0x62, 0xde, 0x5a, 0x14, 0x14, 0x99, 0xd4, 0xd9, 0x01, 0x85, 0xc6,
115 0x9a, 0xd2, 0x51, 0x90, 0xa4, 0xb4, 0x94, 0xbd, 0xb8, 0x8b, 0xe8}; 117 0x9a, 0xd2, 0x51, 0x90, 0xa4, 0xb4, 0x94, 0xbd, 0xb8, 0x8b, 0xe8};
116 118
117 component->pk_hash.assign(arm_sha256_hash, 119 pk_hash->assign(arm_sha256_hash,
118 &arm_sha256_hash[sizeof(arm_sha256_hash)]); 120 &arm_sha256_hash[sizeof(arm_sha256_hash)]);
119 #elif defined(ARCH_CPU_MIPSEL) 121 #elif defined(ARCH_CPU_MIPSEL)
120 // This is a dummy CRX hash for MIPS, so that it will at least compile. 122 // This is a dummy CRX hash for MIPS, so that it will at least compile.
121 static const uint8 mips32_sha256_hash[] = { 123 static const uint8 mips32_sha256_hash[] = {
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
125 127
126 component->pk_hash.assign(mips32_sha256_hash, 128 pk_hash->assign(mips32_sha256_hash,
127 &mips32_sha256_hash[sizeof(mips32_sha256_hash)]); 129 &mips32_sha256_hash[sizeof(mips32_sha256_hash)]);
128 #else 130 #else
129 #error "Add support for your architecture to Pnacl Component Installer." 131 #error "Add support for your architecture to Pnacl Component Installer."
130 #endif 132 #endif
131 } 133 }
132 134
133 135
134 // If we don't have Pnacl installed, this is the version we claim. 136 // If we don't have Pnacl installed, this is the version we claim.
135 const char kNullVersion[] = "0.0.0.0"; 137 const char kNullVersion[] = "0.0.0.0";
136 138
137 // Pnacl components have the version encoded in the path itself: 139 // Pnacl components have the version encoded in the path itself:
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 public: 234 public:
233 explicit PnaclComponentInstaller(const Version& version); 235 explicit PnaclComponentInstaller(const Version& version);
234 236
235 virtual ~PnaclComponentInstaller() {} 237 virtual ~PnaclComponentInstaller() {}
236 238
237 virtual void OnUpdateError(int error) OVERRIDE; 239 virtual void OnUpdateError(int error) OVERRIDE;
238 240
239 virtual bool Install(base::DictionaryValue* manifest, 241 virtual bool Install(base::DictionaryValue* manifest,
240 const base::FilePath& unpack_path) OVERRIDE; 242 const base::FilePath& unpack_path) OVERRIDE;
241 243
244 typedef base::Callback<void(bool)> InstallCallback;
245 void AddInstallCallback(const InstallCallback& cb);
246
242 private: 247 private:
248 // Cancel a particular callback after a timeout.
249 void CancelCallback(int callback_num);
250
251 void NotifyInstallError();
252
253 void NotifyInstallSuccess();
254
243 Version current_version_; 255 Version current_version_;
256
257 // Counter for issue identifiers to each callback.
258 int callback_nums_;
259
260 // List of callbacks to issue when an install completes successfully.
261 std::list<std::pair<InstallCallback, int> > install_callbacks_;
244 }; 262 };
245 263
246 PnaclComponentInstaller::PnaclComponentInstaller( 264 PnaclComponentInstaller::PnaclComponentInstaller(
247 const Version& version) : current_version_(version) { 265 const Version& version) : current_version_(version), callback_nums_(0) {
248 DCHECK(version.IsValid()); 266 DCHECK(version.IsValid());
249 } 267 }
250 268
251 void PnaclComponentInstaller::OnUpdateError(int error) { 269 void PnaclComponentInstaller::OnUpdateError(int error) {
252 NOTREACHED() << "Pnacl update error: " << error; 270 NOTREACHED() << "Pnacl update error: " << error;
253 } 271 }
254 272
255 namespace { 273 namespace {
256 274
257 bool PathContainsPnacl(const base::FilePath& base_path) { 275 bool PathContainsPnacl(const base::FilePath& base_path) {
258 // Check that at least one of the compiler files exists, for the current ISA. 276 // Check that at least one of the compiler files exists, for the current ISA.
259 std::string expected_filename("pnacl_public_"); 277 std::string expected_filename("pnacl_public_");
260 std::string arch = PnaclArch(); 278 std::string arch = PnaclArch();
261 expected_filename = expected_filename + SanitizeForPath(arch) + 279 expected_filename = expected_filename + SanitizeForPath(arch) +
262 "_" + kPnaclCompilerFileName; 280 "_" + kPnaclCompilerFileName;
263 return file_util::PathExists(base_path.AppendASCII(expected_filename)); 281 return file_util::PathExists(base_path.AppendASCII(expected_filename));
264 } 282 }
265 283
284 CrxComponent GetPnaclComponentWithVersion(const Version& current_version) {
285 // Note: the source is the default of BANDAID, even though the
286 // crxes are hosted from CWS.
287 LOG(WARNING) << "GetPnaclComponentWithVersion!!\n";
288 CrxComponent pnacl;
289 pnacl.name = "pnacl";
290 // We need a singleton installer... or singleton component,
291 // so that the correct installer's Install() hook gets called.
292 // Or the component updater service needs to be able to look up
293 // the component by id instead.
294 pnacl.installer = new PnaclComponentInstaller(current_version);
295 pnacl.version = current_version;
296 SetPnaclHash(&pnacl.pk_hash);
297 return pnacl;
298 }
299
266 } // namespace 300 } // namespace
267 301
268 bool PnaclComponentInstaller::Install(base::DictionaryValue* manifest, 302 bool PnaclComponentInstaller::Install(base::DictionaryValue* manifest,
269 const base::FilePath& unpack_path) { 303 const base::FilePath& unpack_path) {
304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
270 scoped_ptr<base::DictionaryValue> pnacl_manifest( 305 scoped_ptr<base::DictionaryValue> pnacl_manifest(
271 ReadPnaclManifest(unpack_path)); 306 ReadPnaclManifest(unpack_path));
272 if (pnacl_manifest == NULL) { 307 if (pnacl_manifest == NULL) {
273 LOG(WARNING) << "Failed to read pnacl manifest."; 308 LOG(WARNING) << "Failed to read pnacl manifest.";
309 NotifyInstallError();
274 return false; 310 return false;
275 } 311 }
276 312
277 Version version; 313 Version version;
278 if (!CheckPnaclComponentManifest(manifest, 314 if (!CheckPnaclComponentManifest(manifest,
279 pnacl_manifest.get(), 315 pnacl_manifest.get(),
280 &version)) { 316 &version)) {
281 LOG(WARNING) << "CheckPnaclComponentManifest failed, not installing."; 317 LOG(WARNING) << "CheckPnaclComponentManifest failed, not installing.";
318 NotifyInstallError();
282 return false; 319 return false;
283 } 320 }
284 321
285 // Don't install if the current version is actually newer. 322 // Don't install if the current version is actually newer.
286 if (current_version_.CompareTo(version) > 0) 323 if (current_version_.CompareTo(version) > 0) {
324 NotifyInstallError();
287 return false; 325 return false;
326 }
288 327
289 if (!PathContainsPnacl(unpack_path)) { 328 if (!PathContainsPnacl(unpack_path)) {
290 LOG(WARNING) << "PathContainsPnacl check failed, not installing."; 329 LOG(WARNING) << "PathContainsPnacl check failed, not installing.";
330 NotifyInstallError();
291 return false; 331 return false;
292 } 332 }
293 333
294 // Passed the basic tests. Time to install it. 334 // Passed the basic tests. Time to install it.
295 base::FilePath path = 335 base::FilePath path =
296 GetPnaclBaseDirectory().AppendASCII(version.GetString()); 336 GetPnaclBaseDirectory().AppendASCII(version.GetString());
297 if (file_util::PathExists(path)) { 337 if (file_util::PathExists(path)) {
298 LOG(WARNING) << "Target path already exists, not installing."; 338 LOG(WARNING) << "Target path already exists, not installing.";
339 NotifyInstallError();
299 return false; 340 return false;
300 } 341 }
301 if (!file_util::Move(unpack_path, path)) { 342 if (!file_util::Move(unpack_path, path)) {
302 LOG(WARNING) << "Move failed, not installing."; 343 LOG(WARNING) << "Move failed, not installing.";
344 NotifyInstallError();
303 return false; 345 return false;
304 } 346 }
305 347
306 // Installation is done. Now tell the rest of chrome (just the path service 348 // Installation is done. Now tell the rest of chrome.
307 // for now). TODO(jvoung): we need notifications if someone surfed to a 349 // - The path service.
308 // Pnacl webpage and Pnacl was just installed at this time. They should 350 // - Callbacks that requested an update.
309 // then be able to reload the page and retry (or something).
310 // See: http://code.google.com/p/chromium/issues/detail?id=107438
311 current_version_ = version; 351 current_version_ = version;
312 352 NotifyInstallSuccess();
313 PathService::Override(chrome::DIR_PNACL_COMPONENT, path); 353 PathService::Override(chrome::DIR_PNACL_COMPONENT, path);
314 return true; 354 return true;
315 } 355 }
316 356
317 namespace { 357 void PnaclComponentInstaller::AddInstallCallback(
358 const InstallCallback& cb) {
359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
360 int num = ++callback_nums_;
361 install_callbacks_.push_back(std::make_pair(cb, num));
318 362
319 void DoCheckForUpdate(ComponentUpdateService* cus, 363 // Set a timeout. If the install doesn't complete within a minute,
320 const CrxComponent& pnacl) { 364 // assume that the update failed and cancel the callback.
321 if (cus->CheckForUpdateSoon(pnacl) != ComponentUpdateService::kOk) { 365 // Do this on the same thread that would have checked the callbacks.
322 LOG(WARNING) << "Pnacl check for update failed."; 366 BrowserThread::PostDelayedTask(
367 BrowserThread::FILE, FROM_HERE,
368 base::Bind(&PnaclComponentInstaller::CancelCallback,
369 // Why unretained? The installer should have
370 // the same lifetime as the component updater service,
371 // which lives until process shutdown.
372 base::Unretained(this),
373 num),
374 base::TimeDelta::FromSeconds(kPnaclInstallerTimeout));
375 }
376
377 void PnaclComponentInstaller::CancelCallback(int num) {
378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
379 for (std::list<std::pair<InstallCallback, int> >::iterator
380 i = install_callbacks_.begin(),
381 e = install_callbacks_.end(); i != e; ++i) {
382 if (i->second == num) {
383 BrowserThread::PostTask(
384 BrowserThread::UI, FROM_HERE,
385 base::Bind(i->first, false));
386 install_callbacks_.erase(i);
387 return;
388 }
323 } 389 }
324 } 390 }
325 391
392 void PnaclComponentInstaller::NotifyInstallError() {
393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
394 while (!install_callbacks_.empty()) {
395 BrowserThread::PostTask(
396 BrowserThread::UI, FROM_HERE,
397 base::Bind(install_callbacks_.front().first, false));
398 install_callbacks_.pop_front();
399 }
400 }
401
402 void PnaclComponentInstaller::NotifyInstallSuccess() {
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
404 while (!install_callbacks_.empty()) {
405 BrowserThread::PostTask(
406 BrowserThread::UI, FROM_HERE,
407 base::Bind(install_callbacks_.front().first, true));
408 install_callbacks_.pop_front();
409 }
410 }
411
412 namespace {
413
326 // Finally, do the registration with the right version number. 414 // Finally, do the registration with the right version number.
327 void FinishPnaclUpdateRegistration(ComponentUpdateService* cus, 415 void FinishPnaclUpdateRegistration(ComponentUpdateService* cus,
328 const Version& current_version) { 416 const CrxComponent& pnacl) {
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
330 // Note: the source is the default of BANDAID, even though the
331 // crxes are hosted from CWS.
332 CrxComponent pnacl;
333 pnacl.name = "pnacl";
334 pnacl.installer = new PnaclComponentInstaller(current_version);
335 pnacl.version = current_version;
336 SetPnaclHash(&pnacl);
337 if (cus->RegisterComponent(pnacl) != ComponentUpdateService::kOk) { 418 if (cus->RegisterComponent(pnacl) != ComponentUpdateService::kOk) {
338 NOTREACHED() << "Pnacl component registration failed."; 419 NOTREACHED() << "Pnacl component registration failed.";
339 } 420 }
340
341 // If PNaCl is not yet installed but it is requested by --enable-pnacl,
342 // we want it to be available "soon", so kick off an update check
343 // earlier than usual.
344 Version null_version(kNullVersion);
345 if (current_version.Equals(null_version)) {
346 BrowserThread::PostDelayedTask(
347 BrowserThread::UI, FROM_HERE,
348 base::Bind(DoCheckForUpdate, cus, pnacl),
349 base::TimeDelta::FromSeconds(kInitialDelaySeconds));
350 }
351 } 421 }
352 422
353 // Check if there is an existing version on disk first to know when 423 // Check if there is an existing version on disk first to know when
354 // a hosted version is actually newer. 424 // a hosted version is actually newer.
355 void StartPnaclUpdateRegistration(ComponentUpdateService* cus) { 425 void StartPnaclUpdateRegistration(ComponentUpdateService* cus) {
356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
357 base::FilePath path = GetPnaclBaseDirectory(); 427 base::FilePath path = GetPnaclBaseDirectory();
358 if (!file_util::PathExists(path)) { 428 if (!file_util::PathExists(path)) {
359 if (!file_util::CreateDirectory(path)) { 429 if (!file_util::CreateDirectory(path)) {
360 NOTREACHED() << "Could not create base Pnacl directory."; 430 NOTREACHED() << "Could not create base Pnacl directory.";
361 return; 431 return;
362 } 432 }
363 } 433 }
364 434
365 Version version(kNullVersion); 435 Version version(kNullVersion);
366 std::vector<base::FilePath> older_dirs; 436 std::vector<base::FilePath> older_dirs;
367 if (GetLatestPnaclDirectory(&path, &version, &older_dirs)) { 437 if (GetLatestPnaclDirectory(&path, &version, &older_dirs)) {
368 if (!PathContainsPnacl(path)) { 438 if (!PathContainsPnacl(path)) {
369 version = Version(kNullVersion); 439 version = Version(kNullVersion);
370 } else { 440 } else {
371 PathService::Override(chrome::DIR_PNACL_COMPONENT, path); 441 PathService::Override(chrome::DIR_PNACL_COMPONENT, path);
372 } 442 }
373 } 443 }
374 444
375 BrowserThread::PostTask( 445 BrowserThread::PostTask(
376 BrowserThread::UI, FROM_HERE, 446 BrowserThread::UI, FROM_HERE,
377 base::Bind(&FinishPnaclUpdateRegistration, cus, version)); 447 base::Bind(&FinishPnaclUpdateRegistration,
448 cus,
449 GetPnaclComponentWithVersion(version)));
378 450
379 // Remove older versions of PNaCl. 451 // Remove older versions of PNaCl.
380 for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); 452 for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
381 iter != older_dirs.end(); ++iter) { 453 iter != older_dirs.end(); ++iter) {
382 file_util::Delete(*iter, true); 454 file_util::Delete(*iter, true);
383 } 455 }
384 } 456 }
385 457
386 } // namespace 458 } // namespace
387 459
388 void RegisterPnaclComponent(ComponentUpdateService* cus) { 460 void RegisterPnaclComponent(ComponentUpdateService* cus) {
389 BrowserThread::PostTask( 461 BrowserThread::PostTask(
390 BrowserThread::FILE, FROM_HERE, 462 BrowserThread::FILE, FROM_HERE,
391 base::Bind(&StartPnaclUpdateRegistration, cus)); 463 base::Bind(&StartPnaclUpdateRegistration, cus));
392 } 464 }
465
466 void CheckUpdatesForPnacl(ComponentUpdateService* cus,
467 const base::Callback<void(bool)>& installed) {
468 std::vector<uint8> pk_hash;
469 SetPnaclHash(&pk_hash);
470 CrxComponent pnacl;
471 if (!cus->FindRegisteredComponent(pk_hash, &pnacl)) {
472 installed.Run(false);
473 return;
474 }
475 ComponentUpdateService::Status status = cus->CheckForUpdateSoon(pnacl);
476 if (status != ComponentUpdateService::kOk) {
477 installed.Run(false);
478 return;
479 }
480 PnaclComponentInstaller* installer =
481 static_cast<PnaclComponentInstaller*>(pnacl.installer);
482 BrowserThread::PostTask(
483 BrowserThread::FILE, FROM_HERE,
484 base::Bind(
485 &PnaclComponentInstaller::AddInstallCallback,
486 // Why unretained? The installer should have
487 // the same lifetime as the component updater service,
488 // which lives until process shutdown.
489 base::Unretained(installer),
490 installed));
491 }
OLDNEW
« no previous file with comments | « chrome/browser/component_updater/pnacl/pnacl_component_installer.h ('k') | chrome/browser/nacl_host/pnacl_file_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698