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 |