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.
5 #include "chrome/browser/extensions/extension_install_checker.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/blacklist.h"
9 #include "chrome/browser/extensions/requirements_checker.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "extensions/browser/extension_system.h"
13 #include "extensions/browser/management_policy.h"
15 namespace extensions
{
17 ExtensionInstallChecker::ExtensionInstallChecker(Profile
* profile
)
19 blacklist_state_(NOT_BLACKLISTED
),
20 policy_allows_load_(true),
21 current_sequence_number_(0),
24 weak_ptr_factory_(this) {
27 ExtensionInstallChecker::~ExtensionInstallChecker() {
30 void ExtensionInstallChecker::Start(int enabled_checks
,
32 const Callback
& callback
) {
33 // Profile is null in tests.
35 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
36 if (!extension_
.get()) {
42 if (is_running() || !enabled_checks
|| callback
.is_null()) {
47 running_checks_
= enabled_checks
;
48 fail_fast_
= fail_fast
;
52 // Execute the management policy check first as it is synchronous.
53 if (enabled_checks
& CHECK_MANAGEMENT_POLICY
) {
54 CheckManagementPolicy();
59 if (enabled_checks
& CHECK_REQUIREMENTS
) {
65 if (enabled_checks
& CHECK_BLACKLIST
)
66 CheckBlacklistState();
69 void ExtensionInstallChecker::CheckManagementPolicy() {
70 DCHECK(extension_
.get());
73 bool allow
= ExtensionSystem::Get(profile_
)->management_policy()->UserMayLoad(
74 extension_
.get(), &error
);
75 OnManagementPolicyCheckDone(allow
, base::UTF16ToUTF8(error
));
78 void ExtensionInstallChecker::OnManagementPolicyCheckDone(
80 const std::string
& error
) {
81 policy_allows_load_
= allows_load
;
82 policy_error_
= error
;
83 DCHECK(policy_allows_load_
|| !policy_error_
.empty());
85 running_checks_
&= ~CHECK_MANAGEMENT_POLICY
;
86 MaybeInvokeCallback();
89 void ExtensionInstallChecker::CheckRequirements() {
90 DCHECK(extension_
.get());
92 if (!requirements_checker_
.get())
93 requirements_checker_
.reset(new RequirementsChecker());
94 requirements_checker_
->Check(
96 base::Bind(&ExtensionInstallChecker::OnRequirementsCheckDone
,
97 weak_ptr_factory_
.GetWeakPtr(),
98 current_sequence_number_
));
101 void ExtensionInstallChecker::OnRequirementsCheckDone(
103 std::vector
<std::string
> errors
) {
104 // Some pending results may arrive after fail fast.
105 if (sequence_number
!= current_sequence_number_
)
108 requirement_errors_
= errors
;
110 running_checks_
&= ~CHECK_REQUIREMENTS
;
111 MaybeInvokeCallback();
114 void ExtensionInstallChecker::CheckBlacklistState() {
115 DCHECK(extension_
.get());
117 extensions::Blacklist
* blacklist
= Blacklist::Get(profile_
);
118 blacklist
->IsBlacklisted(
120 base::Bind(&ExtensionInstallChecker::OnBlacklistStateCheckDone
,
121 weak_ptr_factory_
.GetWeakPtr(),
122 current_sequence_number_
));
125 void ExtensionInstallChecker::OnBlacklistStateCheckDone(int sequence_number
,
126 BlacklistState state
) {
127 // Some pending results may arrive after fail fast.
128 if (sequence_number
!= current_sequence_number_
)
131 blacklist_state_
= state
;
133 running_checks_
&= ~CHECK_BLACKLIST
;
134 MaybeInvokeCallback();
137 void ExtensionInstallChecker::ResetResults() {
138 requirement_errors_
.clear();
139 blacklist_state_
= NOT_BLACKLISTED
;
140 policy_allows_load_
= true;
141 policy_error_
.clear();
144 void ExtensionInstallChecker::MaybeInvokeCallback() {
145 if (callback_
.is_null())
148 // Set bits for failed checks.
150 if (blacklist_state_
== BLACKLISTED_MALWARE
)
151 failed_mask
|= CHECK_BLACKLIST
;
152 if (!requirement_errors_
.empty())
153 failed_mask
|= CHECK_REQUIREMENTS
;
154 if (!policy_allows_load_
)
155 failed_mask
|= CHECK_MANAGEMENT_POLICY
;
157 // Invoke callback if all checks are complete or there was at least one
158 // failure and |fail_fast_| is true.
159 if (!is_running() || (failed_mask
&& fail_fast_
)) {
160 // If we are failing fast, discard any pending results.
161 weak_ptr_factory_
.InvalidateWeakPtrs();
163 ++current_sequence_number_
;
165 Callback callback_copy
= callback_
;
168 // This instance may be owned by the callback recipient and deleted here,
169 // so reset |callback_| first and invoke a copy of the callback.
170 callback_copy
.Run(failed_mask
);
174 } // namespace extensions