OLD | NEW |
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 "base/base_paths.h" | 7 #include "base/base_paths.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 188 |
189 } // namespace | 189 } // namespace |
190 | 190 |
191 PnaclComponentInstaller::PnaclComponentInstaller() | 191 PnaclComponentInstaller::PnaclComponentInstaller() |
192 : per_user_(false), | 192 : per_user_(false), |
193 updates_disabled_(false), | 193 updates_disabled_(false), |
194 cus_(NULL) { | 194 cus_(NULL) { |
195 #if defined(OS_CHROMEOS) | 195 #if defined(OS_CHROMEOS) |
196 per_user_ = true; | 196 per_user_ = true; |
197 #endif | 197 #endif |
198 updater_observer_.reset(new PnaclUpdaterObserver(this)); | |
199 } | 198 } |
200 | 199 |
201 PnaclComponentInstaller::~PnaclComponentInstaller() { | 200 PnaclComponentInstaller::~PnaclComponentInstaller() { |
202 } | 201 } |
203 | 202 |
204 void PnaclComponentInstaller::OnUpdateError(int error) { | 203 void PnaclComponentInstaller::OnUpdateError(int error) { |
205 NOTREACHED() << "Pnacl update error: " << error; | 204 NOTREACHED() << "Pnacl update error: " << error; |
206 } | 205 } |
207 | 206 |
208 // Pnacl components have the version encoded in the path itself: | 207 // Pnacl components have the version encoded in the path itself: |
(...skipping 27 matching lines...) Expand all Loading... |
236 current_profile_path_ = pm->user_data_dir().Append( | 235 current_profile_path_ = pm->user_data_dir().Append( |
237 pm->GetInitialProfileDir()); | 236 pm->GetInitialProfileDir()); |
238 } | 237 } |
239 | 238 |
240 bool PnaclComponentInstaller::Install(const base::DictionaryValue& manifest, | 239 bool PnaclComponentInstaller::Install(const base::DictionaryValue& manifest, |
241 const base::FilePath& unpack_path) { | 240 const base::FilePath& unpack_path) { |
242 scoped_ptr<base::DictionaryValue> pnacl_manifest( | 241 scoped_ptr<base::DictionaryValue> pnacl_manifest( |
243 ReadPnaclManifest(unpack_path)); | 242 ReadPnaclManifest(unpack_path)); |
244 if (pnacl_manifest == NULL) { | 243 if (pnacl_manifest == NULL) { |
245 LOG(WARNING) << "Failed to read pnacl manifest."; | 244 LOG(WARNING) << "Failed to read pnacl manifest."; |
246 NotifyInstallError(); | |
247 return false; | 245 return false; |
248 } | 246 } |
249 | 247 |
250 Version version; | 248 Version version; |
251 if (!CheckPnaclComponentManifest(manifest, *pnacl_manifest, &version)) { | 249 if (!CheckPnaclComponentManifest(manifest, *pnacl_manifest, &version)) { |
252 LOG(WARNING) << "CheckPnaclComponentManifest failed, not installing."; | 250 LOG(WARNING) << "CheckPnaclComponentManifest failed, not installing."; |
253 NotifyInstallError(); | |
254 return false; | 251 return false; |
255 } | 252 } |
256 | 253 |
257 // Don't install if the current version is actually newer. | 254 // Don't install if the current version is actually newer. |
258 if (current_version().CompareTo(version) > 0) { | 255 if (current_version().CompareTo(version) > 0) { |
259 NotifyInstallError(); | |
260 return false; | 256 return false; |
261 } | 257 } |
262 | 258 |
263 // Passed the basic tests. Time to install it. | 259 // Passed the basic tests. Time to install it. |
264 base::FilePath path = GetPnaclBaseDirectory().AppendASCII( | 260 base::FilePath path = GetPnaclBaseDirectory().AppendASCII( |
265 version.GetString()); | 261 version.GetString()); |
266 if (base::PathExists(path)) { | 262 if (base::PathExists(path)) { |
267 LOG(WARNING) << "Target path already exists, not installing."; | 263 LOG(WARNING) << "Target path already exists, not installing."; |
268 NotifyInstallError(); | |
269 return false; | 264 return false; |
270 } | 265 } |
271 if (!base::Move(unpack_path, path)) { | 266 if (!base::Move(unpack_path, path)) { |
272 LOG(WARNING) << "Move failed, not installing."; | 267 LOG(WARNING) << "Move failed, not installing."; |
273 NotifyInstallError(); | |
274 return false; | 268 return false; |
275 } | 269 } |
276 | 270 |
277 // Installation is done. Now tell the rest of chrome. | 271 // Installation is done. Now tell the rest of chrome. |
278 // - The path service. | 272 // - The path service. |
279 // - Callbacks that requested an update. | 273 // - Callbacks that requested an update. |
280 set_current_version(version); | 274 set_current_version(version); |
281 NotifyInstallSuccess(); | |
282 OverrideDirPnaclComponent(path); | 275 OverrideDirPnaclComponent(path); |
283 return true; | 276 return true; |
284 } | 277 } |
285 | 278 |
286 // Given |file|, which can be a path like "_platform_specific/arm/pnacl_foo", | 279 // Given |file|, which can be a path like "_platform_specific/arm/pnacl_foo", |
287 // returns the assumed install path. The path separator in |file| is '/' | 280 // returns the assumed install path. The path separator in |file| is '/' |
288 // for all platforms. Caller is responsible for checking that the | 281 // for all platforms. Caller is responsible for checking that the |
289 // |installed_file| actually exists. | 282 // |installed_file| actually exists. |
290 bool PnaclComponentInstaller::GetInstalledFile( | 283 bool PnaclComponentInstaller::GetInstalledFile( |
291 const std::string& file, base::FilePath* installed_file) { | 284 const std::string& file, base::FilePath* installed_file) { |
292 if (current_version().Equals(Version(kNullVersion))) | 285 if (current_version().Equals(Version(kNullVersion))) |
293 return false; | 286 return false; |
294 | 287 |
295 *installed_file = GetPnaclBaseDirectory().AppendASCII( | 288 *installed_file = GetPnaclBaseDirectory().AppendASCII( |
296 current_version().GetString()).AppendASCII(file); | 289 current_version().GetString()).AppendASCII(file); |
297 return true; | 290 return true; |
298 } | 291 } |
299 | 292 |
300 void PnaclComponentInstaller::NotifyInstallError() { | |
301 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
302 BrowserThread::PostTask( | |
303 BrowserThread::UI, FROM_HERE, | |
304 base::Bind(&PnaclComponentInstaller::NotifyInstallError, | |
305 // Unretained because installer lives until process shutdown. | |
306 base::Unretained(this))); | |
307 return; | |
308 } | |
309 if (!install_callback_.is_null()) { | |
310 updater_observer_->StopObserving(); | |
311 install_callback_.Run(false); | |
312 install_callback_.Reset(); | |
313 } | |
314 } | |
315 | |
316 void PnaclComponentInstaller::NotifyInstallSuccess() { | |
317 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
318 BrowserThread::PostTask( | |
319 BrowserThread::UI, FROM_HERE, | |
320 base::Bind(&PnaclComponentInstaller::NotifyInstallSuccess, | |
321 // Unretained because installer lives until process shutdown. | |
322 base::Unretained(this))); | |
323 return; | |
324 } | |
325 if (!install_callback_.is_null()) { | |
326 updater_observer_->StopObserving(); | |
327 install_callback_.Run(true); | |
328 install_callback_.Reset(); | |
329 } | |
330 } | |
331 | |
332 CrxComponent PnaclComponentInstaller::GetCrxComponent() { | 293 CrxComponent PnaclComponentInstaller::GetCrxComponent() { |
333 CrxComponent pnacl_component; | 294 CrxComponent pnacl_component; |
334 pnacl_component.version = current_version(); | 295 pnacl_component.version = current_version(); |
335 pnacl_component.name = "pnacl"; | 296 pnacl_component.name = "pnacl"; |
336 pnacl_component.installer = this; | 297 pnacl_component.installer = this; |
337 pnacl_component.observer = updater_observer_.get(); | |
338 pnacl_component.fingerprint = current_fingerprint(); | 298 pnacl_component.fingerprint = current_fingerprint(); |
339 SetPnaclHash(&pnacl_component); | 299 SetPnaclHash(&pnacl_component); |
340 | 300 |
341 return pnacl_component; | 301 return pnacl_component; |
342 } | 302 } |
343 | 303 |
344 namespace { | 304 namespace { |
345 | 305 |
346 void FinishPnaclUpdateRegistration(const Version& current_version, | 306 void FinishPnaclUpdateRegistration(const Version& current_version, |
347 const std::string& current_fingerprint, | 307 const std::string& current_fingerprint, |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 } | 431 } |
472 } | 432 } |
473 | 433 |
474 void PnaclComponentInstaller::ReRegisterPnacl() { | 434 void PnaclComponentInstaller::ReRegisterPnacl() { |
475 DCHECK(per_user_); | 435 DCHECK(per_user_); |
476 // Figure out profile information, before proceeding to look for files. | 436 // Figure out profile information, before proceeding to look for files. |
477 BrowserThread::PostTask( | 437 BrowserThread::PostTask( |
478 BrowserThread::UI, FROM_HERE, | 438 BrowserThread::UI, FROM_HERE, |
479 base::Bind(&GetProfileInformation, this)); | 439 base::Bind(&GetProfileInformation, this)); |
480 } | 440 } |
481 | |
482 void PnaclComponentInstaller::RequestFirstInstall(const InstallCallback& cb) { | |
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
484 // Only one request can happen at once. | |
485 if (!install_callback_.is_null()) { | |
486 cb.Run(false); | |
487 return; | |
488 } | |
489 set_current_version(Version(kNullVersion)); | |
490 CrxComponent pnacl_component = GetCrxComponent(); | |
491 ComponentUpdateService::Status status = cus_->OnDemandUpdate( | |
492 GetCrxComponentID(pnacl_component)); | |
493 if (status != ComponentUpdateService::kOk) { | |
494 cb.Run(false); | |
495 return; | |
496 } | |
497 install_callback_ = cb; | |
498 updater_observer_->EnsureObserving(); | |
499 } | |
OLD | NEW |