Index: chrome/browser/extensions/extension_install_checker.cc |
diff --git a/chrome/browser/extensions/extension_install_checker.cc b/chrome/browser/extensions/extension_install_checker.cc |
index d027389d6e26b672969e8e8c84a9c644216ccfc1..313225df59060d09c967dd4cf239bc78eb43db8f 100644 |
--- a/chrome/browser/extensions/extension_install_checker.cc |
+++ b/chrome/browser/extensions/extension_install_checker.cc |
@@ -4,7 +4,6 @@ |
#include "chrome/browser/extensions/extension_install_checker.h" |
-#include "base/callback_helpers.h" |
#include "base/strings/utf_string_conversions.h" |
#include "chrome/browser/extensions/blacklist.h" |
#include "chrome/browser/extensions/chrome_requirements_checker.h" |
@@ -15,56 +14,55 @@ |
namespace extensions { |
-ExtensionInstallChecker::ExtensionInstallChecker( |
- Profile* profile, |
- scoped_refptr<const Extension> extension, |
- int enabled_checks, |
- bool fail_fast) |
+ExtensionInstallChecker::ExtensionInstallChecker(Profile* profile) |
: profile_(profile), |
- extension_(extension), |
blacklist_state_(NOT_BLACKLISTED), |
policy_allows_load_(true), |
- enabled_checks_(enabled_checks), |
+ current_sequence_number_(0), |
running_checks_(0), |
- fail_fast_(fail_fast), |
- weak_ptr_factory_(this) {} |
+ fail_fast_(false), |
+ weak_ptr_factory_(this) { |
+} |
ExtensionInstallChecker::~ExtensionInstallChecker() { |
} |
-void ExtensionInstallChecker::Start(const Callback& callback) { |
+void ExtensionInstallChecker::Start(int enabled_checks, |
+ bool fail_fast, |
+ const Callback& callback) { |
// Profile is null in tests. |
if (profile_) { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- // TODO(michaelpg): change NOTREACHED to [D]CHECK here and below. |
if (!extension_.get()) { |
NOTREACHED(); |
return; |
} |
} |
- if (is_running() || !enabled_checks_ || callback.is_null()) { |
+ if (is_running() || !enabled_checks || callback.is_null()) { |
NOTREACHED(); |
return; |
} |
- running_checks_ = enabled_checks_; |
+ running_checks_ = enabled_checks; |
+ fail_fast_ = fail_fast; |
callback_ = callback; |
+ ResetResults(); |
// Execute the management policy check first as it is synchronous. |
- if (enabled_checks_ & CHECK_MANAGEMENT_POLICY) { |
+ if (enabled_checks & CHECK_MANAGEMENT_POLICY) { |
CheckManagementPolicy(); |
if (!is_running()) |
return; |
} |
- if (enabled_checks_ & CHECK_REQUIREMENTS) { |
+ if (enabled_checks & CHECK_REQUIREMENTS) { |
CheckRequirements(); |
if (!is_running()) |
return; |
} |
- if (enabled_checks_ & CHECK_BLACKLIST) |
+ if (enabled_checks & CHECK_BLACKLIST) |
CheckBlacklistState(); |
} |
@@ -91,15 +89,21 @@ |
void ExtensionInstallChecker::CheckRequirements() { |
DCHECK(extension_.get()); |
- requirements_checker_ = base::MakeUnique<ChromeRequirementsChecker>(); |
+ if (!requirements_checker_.get()) |
+ requirements_checker_.reset(new ChromeRequirementsChecker()); |
requirements_checker_->Check( |
- extension_, base::Bind(&ExtensionInstallChecker::OnRequirementsCheckDone, |
- weak_ptr_factory_.GetWeakPtr())); |
+ extension_, |
+ base::Bind(&ExtensionInstallChecker::OnRequirementsCheckDone, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ current_sequence_number_)); |
} |
void ExtensionInstallChecker::OnRequirementsCheckDone( |
+ int sequence_number, |
const std::vector<std::string>& errors) { |
- DCHECK(is_running()); |
+ // Some pending results may arrive after fail fast. |
+ if (sequence_number != current_sequence_number_) |
+ return; |
requirement_errors_ = errors; |
@@ -114,16 +118,27 @@ |
blacklist->IsBlacklisted( |
extension_->id(), |
base::Bind(&ExtensionInstallChecker::OnBlacklistStateCheckDone, |
- weak_ptr_factory_.GetWeakPtr())); |
+ weak_ptr_factory_.GetWeakPtr(), |
+ current_sequence_number_)); |
} |
-void ExtensionInstallChecker::OnBlacklistStateCheckDone(BlacklistState state) { |
- DCHECK(is_running()); |
+void ExtensionInstallChecker::OnBlacklistStateCheckDone(int sequence_number, |
+ BlacklistState state) { |
+ // Some pending results may arrive after fail fast. |
+ if (sequence_number != current_sequence_number_) |
+ return; |
blacklist_state_ = state; |
running_checks_ &= ~CHECK_BLACKLIST; |
MaybeInvokeCallback(); |
+} |
+ |
+void ExtensionInstallChecker::ResetResults() { |
+ requirement_errors_.clear(); |
+ blacklist_state_ = NOT_BLACKLISTED; |
+ policy_allows_load_ = true; |
+ policy_error_.clear(); |
} |
void ExtensionInstallChecker::MaybeInvokeCallback() { |
@@ -145,7 +160,14 @@ |
// If we are failing fast, discard any pending results. |
weak_ptr_factory_.InvalidateWeakPtrs(); |
running_checks_ = 0; |
- base::ResetAndReturn(&callback_).Run(failed_mask); |
+ ++current_sequence_number_; |
+ |
+ Callback callback_copy = callback_; |
+ callback_.Reset(); |
+ |
+ // This instance may be owned by the callback recipient and deleted here, |
+ // so reset |callback_| first and invoke a copy of the callback. |
+ callback_copy.Run(failed_mask); |
} |
} |