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/extensions/webstore_installer.h" | 5 #include "chrome/browser/extensions/webstore_installer.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 #include "content/public/browser/download_save_info.h" | 41 #include "content/public/browser/download_save_info.h" |
42 #include "content/public/browser/download_url_parameters.h" | 42 #include "content/public/browser/download_url_parameters.h" |
43 #include "content/public/browser/navigation_controller.h" | 43 #include "content/public/browser/navigation_controller.h" |
44 #include "content/public/browser/navigation_entry.h" | 44 #include "content/public/browser/navigation_entry.h" |
45 #include "content/public/browser/notification_details.h" | 45 #include "content/public/browser/notification_details.h" |
46 #include "content/public/browser/notification_service.h" | 46 #include "content/public/browser/notification_service.h" |
47 #include "content/public/browser/notification_source.h" | 47 #include "content/public/browser/notification_source.h" |
48 #include "content/public/browser/render_process_host.h" | 48 #include "content/public/browser/render_process_host.h" |
49 #include "content/public/browser/render_view_host.h" | 49 #include "content/public/browser/render_view_host.h" |
50 #include "content/public/browser/web_contents.h" | 50 #include "content/public/browser/web_contents.h" |
| 51 #include "extensions/browser/extension_registry.h" |
51 #include "extensions/browser/extension_system.h" | 52 #include "extensions/browser/extension_system.h" |
52 #include "extensions/common/extension.h" | 53 #include "extensions/common/extension.h" |
53 #include "extensions/common/manifest_constants.h" | 54 #include "extensions/common/manifest_constants.h" |
54 #include "extensions/common/manifest_handlers/shared_module_info.h" | 55 #include "extensions/common/manifest_handlers/shared_module_info.h" |
55 #include "net/base/escape.h" | 56 #include "net/base/escape.h" |
56 #include "url/gurl.h" | 57 #include "url/gurl.h" |
57 | 58 |
58 #if defined(OS_CHROMEOS) | 59 #if defined(OS_CHROMEOS) |
59 #include "chrome/browser/chromeos/drive/file_system_util.h" | 60 #include "chrome/browser/chromeos/drive/file_system_util.h" |
60 #endif | 61 #endif |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 return static_cast<const Approval*>(download.GetUserData(kApprovalKey)); | 280 return static_cast<const Approval*>(download.GetUserData(kApprovalKey)); |
280 } | 281 } |
281 | 282 |
282 WebstoreInstaller::WebstoreInstaller(Profile* profile, | 283 WebstoreInstaller::WebstoreInstaller(Profile* profile, |
283 Delegate* delegate, | 284 Delegate* delegate, |
284 content::WebContents* web_contents, | 285 content::WebContents* web_contents, |
285 const std::string& id, | 286 const std::string& id, |
286 scoped_ptr<Approval> approval, | 287 scoped_ptr<Approval> approval, |
287 InstallSource source) | 288 InstallSource source) |
288 : content::WebContentsObserver(web_contents), | 289 : content::WebContentsObserver(web_contents), |
| 290 extension_registry_observer_(this), |
289 profile_(profile), | 291 profile_(profile), |
290 delegate_(delegate), | 292 delegate_(delegate), |
291 id_(id), | 293 id_(id), |
292 install_source_(source), | 294 install_source_(source), |
293 download_item_(NULL), | 295 download_item_(NULL), |
294 approval_(approval.release()), | 296 approval_(approval.release()), |
295 total_modules_(0), | 297 total_modules_(0), |
296 download_started_(false) { | 298 download_started_(false) { |
297 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 299 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
298 DCHECK(web_contents); | 300 DCHECK(web_contents); |
299 | 301 |
300 registrar_.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE, | 302 registrar_.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE, |
301 content::NotificationService::AllSources()); | 303 content::NotificationService::AllSources()); |
302 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, | |
303 content::Source<Profile>(profile->GetOriginalProfile())); | |
304 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, | 304 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, |
305 content::Source<CrxInstaller>(NULL)); | 305 content::Source<CrxInstaller>(NULL)); |
| 306 extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); |
306 } | 307 } |
307 | 308 |
308 void WebstoreInstaller::Start() { | 309 void WebstoreInstaller::Start() { |
309 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 310 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
310 AddRef(); // Balanced in ReportSuccess and ReportFailure. | 311 AddRef(); // Balanced in ReportSuccess and ReportFailure. |
311 | 312 |
312 if (!Extension::IdIsValid(id_)) { | 313 if (!Extension::IdIsValid(id_)) { |
313 ReportFailure(kInvalidIdError, FAILURE_REASON_OTHER); | 314 ReportFailure(kInvalidIdError, FAILURE_REASON_OTHER); |
314 return; | 315 return; |
315 } | 316 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 if (crx_installer_.get() == installer) { | 378 if (crx_installer_.get() == installer) { |
378 crx_installer_ = NULL; | 379 crx_installer_ = NULL; |
379 // ReportFailure releases a reference to this object so it must be the | 380 // ReportFailure releases a reference to this object so it must be the |
380 // last operation in this method. | 381 // last operation in this method. |
381 if (extension == NULL) | 382 if (extension == NULL) |
382 ReportFailure(kInstallCanceledError, FAILURE_REASON_CANCELLED); | 383 ReportFailure(kInstallCanceledError, FAILURE_REASON_CANCELLED); |
383 } | 384 } |
384 break; | 385 break; |
385 } | 386 } |
386 | 387 |
387 case chrome::NOTIFICATION_EXTENSION_INSTALLED: { | |
388 CHECK(profile_->IsSameProfile(content::Source<Profile>(source).ptr())); | |
389 const Extension* extension = | |
390 content::Details<const InstalledExtensionInfo>(details)->extension; | |
391 if (pending_modules_.empty()) | |
392 return; | |
393 SharedModuleInfo::ImportInfo info = pending_modules_.front(); | |
394 if (extension->id() != info.extension_id) | |
395 return; | |
396 pending_modules_.pop_front(); | |
397 | |
398 if (pending_modules_.empty()) { | |
399 CHECK_EQ(extension->id(), id_); | |
400 ReportSuccess(); | |
401 } else { | |
402 const Version version_required(info.minimum_version); | |
403 if (version_required.IsValid() && | |
404 extension->version()->CompareTo(version_required) < 0) { | |
405 // It should not happen, CrxInstaller will make sure the version is | |
406 // equal or newer than version_required. | |
407 ReportFailure(kDependencyNotFoundError, | |
408 FAILURE_REASON_DEPENDENCY_NOT_FOUND); | |
409 } else if (!SharedModuleInfo::IsSharedModule(extension)) { | |
410 // It should not happen, CrxInstaller will make sure it is a shared | |
411 // module. | |
412 ReportFailure(kDependencyNotSharedModuleError, | |
413 FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE); | |
414 } else { | |
415 DownloadNextPendingModule(); | |
416 } | |
417 } | |
418 break; | |
419 } | |
420 | |
421 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { | 388 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { |
422 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); | 389 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); |
423 CHECK(crx_installer); | 390 CHECK(crx_installer); |
424 if (crx_installer != crx_installer_.get()) | 391 if (crx_installer != crx_installer_.get()) |
425 return; | 392 return; |
426 | 393 |
427 // TODO(rdevlin.cronin): Continue removing std::string errors and | 394 // TODO(rdevlin.cronin): Continue removing std::string errors and |
428 // replacing with base::string16. See crbug.com/71980. | 395 // replacing with base::string16. See crbug.com/71980. |
429 const base::string16* error = | 396 const base::string16* error = |
430 content::Details<const base::string16>(details).ptr(); | 397 content::Details<const base::string16>(details).ptr(); |
431 const std::string utf8_error = base::UTF16ToUTF8(*error); | 398 const std::string utf8_error = base::UTF16ToUTF8(*error); |
432 crx_installer_ = NULL; | 399 crx_installer_ = NULL; |
433 // ReportFailure releases a reference to this object so it must be the | 400 // ReportFailure releases a reference to this object so it must be the |
434 // last operation in this method. | 401 // last operation in this method. |
435 ReportFailure(utf8_error, FAILURE_REASON_OTHER); | 402 ReportFailure(utf8_error, FAILURE_REASON_OTHER); |
436 break; | 403 break; |
437 } | 404 } |
438 | 405 |
439 default: | 406 default: |
440 NOTREACHED(); | 407 NOTREACHED(); |
441 } | 408 } |
442 } | 409 } |
443 | 410 |
| 411 void WebstoreInstaller::OnExtensionInstalled( |
| 412 content::BrowserContext* browser_context, |
| 413 const Extension* extension, |
| 414 bool is_update, |
| 415 const std::string& old_name) { |
| 416 CHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context))); |
| 417 if (pending_modules_.empty()) |
| 418 return; |
| 419 SharedModuleInfo::ImportInfo info = pending_modules_.front(); |
| 420 if (extension->id() != info.extension_id) |
| 421 return; |
| 422 pending_modules_.pop_front(); |
| 423 |
| 424 if (pending_modules_.empty()) { |
| 425 CHECK_EQ(extension->id(), id_); |
| 426 ReportSuccess(); |
| 427 } else { |
| 428 const Version version_required(info.minimum_version); |
| 429 if (version_required.IsValid() && |
| 430 extension->version()->CompareTo(version_required) < 0) { |
| 431 // It should not happen, CrxInstaller will make sure the version is |
| 432 // equal or newer than version_required. |
| 433 ReportFailure(kDependencyNotFoundError, |
| 434 FAILURE_REASON_DEPENDENCY_NOT_FOUND); |
| 435 } else if (!SharedModuleInfo::IsSharedModule(extension)) { |
| 436 // It should not happen, CrxInstaller will make sure it is a shared |
| 437 // module. |
| 438 ReportFailure(kDependencyNotSharedModuleError, |
| 439 FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE); |
| 440 } else { |
| 441 DownloadNextPendingModule(); |
| 442 } |
| 443 } |
| 444 } |
| 445 |
444 void WebstoreInstaller::InvalidateDelegate() { | 446 void WebstoreInstaller::InvalidateDelegate() { |
445 delegate_ = NULL; | 447 delegate_ = NULL; |
446 } | 448 } |
447 | 449 |
448 void WebstoreInstaller::SetDownloadDirectoryForTests( | 450 void WebstoreInstaller::SetDownloadDirectoryForTests( |
449 base::FilePath* directory) { | 451 base::FilePath* directory) { |
450 g_download_directory_for_tests = directory; | 452 g_download_directory_for_tests = directory; |
451 } | 453 } |
452 | 454 |
453 WebstoreInstaller::~WebstoreInstaller() { | 455 WebstoreInstaller::~WebstoreInstaller() { |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 1, | 764 1, |
763 kMaxSizeKb, | 765 kMaxSizeKb, |
764 kNumBuckets); | 766 kNumBuckets); |
765 } | 767 } |
766 UMA_HISTOGRAM_BOOLEAN( | 768 UMA_HISTOGRAM_BOOLEAN( |
767 "Extensions.WebstoreDownload.InterruptTotalSizeUnknown", | 769 "Extensions.WebstoreDownload.InterruptTotalSizeUnknown", |
768 total_bytes <= 0); | 770 total_bytes <= 0); |
769 } | 771 } |
770 | 772 |
771 } // namespace extensions | 773 } // namespace extensions |
OLD | NEW |