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

Side by Side Diff: chrome/browser/extensions/crx_installer.cc

Issue 381553002: Update the CrxInstaller and UnpackedInstaller to use the ExtensionInstallChecker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved include to correct file Created 6 years, 5 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
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/crx_installer.h" 5 #include "chrome/browser/extensions/crx_installer.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 apps_require_extension_mime_type_(false), 126 apps_require_extension_mime_type_(false),
127 allow_silent_install_(false), 127 allow_silent_install_(false),
128 grant_permissions_(true), 128 grant_permissions_(true),
129 install_cause_(extension_misc::INSTALL_CAUSE_UNSET), 129 install_cause_(extension_misc::INSTALL_CAUSE_UNSET),
130 creation_flags_(Extension::NO_FLAGS), 130 creation_flags_(Extension::NO_FLAGS),
131 off_store_install_allow_reason_(OffStoreInstallDisallowed), 131 off_store_install_allow_reason_(OffStoreInstallDisallowed),
132 did_handle_successfully_(true), 132 did_handle_successfully_(true),
133 error_on_unsupported_requirements_(false), 133 error_on_unsupported_requirements_(false),
134 update_from_settings_page_(false), 134 update_from_settings_page_(false),
135 install_flags_(kInstallFlagNone), 135 install_flags_(kInstallFlagNone),
136 installer_(service_weak->profile()) { 136 install_checker_(service_weak->profile()) {
137 installer_task_runner_ = service_weak->GetFileTaskRunner(); 137 installer_task_runner_ = service_weak->GetFileTaskRunner();
138 if (!approval) 138 if (!approval)
139 return; 139 return;
140 140
141 CHECK(profile()->IsSameProfile(approval->profile)); 141 CHECK(profile()->IsSameProfile(approval->profile));
142 if (client_) { 142 if (client_) {
143 client_->install_ui()->SetUseAppInstalledBubble( 143 client_->install_ui()->SetUseAppInstalledBubble(
144 approval->use_app_installed_bubble); 144 approval->use_app_installed_bubble);
145 client_->install_ui()->set_skip_post_install_ui( 145 client_->install_ui()->set_skip_post_install_ui(
146 approval->skip_post_install_ui); 146 approval->skip_post_install_ui);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 did_handle_successfully_ = false; 362 did_handle_successfully_ = false;
363 363
364 return CrxInstallerError( 364 return CrxInstallerError(
365 CrxInstallerError::ERROR_OFF_STORE, 365 CrxInstallerError::ERROR_OFF_STORE,
366 l10n_util::GetStringUTF16( 366 l10n_util::GetStringUTF16(
367 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE)); 367 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE));
368 } 368 }
369 } 369 }
370 } 370 }
371 371
372 if (installer_.extension()->is_app()) { 372 if (install_checker_.extension()->is_app()) {
373 // If the app was downloaded, apps_require_extension_mime_type_ 373 // If the app was downloaded, apps_require_extension_mime_type_
374 // will be set. In this case, check that it was served with the 374 // will be set. In this case, check that it was served with the
375 // right mime type. Make an exception for file URLs, which come 375 // right mime type. Make an exception for file URLs, which come
376 // from the users computer and have no headers. 376 // from the users computer and have no headers.
377 if (!download_url_.SchemeIsFile() && 377 if (!download_url_.SchemeIsFile() &&
378 apps_require_extension_mime_type_ && 378 apps_require_extension_mime_type_ &&
379 original_mime_type_ != Extension::kMimeType) { 379 original_mime_type_ != Extension::kMimeType) {
380 return CrxInstallerError( 380 return CrxInstallerError(
381 l10n_util::GetStringFUTF16( 381 l10n_util::GetStringFUTF16(
382 IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE, 382 IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE,
(...skipping 14 matching lines...) Expand all
397 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE))); 397 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)));
398 } 398 }
399 399
400 // For self-hosted apps, verify that the entire extent is on the same 400 // For self-hosted apps, verify that the entire extent is on the same
401 // host (or a subdomain of the host) the download happened from. There's 401 // host (or a subdomain of the host) the download happened from. There's
402 // no way for us to verify that the app controls any other hosts. 402 // no way for us to verify that the app controls any other hosts.
403 URLPattern pattern(UserScript::ValidUserScriptSchemes()); 403 URLPattern pattern(UserScript::ValidUserScriptSchemes());
404 pattern.SetHost(download_url_.host()); 404 pattern.SetHost(download_url_.host());
405 pattern.SetMatchSubdomains(true); 405 pattern.SetMatchSubdomains(true);
406 406
407 URLPatternSet patterns = installer_.extension()->web_extent(); 407 URLPatternSet patterns = install_checker_.extension()->web_extent();
408 for (URLPatternSet::const_iterator i = patterns.begin(); 408 for (URLPatternSet::const_iterator i = patterns.begin();
409 i != patterns.end(); ++i) { 409 i != patterns.end(); ++i) {
410 if (!pattern.MatchesHost(i->host())) { 410 if (!pattern.MatchesHost(i->host())) {
411 return CrxInstallerError( 411 return CrxInstallerError(
412 l10n_util::GetStringUTF16( 412 l10n_util::GetStringUTF16(
413 IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST)); 413 IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST));
414 } 414 }
415 } 415 }
416 } 416 }
417 } 417 }
(...skipping 23 matching lines...) Expand all
441 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); 441 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread());
442 442
443 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource", 443 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource",
444 install_source(), Manifest::NUM_LOCATIONS); 444 install_source(), Manifest::NUM_LOCATIONS);
445 445
446 446
447 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause", 447 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause",
448 install_cause(), 448 install_cause(),
449 extension_misc::NUM_INSTALL_CAUSES); 449 extension_misc::NUM_INSTALL_CAUSES);
450 450
451 installer_.set_extension(extension); 451 install_checker_.set_extension(extension);
452 temp_dir_ = temp_dir; 452 temp_dir_ = temp_dir;
453 if (!install_icon.empty()) 453 if (!install_icon.empty())
454 install_icon_.reset(new SkBitmap(install_icon)); 454 install_icon_.reset(new SkBitmap(install_icon));
455 455
456 if (original_manifest) 456 if (original_manifest)
457 original_manifest_.reset(new Manifest( 457 original_manifest_.reset(new Manifest(
458 Manifest::INVALID_LOCATION, 458 Manifest::INVALID_LOCATION,
459 scoped_ptr<base::DictionaryValue>(original_manifest->DeepCopy()))); 459 scoped_ptr<base::DictionaryValue>(original_manifest->DeepCopy())));
460 460
461 // We don't have to delete the unpack dir explicity since it is a child of 461 // We don't have to delete the unpack dir explicity since it is a child of
462 // the temp dir. 462 // the temp dir.
463 unpacked_extension_root_ = extension_dir; 463 unpacked_extension_root_ = extension_dir;
464 464
465 CrxInstallerError error = AllowInstall(extension); 465 CrxInstallerError error = AllowInstall(extension);
466 if (error.type() != CrxInstallerError::ERROR_NONE) { 466 if (error.type() != CrxInstallerError::ERROR_NONE) {
467 ReportFailureFromFileThread(error); 467 ReportFailureFromFileThread(error);
468 return; 468 return;
469 } 469 }
470 470
471 if (!BrowserThread::PostTask( 471 if (!BrowserThread::PostTask(BrowserThread::UI,
472 BrowserThread::UI, FROM_HERE, 472 FROM_HERE,
473 base::Bind(&CrxInstaller::CheckImportsAndRequirements, this))) 473 base::Bind(&CrxInstaller::CheckInstall, this)))
474 NOTREACHED(); 474 NOTREACHED();
475 } 475 }
476 476
477 void CrxInstaller::CheckImportsAndRequirements() { 477 void CrxInstaller::CheckInstall() {
478 DCHECK_CURRENTLY_ON(BrowserThread::UI); 478 DCHECK_CURRENTLY_ON(BrowserThread::UI);
479 ExtensionService* service = service_weak_.get(); 479 ExtensionService* service = service_weak_.get();
480 if (!service || service->browser_terminating()) 480 if (!service || service->browser_terminating())
481 return; 481 return;
482 482
483 if (SharedModuleInfo::ImportsModules(extension())) { 483 if (SharedModuleInfo::ImportsModules(extension())) {
484 const std::vector<SharedModuleInfo::ImportInfo>& imports = 484 const std::vector<SharedModuleInfo::ImportInfo>& imports =
485 SharedModuleInfo::GetImports(extension()); 485 SharedModuleInfo::GetImports(extension());
486 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i; 486 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
487 for (i = imports.begin(); i != imports.end(); ++i) { 487 for (i = imports.begin(); i != imports.end(); ++i) {
(...skipping 10 matching lines...) Expand all
498 !SharedModuleInfo::IsExportAllowedByWhitelist(imported_module, 498 !SharedModuleInfo::IsExportAllowedByWhitelist(imported_module,
499 extension()->id())) { 499 extension()->id())) {
500 ReportFailureFromUIThread( 500 ReportFailureFromUIThread(
501 CrxInstallerError(l10n_util::GetStringFUTF16( 501 CrxInstallerError(l10n_util::GetStringFUTF16(
502 IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_WHITELISTED, 502 IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_WHITELISTED,
503 base::ASCIIToUTF16(i->extension_id)))); 503 base::ASCIIToUTF16(i->extension_id))));
504 return; 504 return;
505 } 505 }
506 } 506 }
507 } 507 }
508 installer_.CheckRequirements(base::Bind(&CrxInstaller::OnRequirementsChecked, 508
509 this)); 509 // Run the policy, requirements and blacklist checks in parallel.
510 install_checker_.Start(
511 ExtensionInstallChecker::CHECK_ALL,
512 false /* fail fast */,
513 base::Bind(&CrxInstaller::OnInstallChecksComplete, this));
510 } 514 }
511 515
512 void CrxInstaller::OnRequirementsChecked( 516 void CrxInstaller::OnInstallChecksComplete(int failed_checks) {
513 std::vector<std::string> requirement_errors) {
514 DCHECK_CURRENTLY_ON(BrowserThread::UI); 517 DCHECK_CURRENTLY_ON(BrowserThread::UI);
515 if (!service_weak_) 518 if (!service_weak_)
516 return; 519 return;
517 520
518 if (!requirement_errors.empty()) { 521 // Check for requirement errors.
522 if (!install_checker_.requirement_errors().empty()) {
519 if (error_on_unsupported_requirements_) { 523 if (error_on_unsupported_requirements_) {
520 ReportFailureFromUIThread(CrxInstallerError( 524 ReportFailureFromUIThread(CrxInstallerError(base::UTF8ToUTF16(
521 base::UTF8ToUTF16(JoinString(requirement_errors, ' ')))); 525 JoinString(install_checker_.requirement_errors(), ' '))));
522 return; 526 return;
523 } 527 }
524 install_flags_ |= kInstallFlagHasRequirementErrors; 528 install_flags_ |= kInstallFlagHasRequirementErrors;
525 } 529 }
526 530
527 ExtensionSystem::Get(profile())->blacklist()->IsBlacklisted( 531 // Check the blacklist state.
528 extension()->id(), 532 if (install_checker_.blacklist_state() == extensions::BLACKLISTED_MALWARE) {
529 base::Bind(&CrxInstaller::OnBlacklistChecked, this));
530 }
531
532 void CrxInstaller::OnBlacklistChecked(
533 extensions::BlacklistState blacklist_state) {
534 DCHECK_CURRENTLY_ON(BrowserThread::UI);
535 if (!service_weak_)
536 return;
537
538 if (blacklist_state == extensions::BLACKLISTED_MALWARE) {
539 install_flags_ |= kInstallFlagIsBlacklistedForMalware; 533 install_flags_ |= kInstallFlagIsBlacklistedForMalware;
540 } 534 }
541 535
542 if ((blacklist_state == extensions::BLACKLISTED_MALWARE || 536 if ((install_checker_.blacklist_state() == extensions::BLACKLISTED_MALWARE ||
543 blacklist_state == extensions::BLACKLISTED_UNKNOWN) && 537 install_checker_.blacklist_state() == extensions::BLACKLISTED_UNKNOWN) &&
544 !allow_silent_install_) { 538 !allow_silent_install_) {
545 // User tried to install a blacklisted extension. Show an error and 539 // User tried to install a blacklisted extension. Show an error and
546 // refuse to install it. 540 // refuse to install it.
547 ReportFailureFromUIThread(extensions::CrxInstallerError( 541 ReportFailureFromUIThread(extensions::CrxInstallerError(
548 l10n_util::GetStringFUTF16(IDS_EXTENSION_IS_BLACKLISTED, 542 l10n_util::GetStringFUTF16(IDS_EXTENSION_IS_BLACKLISTED,
549 base::UTF8ToUTF16(extension()->name())))); 543 base::UTF8ToUTF16(extension()->name()))));
550 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlockCRX", 544 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlockCRX",
551 extension()->location(), 545 extension()->location(),
552 Manifest::NUM_LOCATIONS); 546 Manifest::NUM_LOCATIONS);
553 return; 547 return;
554 } 548 }
555 549
556 // NOTE: extension may still be blacklisted, but we're forced to silently 550 // NOTE: extension may still be blacklisted, but we're forced to silently
557 // install it. In this case, ExtensionService::OnExtensionInstalled needs to 551 // install it. In this case, ExtensionService::OnExtensionInstalled needs to
558 // deal with it. 552 // deal with it.
553
554 // Check for policy errors.
555 if (!install_checker_.policy_error().empty()) {
556 // We don't want to show the error infobar for installs from the WebStore,
557 // because the WebStore already shows an error dialog itself.
558 // Note: |client_| can be NULL in unit_tests!
559 if (extension()->from_webstore() && client_)
560 client_->install_ui()->set_skip_post_install_ui(true);
561 ReportFailureFromUIThread(
562 CrxInstallerError(base::UTF8ToUTF16(install_checker_.policy_error())));
563 return;
564 }
565
559 ConfirmInstall(); 566 ConfirmInstall();
560 } 567 }
561 568
562 void CrxInstaller::ConfirmInstall() { 569 void CrxInstaller::ConfirmInstall() {
563 DCHECK_CURRENTLY_ON(BrowserThread::UI); 570 DCHECK_CURRENTLY_ON(BrowserThread::UI);
564 ExtensionService* service = service_weak_.get(); 571 ExtensionService* service = service_weak_.get();
565 if (!service || service->browser_terminating()) 572 if (!service || service->browser_terminating())
566 return; 573 return;
567 574
568 if (KioskModeInfo::IsKioskOnly(installer_.extension())) { 575 if (KioskModeInfo::IsKioskOnly(install_checker_.extension())) {
569 bool in_kiosk_mode = false; 576 bool in_kiosk_mode = false;
570 #if defined(OS_CHROMEOS) 577 #if defined(OS_CHROMEOS)
571 chromeos::UserManager* user_manager = chromeos::UserManager::Get(); 578 chromeos::UserManager* user_manager = chromeos::UserManager::Get();
572 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp(); 579 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp();
573 #endif 580 #endif
574 if (!in_kiosk_mode) { 581 if (!in_kiosk_mode) {
575 ReportFailureFromUIThread(CrxInstallerError( 582 ReportFailureFromUIThread(CrxInstallerError(
576 l10n_util::GetStringUTF16( 583 l10n_util::GetStringUTF16(
577 IDS_EXTENSION_INSTALL_KIOSK_MODE_ONLY))); 584 IDS_EXTENSION_INSTALL_KIOSK_MODE_ONLY)));
578 return; 585 return;
579 } 586 }
580 } 587 }
581 588
582 base::string16 error = installer_.CheckManagementPolicy();
583 if (!error.empty()) {
584 // We don't want to show the error infobar for installs from the WebStore,
585 // because the WebStore already shows an error dialog itself.
586 // Note: |client_| can be NULL in unit_tests!
587 if (extension()->from_webstore() && client_)
588 client_->install_ui()->set_skip_post_install_ui(true);
589 ReportFailureFromUIThread(CrxInstallerError(error));
590 return;
591 }
592
593 // Check whether this install is initiated from the settings page to 589 // Check whether this install is initiated from the settings page to
594 // update an existing extension or app. 590 // update an existing extension or app.
595 CheckUpdateFromSettingsPage(); 591 CheckUpdateFromSettingsPage();
596 592
597 GURL overlapping_url; 593 GURL overlapping_url;
598 const Extension* overlapping_extension = 594 const Extension* overlapping_extension =
599 service->extensions()->GetHostedAppByOverlappingWebExtent( 595 service->extensions()->GetHostedAppByOverlappingWebExtent(
600 extension()->web_extent()); 596 extension()->web_extent());
601 if (overlapping_extension && 597 if (overlapping_extension &&
602 overlapping_extension->id() != extension()->id()) { 598 overlapping_extension->id() != extension()->id()) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 711
716 // This is lame, but we must reload the extension because absolute paths 712 // This is lame, but we must reload the extension because absolute paths
717 // inside the content scripts are established inside InitFromValue() and we 713 // inside the content scripts are established inside InitFromValue() and we
718 // just moved the extension. 714 // just moved the extension.
719 // TODO(aa): All paths to resources inside extensions should be created 715 // TODO(aa): All paths to resources inside extensions should be created
720 // lazily and based on the Extension's root path at that moment. 716 // lazily and based on the Extension's root path at that moment.
721 // TODO(rdevlin.cronin): Continue removing std::string errors and replacing 717 // TODO(rdevlin.cronin): Continue removing std::string errors and replacing
722 // with base::string16 718 // with base::string16
723 std::string extension_id = extension()->id(); 719 std::string extension_id = extension()->id();
724 std::string error; 720 std::string error;
725 installer_.set_extension( 721 install_checker_.set_extension(
726 file_util::LoadExtension( 722 file_util::LoadExtension(
727 version_dir, 723 version_dir,
728 install_source_, 724 install_source_,
729 extension()->creation_flags() | Extension::REQUIRE_KEY, 725 extension()->creation_flags() | Extension::REQUIRE_KEY,
730 &error).get()); 726 &error).get());
731 727
732 if (extension()) { 728 if (extension()) {
733 ReportSuccessFromFileThread(); 729 ReportSuccessFromFileThread();
734 } else { 730 } else {
735 LOG(ERROR) << error << " " << extension_id << " " << download_url_; 731 LOG(ERROR) << error << " " << extension_id << " " << download_url_;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 if (!prefs->DidExtensionEscalatePermissions(extension()->id())) 894 if (!prefs->DidExtensionEscalatePermissions(extension()->id()))
899 return; 895 return;
900 896
901 if (client_) { 897 if (client_) {
902 AddRef(); // Balanced in InstallUIProceed() and InstallUIAbort(). 898 AddRef(); // Balanced in InstallUIProceed() and InstallUIAbort().
903 client_->ConfirmReEnable(this, extension()); 899 client_->ConfirmReEnable(this, extension());
904 } 900 }
905 } 901 }
906 902
907 } // namespace extensions 903 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/crx_installer.h ('k') | chrome/browser/extensions/crx_installer_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698