| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/extensions/extension_install_checker.h" | |
| 6 | |
| 7 #include "base/bind_helpers.h" | |
| 8 #include "base/callback_helpers.h" | |
| 9 #include "base/memory/ptr_util.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "chrome/browser/extensions/blacklist.h" | |
| 12 #include "chrome/browser/extensions/blacklist_check.h" | |
| 13 #include "chrome/browser/profiles/profile.h" | |
| 14 #include "content/public/browser/browser_thread.h" | |
| 15 #include "extensions/browser/extension_system.h" | |
| 16 #include "extensions/browser/policy_check.h" | |
| 17 #include "extensions/browser/requirements_checker.h" | |
| 18 | |
| 19 namespace extensions { | |
| 20 | |
| 21 ExtensionInstallChecker::ExtensionInstallChecker( | |
| 22 Profile* profile, | |
| 23 scoped_refptr<const Extension> extension, | |
| 24 int enabled_checks, | |
| 25 bool fail_fast) | |
| 26 : profile_(profile), | |
| 27 extension_(extension), | |
| 28 enabled_checks_(enabled_checks), | |
| 29 running_checks_(0), | |
| 30 fail_fast_(fail_fast), | |
| 31 weak_ptr_factory_(this) {} | |
| 32 | |
| 33 ExtensionInstallChecker::~ExtensionInstallChecker() { | |
| 34 } | |
| 35 | |
| 36 void ExtensionInstallChecker::Start(const Callback& callback) { | |
| 37 // Profile is null in tests. | |
| 38 if (profile_) { | |
| 39 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 40 // TODO(michaelpg): change NOTREACHED to [D]CHECK here and below. | |
| 41 if (!extension_.get()) { | |
| 42 NOTREACHED(); | |
| 43 return; | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 if (is_running() || !enabled_checks_ || callback.is_null()) { | |
| 48 NOTREACHED(); | |
| 49 return; | |
| 50 } | |
| 51 | |
| 52 running_checks_ = enabled_checks_; | |
| 53 callback_ = callback; | |
| 54 | |
| 55 // Execute the management policy check first as it is synchronous. | |
| 56 if (enabled_checks_ & CHECK_MANAGEMENT_POLICY) { | |
| 57 CheckManagementPolicy(); | |
| 58 if (!is_running()) | |
| 59 return; | |
| 60 } | |
| 61 | |
| 62 if (enabled_checks_ & CHECK_REQUIREMENTS) { | |
| 63 CheckRequirements(); | |
| 64 if (!is_running()) | |
| 65 return; | |
| 66 } | |
| 67 | |
| 68 if (enabled_checks_ & CHECK_BLACKLIST) | |
| 69 CheckBlacklistState(); | |
| 70 } | |
| 71 | |
| 72 void ExtensionInstallChecker::CheckManagementPolicy() { | |
| 73 // In tests, this check may already be stubbed. | |
| 74 if (!policy_check_) | |
| 75 policy_check_ = base::MakeUnique<PolicyCheck>(profile_, extension_); | |
| 76 policy_check_->Start( | |
| 77 base::BindOnce(&ExtensionInstallChecker::OnManagementPolicyCheckDone, | |
| 78 weak_ptr_factory_.GetWeakPtr())); | |
| 79 } | |
| 80 | |
| 81 void ExtensionInstallChecker::OnManagementPolicyCheckDone( | |
| 82 PreloadCheck::Errors errors) { | |
| 83 if (!errors.empty()) { | |
| 84 DCHECK_EQ(1u, errors.count(PreloadCheck::DISALLOWED_BY_POLICY)); | |
| 85 policy_error_ = policy_check_->GetErrorMessage(); | |
| 86 } | |
| 87 | |
| 88 running_checks_ &= ~CHECK_MANAGEMENT_POLICY; | |
| 89 MaybeInvokeCallback(); | |
| 90 } | |
| 91 | |
| 92 void ExtensionInstallChecker::CheckRequirements() { | |
| 93 // In tests, this check may already be stubbed. | |
| 94 if (!requirements_check_) | |
| 95 requirements_check_ = base::MakeUnique<RequirementsChecker>(extension_); | |
| 96 requirements_check_->Start( | |
| 97 base::BindOnce(&ExtensionInstallChecker::OnRequirementsCheckDone, | |
| 98 weak_ptr_factory_.GetWeakPtr())); | |
| 99 } | |
| 100 | |
| 101 void ExtensionInstallChecker::OnRequirementsCheckDone( | |
| 102 PreloadCheck::Errors errors) { | |
| 103 DCHECK(is_running()); | |
| 104 | |
| 105 requirements_error_message_ = requirements_check_->GetErrorMessage(); | |
| 106 | |
| 107 running_checks_ &= ~CHECK_REQUIREMENTS; | |
| 108 MaybeInvokeCallback(); | |
| 109 } | |
| 110 | |
| 111 void ExtensionInstallChecker::CheckBlacklistState() { | |
| 112 // In tests, this check may already be stubbed. | |
| 113 if (!blacklist_check_) { | |
| 114 blacklist_check_ = | |
| 115 base::MakeUnique<BlacklistCheck>(Blacklist::Get(profile_), extension_); | |
| 116 } | |
| 117 blacklist_check_->Start( | |
| 118 base::BindOnce(&ExtensionInstallChecker::OnBlacklistStateCheckDone, | |
| 119 weak_ptr_factory_.GetWeakPtr())); | |
| 120 } | |
| 121 | |
| 122 void ExtensionInstallChecker::OnBlacklistStateCheckDone( | |
| 123 PreloadCheck::Errors errors) { | |
| 124 DCHECK(is_running()); | |
| 125 | |
| 126 if (errors.empty()) { | |
| 127 blacklist_error_ = PreloadCheck::NONE; | |
| 128 } else { | |
| 129 DCHECK_EQ(1u, errors.size()); | |
| 130 blacklist_error_ = *errors.begin(); | |
| 131 } | |
| 132 | |
| 133 running_checks_ &= ~CHECK_BLACKLIST; | |
| 134 MaybeInvokeCallback(); | |
| 135 } | |
| 136 | |
| 137 void ExtensionInstallChecker::MaybeInvokeCallback() { | |
| 138 if (callback_.is_null()) | |
| 139 return; | |
| 140 | |
| 141 // Set bits for failed checks. | |
| 142 int failed_mask = 0; | |
| 143 if (blacklist_error_ == PreloadCheck::BLACKLISTED_ID) | |
| 144 failed_mask |= CHECK_BLACKLIST; | |
| 145 if (!requirements_error_message_.empty()) | |
| 146 failed_mask |= CHECK_REQUIREMENTS; | |
| 147 if (!policy_error_.empty()) | |
| 148 failed_mask |= CHECK_MANAGEMENT_POLICY; | |
| 149 | |
| 150 // Invoke callback if all checks are complete or there was at least one | |
| 151 // failure and |fail_fast_| is true. | |
| 152 if (!is_running() || (failed_mask && fail_fast_)) { | |
| 153 running_checks_ = 0; | |
| 154 | |
| 155 // If we are failing fast, discard any pending results. | |
| 156 blacklist_check_.reset(); | |
| 157 policy_check_.reset(); | |
| 158 requirements_check_.reset(); | |
| 159 weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 160 base::ResetAndReturn(&callback_).Run(failed_mask); | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 } // namespace extensions | |
| OLD | NEW |