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

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

Issue 2751013002: Simplify ExtensionInstallChecker into a single-use class (Closed)
Patch Set: Created 3 years, 9 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 #include <utility> 9 #include <utility>
10 10
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 scoped_refptr<CrxInstaller> CrxInstaller::Create( 101 scoped_refptr<CrxInstaller> CrxInstaller::Create(
102 ExtensionService* service, 102 ExtensionService* service,
103 std::unique_ptr<ExtensionInstallPrompt> client, 103 std::unique_ptr<ExtensionInstallPrompt> client,
104 const WebstoreInstaller::Approval* approval) { 104 const WebstoreInstaller::Approval* approval) {
105 return new CrxInstaller(service->AsWeakPtr(), std::move(client), approval); 105 return new CrxInstaller(service->AsWeakPtr(), std::move(client), approval);
106 } 106 }
107 107
108 CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> service_weak, 108 CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> service_weak,
109 std::unique_ptr<ExtensionInstallPrompt> client, 109 std::unique_ptr<ExtensionInstallPrompt> client,
110 const WebstoreInstaller::Approval* approval) 110 const WebstoreInstaller::Approval* approval)
111 : install_directory_(service_weak->install_directory()), 111 : profile_(service_weak->profile()),
112 install_directory_(service_weak->install_directory()),
112 install_source_(Manifest::INTERNAL), 113 install_source_(Manifest::INTERNAL),
113 approved_(false), 114 approved_(false),
114 hash_check_failed_(false), 115 hash_check_failed_(false),
115 expected_manifest_check_level_( 116 expected_manifest_check_level_(
116 WebstoreInstaller::MANIFEST_CHECK_LEVEL_STRICT), 117 WebstoreInstaller::MANIFEST_CHECK_LEVEL_STRICT),
117 fail_install_if_unexpected_version_(false), 118 fail_install_if_unexpected_version_(false),
118 extensions_enabled_(service_weak->extensions_enabled()), 119 extensions_enabled_(service_weak->extensions_enabled()),
119 delete_source_(false), 120 delete_source_(false),
120 create_app_shortcut_(false), 121 create_app_shortcut_(false),
121 service_weak_(service_weak), 122 service_weak_(service_weak),
122 // See header file comment on |client_| for why we use a raw pointer here. 123 // See header file comment on |client_| for why we use a raw pointer here.
123 client_(client.release()), 124 client_(client.release()),
124 apps_require_extension_mime_type_(false), 125 apps_require_extension_mime_type_(false),
125 allow_silent_install_(false), 126 allow_silent_install_(false),
126 grant_permissions_(true), 127 grant_permissions_(true),
127 install_cause_(extension_misc::INSTALL_CAUSE_UNSET), 128 install_cause_(extension_misc::INSTALL_CAUSE_UNSET),
128 creation_flags_(Extension::NO_FLAGS), 129 creation_flags_(Extension::NO_FLAGS),
129 off_store_install_allow_reason_(OffStoreInstallDisallowed), 130 off_store_install_allow_reason_(OffStoreInstallDisallowed),
130 did_handle_successfully_(true), 131 did_handle_successfully_(true),
131 error_on_unsupported_requirements_(false), 132 error_on_unsupported_requirements_(false),
132 update_from_settings_page_(false), 133 update_from_settings_page_(false),
133 install_flags_(kInstallFlagNone), 134 install_flags_(kInstallFlagNone) {
134 install_checker_(service_weak->profile()) {
135 installer_task_runner_ = service_weak->GetFileTaskRunner(); 135 installer_task_runner_ = service_weak->GetFileTaskRunner();
136 if (!approval) 136 if (!approval)
137 return; 137 return;
138 138
139 CHECK(profile()->IsSameProfile(approval->profile)); 139 CHECK(profile()->IsSameProfile(approval->profile));
140 if (client_) { 140 if (client_) {
141 client_->install_ui()->SetUseAppInstalledBubble( 141 client_->install_ui()->SetUseAppInstalledBubble(
142 approval->use_app_installed_bubble); 142 approval->use_app_installed_bubble);
143 client_->install_ui()->SetSkipPostInstallUI(approval->skip_post_install_ui); 143 client_->install_ui()->SetSkipPostInstallUI(approval->skip_post_install_ui);
144 } 144 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 // manually if they want. 348 // manually if they want.
349 delete_source_ = false; 349 delete_source_ = false;
350 did_handle_successfully_ = false; 350 did_handle_successfully_ = false;
351 351
352 return CrxInstallError( 352 return CrxInstallError(
353 CrxInstallError::ERROR_OFF_STORE, 353 CrxInstallError::ERROR_OFF_STORE,
354 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE)); 354 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE));
355 } 355 }
356 } 356 }
357 357
358 if (install_checker_.extension()->is_app()) { 358 if (extension_->is_app()) {
359 // If the app was downloaded, apps_require_extension_mime_type_ 359 // If the app was downloaded, apps_require_extension_mime_type_
360 // will be set. In this case, check that it was served with the 360 // will be set. In this case, check that it was served with the
361 // right mime type. Make an exception for file URLs, which come 361 // right mime type. Make an exception for file URLs, which come
362 // from the users computer and have no headers. 362 // from the users computer and have no headers.
363 if (!download_url_.SchemeIsFile() && 363 if (!download_url_.SchemeIsFile() &&
364 apps_require_extension_mime_type_ && 364 apps_require_extension_mime_type_ &&
365 original_mime_type_ != Extension::kMimeType) { 365 original_mime_type_ != Extension::kMimeType) {
366 return CrxInstallError(l10n_util::GetStringFUTF16( 366 return CrxInstallError(l10n_util::GetStringFUTF16(
367 IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE, 367 IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE,
368 base::ASCIIToUTF16(Extension::kMimeType))); 368 base::ASCIIToUTF16(Extension::kMimeType)));
(...skipping 12 matching lines...) Expand all
381 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE))); 381 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)));
382 } 382 }
383 383
384 // For self-hosted apps, verify that the entire extent is on the same 384 // For self-hosted apps, verify that the entire extent is on the same
385 // host (or a subdomain of the host) the download happened from. There's 385 // host (or a subdomain of the host) the download happened from. There's
386 // no way for us to verify that the app controls any other hosts. 386 // no way for us to verify that the app controls any other hosts.
387 URLPattern pattern(UserScript::ValidUserScriptSchemes()); 387 URLPattern pattern(UserScript::ValidUserScriptSchemes());
388 pattern.SetHost(download_url_.host()); 388 pattern.SetHost(download_url_.host());
389 pattern.SetMatchSubdomains(true); 389 pattern.SetMatchSubdomains(true);
390 390
391 URLPatternSet patterns = install_checker_.extension()->web_extent(); 391 URLPatternSet patterns = extension_->web_extent();
392 for (URLPatternSet::const_iterator i = patterns.begin(); 392 for (URLPatternSet::const_iterator i = patterns.begin();
393 i != patterns.end(); ++i) { 393 i != patterns.end(); ++i) {
394 if (!pattern.MatchesHost(i->host())) { 394 if (!pattern.MatchesHost(i->host())) {
395 return CrxInstallError(l10n_util::GetStringUTF16( 395 return CrxInstallError(l10n_util::GetStringUTF16(
396 IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST)); 396 IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST));
397 } 397 }
398 } 398 }
399 } 399 }
400 } 400 }
401 401
(...skipping 22 matching lines...) Expand all
424 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); 424 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread());
425 425
426 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource", 426 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource",
427 install_source(), Manifest::NUM_LOCATIONS); 427 install_source(), Manifest::NUM_LOCATIONS);
428 428
429 429
430 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause", 430 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause",
431 install_cause(), 431 install_cause(),
432 extension_misc::NUM_INSTALL_CAUSES); 432 extension_misc::NUM_INSTALL_CAUSES);
433 433
434 install_checker_.set_extension(extension); 434 extension_ = extension;
435 temp_dir_ = temp_dir; 435 temp_dir_ = temp_dir;
436 if (!install_icon.empty()) 436 if (!install_icon.empty())
437 install_icon_.reset(new SkBitmap(install_icon)); 437 install_icon_.reset(new SkBitmap(install_icon));
438 438
439 if (original_manifest) 439 if (original_manifest)
440 original_manifest_.reset(new Manifest( 440 original_manifest_.reset(new Manifest(
441 Manifest::INVALID_LOCATION, 441 Manifest::INVALID_LOCATION,
442 std::unique_ptr<base::DictionaryValue>(original_manifest->DeepCopy()))); 442 std::unique_ptr<base::DictionaryValue>(original_manifest->DeepCopy())));
443 443
444 // We don't have to delete the unpack dir explicity since it is a child of 444 // We don't have to delete the unpack dir explicity since it is a child of
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 base::UTF8ToUTF16(extension()->name()), 503 base::UTF8ToUTF16(extension()->name()),
504 base::UTF8ToUTF16(imported_module->name())))); 504 base::UTF8ToUTF16(imported_module->name()))));
505 return; 505 return;
506 } 506 }
507 } 507 }
508 } 508 }
509 509
510 // Run the policy, requirements and blacklist checks in parallel. Skip the 510 // Run the policy, requirements and blacklist checks in parallel. Skip the
511 // checks if the extension is a bookmark app. 511 // checks if the extension is a bookmark app.
512 if (extension()->from_bookmark()) { 512 if (extension()->from_bookmark()) {
513 CrxInstaller::OnInstallChecksComplete(0); 513 ConfirmInstall();
514 } else { 514 } else {
515 install_checker_.Start( 515 install_checker_ =
516 ExtensionInstallChecker::CHECK_ALL, 516 base::MakeUnique<ExtensionInstallChecker>(profile_, extension_);
517 false /* fail fast */, 517 install_checker_->Start(
518 ExtensionInstallChecker::CHECK_ALL, false /* fail fast */,
518 base::Bind(&CrxInstaller::OnInstallChecksComplete, this)); 519 base::Bind(&CrxInstaller::OnInstallChecksComplete, this));
519 } 520 }
520 } 521 }
521 522
522 void CrxInstaller::OnInstallChecksComplete(int failed_checks) { 523 void CrxInstaller::OnInstallChecksComplete(int failed_checks) {
523 DCHECK_CURRENTLY_ON(BrowserThread::UI); 524 DCHECK_CURRENTLY_ON(BrowserThread::UI);
524 if (!service_weak_) 525 if (!service_weak_)
525 return; 526 return;
526 527
527 // Check for requirement errors. 528 // Check for requirement errors.
528 if (!install_checker_.requirement_errors().empty()) { 529 if (!install_checker_->requirement_errors().empty()) {
529 if (error_on_unsupported_requirements_) { 530 if (error_on_unsupported_requirements_) {
530 ReportFailureFromUIThread( 531 ReportFailureFromUIThread(
531 CrxInstallError(CrxInstallError::ERROR_DECLINED, 532 CrxInstallError(CrxInstallError::ERROR_DECLINED,
532 base::UTF8ToUTF16(base::JoinString( 533 base::UTF8ToUTF16(base::JoinString(
533 install_checker_.requirement_errors(), " ")))); 534 install_checker_->requirement_errors(), " "))));
534 return; 535 return;
535 } 536 }
536 install_flags_ |= kInstallFlagHasRequirementErrors; 537 install_flags_ |= kInstallFlagHasRequirementErrors;
537 } 538 }
538 539
539 // Check the blacklist state. 540 // Check the blacklist state.
540 if (install_checker_.blacklist_state() == BLACKLISTED_MALWARE) { 541 if (install_checker_->blacklist_state() == BLACKLISTED_MALWARE) {
541 install_flags_ |= kInstallFlagIsBlacklistedForMalware; 542 install_flags_ |= kInstallFlagIsBlacklistedForMalware;
542 } 543 }
543 544
544 if ((install_checker_.blacklist_state() == BLACKLISTED_MALWARE || 545 if ((install_checker_->blacklist_state() == BLACKLISTED_MALWARE ||
545 install_checker_.blacklist_state() == BLACKLISTED_UNKNOWN) && 546 install_checker_->blacklist_state() == BLACKLISTED_UNKNOWN) &&
546 !allow_silent_install_) { 547 !allow_silent_install_) {
547 // User tried to install a blacklisted extension. Show an error and 548 // User tried to install a blacklisted extension. Show an error and
548 // refuse to install it. 549 // refuse to install it.
549 ReportFailureFromUIThread(CrxInstallError( 550 ReportFailureFromUIThread(CrxInstallError(
550 CrxInstallError::ERROR_DECLINED, 551 CrxInstallError::ERROR_DECLINED,
551 l10n_util::GetStringFUTF16(IDS_EXTENSION_IS_BLACKLISTED, 552 l10n_util::GetStringFUTF16(IDS_EXTENSION_IS_BLACKLISTED,
552 base::UTF8ToUTF16(extension()->name())))); 553 base::UTF8ToUTF16(extension()->name()))));
553 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlockCRX", 554 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlockCRX",
554 extension()->location(), 555 extension()->location(),
555 Manifest::NUM_LOCATIONS); 556 Manifest::NUM_LOCATIONS);
556 return; 557 return;
557 } 558 }
558 559
559 // NOTE: extension may still be blacklisted, but we're forced to silently 560 // NOTE: extension may still be blacklisted, but we're forced to silently
560 // install it. In this case, ExtensionService::OnExtensionInstalled needs to 561 // install it. In this case, ExtensionService::OnExtensionInstalled needs to
561 // deal with it. 562 // deal with it.
562 563
563 // Check for policy errors. 564 // Check for policy errors.
564 if (!install_checker_.policy_error().empty()) { 565 if (!install_checker_->policy_error().empty()) {
565 // We don't want to show the error infobar for installs from the WebStore, 566 // We don't want to show the error infobar for installs from the WebStore,
566 // because the WebStore already shows an error dialog itself. 567 // because the WebStore already shows an error dialog itself.
567 // Note: |client_| can be NULL in unit_tests! 568 // Note: |client_| can be NULL in unit_tests!
568 if (extension()->from_webstore() && client_) 569 if (extension()->from_webstore() && client_)
569 client_->install_ui()->SetSkipPostInstallUI(true); 570 client_->install_ui()->SetSkipPostInstallUI(true);
570 ReportFailureFromUIThread( 571 ReportFailureFromUIThread(
571 CrxInstallError(CrxInstallError::ERROR_DECLINED, 572 CrxInstallError(CrxInstallError::ERROR_DECLINED,
572 base::UTF8ToUTF16(install_checker_.policy_error()))); 573 base::UTF8ToUTF16(install_checker_->policy_error())));
573 return; 574 return;
574 } 575 }
575 576
576 ConfirmInstall(); 577 ConfirmInstall();
577 } 578 }
578 579
579 void CrxInstaller::ConfirmInstall() { 580 void CrxInstaller::ConfirmInstall() {
580 DCHECK_CURRENTLY_ON(BrowserThread::UI); 581 DCHECK_CURRENTLY_ON(BrowserThread::UI);
581 ExtensionService* service = service_weak_.get(); 582 ExtensionService* service = service_weak_.get();
582 if (!service || service->browser_terminating()) 583 if (!service || service->browser_terminating())
583 return; 584 return;
584 585
585 if (KioskModeInfo::IsKioskOnly(install_checker_.extension().get())) { 586 if (KioskModeInfo::IsKioskOnly(extension())) {
586 bool in_kiosk_mode = false; 587 bool in_kiosk_mode = false;
587 #if defined(OS_CHROMEOS) 588 #if defined(OS_CHROMEOS)
588 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 589 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
589 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp(); 590 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp();
590 #endif 591 #endif
591 if (!in_kiosk_mode) { 592 if (!in_kiosk_mode) {
592 ReportFailureFromUIThread(CrxInstallError( 593 ReportFailureFromUIThread(CrxInstallError(
593 CrxInstallError::ERROR_DECLINED, 594 CrxInstallError::ERROR_DECLINED,
594 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_KIOSK_MODE_ONLY))); 595 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_KIOSK_MODE_ONLY)));
595 return; 596 return;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 715
715 // This is lame, but we must reload the extension because absolute paths 716 // This is lame, but we must reload the extension because absolute paths
716 // inside the content scripts are established inside InitFromValue() and we 717 // inside the content scripts are established inside InitFromValue() and we
717 // just moved the extension. 718 // just moved the extension.
718 // TODO(aa): All paths to resources inside extensions should be created 719 // TODO(aa): All paths to resources inside extensions should be created
719 // lazily and based on the Extension's root path at that moment. 720 // lazily and based on the Extension's root path at that moment.
720 // TODO(rdevlin.cronin): Continue removing std::string errors and replacing 721 // TODO(rdevlin.cronin): Continue removing std::string errors and replacing
721 // with base::string16 722 // with base::string16
722 std::string extension_id = extension()->id(); 723 std::string extension_id = extension()->id();
723 std::string error; 724 std::string error;
724 install_checker_.set_extension( 725 extension_ = file_util::LoadExtension(
725 file_util::LoadExtension( 726 version_dir, install_source_,
726 version_dir, 727 // Note: modified by UpdateCreationFlagsAndCompleteInstall.
727 install_source_, 728 creation_flags_, &error);
728 // Note: modified by UpdateCreationFlagsAndCompleteInstall.
729 creation_flags_,
730 &error).get());
731 729
732 if (extension()) { 730 if (extension()) {
733 ReportSuccessFromFileThread(); 731 ReportSuccessFromFileThread();
734 } else { 732 } else {
735 LOG(ERROR) << error << " " << extension_id << " " << download_url_; 733 LOG(ERROR) << error << " " << extension_id << " " << download_url_;
736 ReportFailureFromFileThread(CrxInstallError(base::UTF8ToUTF16(error))); 734 ReportFailureFromFileThread(CrxInstallError(base::UTF8ToUTF16(error)));
737 } 735 }
738 } 736 }
739 737
740 void CrxInstaller::ReportFailureFromFileThread(const CrxInstallError& error) { 738 void CrxInstaller::ReportFailureFromFileThread(const CrxInstallError& error) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 ExtensionInstallPrompt::GetReEnablePromptTypeForExtension( 906 ExtensionInstallPrompt::GetReEnablePromptTypeForExtension(
909 service->profile(), extension()); 907 service->profile(), extension());
910 client_->ShowDialog(base::Bind(&CrxInstaller::OnInstallPromptDone, this), 908 client_->ShowDialog(base::Bind(&CrxInstaller::OnInstallPromptDone, this),
911 extension(), nullptr, 909 extension(), nullptr,
912 base::MakeUnique<ExtensionInstallPrompt::Prompt>(type), 910 base::MakeUnique<ExtensionInstallPrompt::Prompt>(type),
913 ExtensionInstallPrompt::GetDefaultShowDialogCallback()); 911 ExtensionInstallPrompt::GetDefaultShowDialogCallback());
914 } 912 }
915 } 913 }
916 914
917 } // namespace extensions 915 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698