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

Side by Side Diff: chrome/browser/chromeos/arc/arc_auth_service.cc

Issue 2547073002: Fix race issue in ArcAuthService. (Closed)
Patch Set: Created 4 years 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/chromeos/arc/arc_auth_service.h" 5 #include "chrome/browser/chromeos/arc/arc_auth_service.h"
6 6
7 #include <utility>
8
7 #include "base/command_line.h" 9 #include "base/command_line.h"
8 #include "base/logging.h" 10 #include "base/logging.h"
9 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
10 #include "chrome/browser/chromeos/arc/arc_auth_code_fetcher.h"
11 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
12 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" 12 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
13 #include "chrome/browser/chromeos/arc/arc_session_manager.h" 13 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
14 #include "chrome/browser/chromeos/arc/auth/arc_robot_auth.h" 14 #include "chrome/browser/chromeos/arc/auth/arc_auth_code_fetcher.h"
15 #include "chrome/browser/chromeos/arc/auth/arc_background_auth_code_fetcher.h"
16 #include "chrome/browser/chromeos/arc/auth/arc_manual_auth_code_fetcher.h"
17 #include "chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher.h"
15 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" 18 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h"
16 #include "chrome/browser/lifetime/application_lifetime.h" 19 #include "chrome/browser/lifetime/application_lifetime.h"
17 #include "chromeos/chromeos_switches.h" 20 #include "chromeos/chromeos_switches.h"
18 #include "components/arc/arc_bridge_service.h" 21 #include "components/arc/arc_bridge_service.h"
19 #include "components/arc/arc_features.h" 22 #include "components/arc/arc_features.h"
20 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
21 24
22 namespace arc { 25 namespace arc {
23 namespace { 26 namespace {
24 27
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 return g_arc_auth_service; 144 return g_arc_auth_service;
142 } 145 }
143 146
144 void ArcAuthService::OnInstanceReady() { 147 void ArcAuthService::OnInstanceReady() {
145 auto* instance = arc_bridge_service()->auth()->GetInstanceForMethod("Init"); 148 auto* instance = arc_bridge_service()->auth()->GetInstanceForMethod("Init");
146 DCHECK(instance); 149 DCHECK(instance);
147 instance->Init(binding_.CreateInterfacePtrAndBind()); 150 instance->Init(binding_.CreateInterfacePtrAndBind());
148 } 151 }
149 152
150 void ArcAuthService::OnInstanceClosed() { 153 void ArcAuthService::OnInstanceClosed() {
151 ArcSupportHost* support_host = ArcSessionManager::Get()->support_host(); 154 fetcher_.reset();
152 if (support_host)
153 support_host->RemoveObserver(this);
154 notifier_.reset(); 155 notifier_.reset();
155 arc_robot_auth_.reset();
156 auth_code_fetcher_.reset();
157 } 156 }
158 157
159 void ArcAuthService::OnSignInComplete() { 158 void ArcAuthService::OnSignInComplete() {
160 ArcSessionManager::Get()->OnProvisioningFinished(ProvisioningResult::SUCCESS); 159 ArcSessionManager::Get()->OnProvisioningFinished(ProvisioningResult::SUCCESS);
161 } 160 }
162 161
163 void ArcAuthService::OnSignInFailed(mojom::ArcSignInFailureReason reason) { 162 void ArcAuthService::OnSignInFailed(mojom::ArcSignInFailureReason reason) {
164 ArcSessionManager::Get()->OnProvisioningFinished( 163 ArcSessionManager::Get()->OnProvisioningFinished(
165 ConvertArcSignInFailureReasonToProvisioningResult(reason)); 164 ConvertArcSignInFailureReasonToProvisioningResult(reason));
166 } 165 }
167 166
168 void ArcAuthService::RequestAccountInfo() { 167 void ArcAuthService::RequestAccountInfo() {
169 RequestAccountInfoInternal( 168 RequestAccountInfoInternal(
170 base::MakeUnique<ArcAuthService::AccountInfoNotifier>( 169 base::MakeUnique<ArcAuthService::AccountInfoNotifier>(
171 base::Bind(&ArcAuthService::OnAccountInfoReady, 170 base::Bind(&ArcAuthService::OnAccountInfoReady,
172 weak_ptr_factory_.GetWeakPtr()))); 171 weak_ptr_factory_.GetWeakPtr())));
173 } 172 }
174 173
174 void ArcAuthService::OnAccountInfoReady(mojom::AccountInfoPtr account_info) {
175 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
176 auto* instance = arc_bridge_service()->auth()->GetInstanceForMethod(
177 "OnAccountInfoReady", kMinVersionForOnAccountInfoReady);
178 DCHECK(instance);
179 instance->OnAccountInfoReady(std::move(account_info));
180 }
181
175 void ArcAuthService::GetAuthCodeDeprecated0( 182 void ArcAuthService::GetAuthCodeDeprecated0(
176 const GetAuthCodeDeprecated0Callback& callback) { 183 const GetAuthCodeDeprecated0Callback& callback) {
177 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 184 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
178 NOTREACHED() << "GetAuthCodeDeprecated0() should no longer be callable"; 185 NOTREACHED() << "GetAuthCodeDeprecated0() should no longer be callable";
179 } 186 }
180 187
181 void ArcAuthService::GetAuthCodeDeprecated( 188 void ArcAuthService::GetAuthCodeDeprecated(
182 const GetAuthCodeDeprecatedCallback& callback) { 189 const GetAuthCodeDeprecatedCallback& callback) {
183 // For robot account we must use RequestAccountInfo because it allows 190 // For robot account we must use RequestAccountInfo because it allows
184 // to specify account type. 191 // to specify account type.
(...skipping 13 matching lines...) Expand all
198 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 205 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
199 callback.Run( 206 callback.Run(
200 policy_util::IsAccountManaged(ArcSessionManager::Get()->profile())); 207 policy_util::IsAccountManaged(ArcSessionManager::Get()->profile()));
201 } 208 }
202 209
203 void ArcAuthService::RequestAccountInfoInternal( 210 void ArcAuthService::RequestAccountInfoInternal(
204 std::unique_ptr<AccountInfoNotifier> notifier) { 211 std::unique_ptr<AccountInfoNotifier> notifier) {
205 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 212 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
206 // No other auth code-related operation may be in progress. 213 // No other auth code-related operation may be in progress.
207 DCHECK(!notifier_); 214 DCHECK(!notifier_);
215 DCHECK(!fetcher_);
208 216
209 if (ArcSessionManager::IsOptInVerificationDisabled()) { 217 if (ArcSessionManager::IsOptInVerificationDisabled()) {
210 notifier->Notify( 218 notifier->Notify(
211 false /* = is_enforced */, std::string(), GetAccountType(), 219 false /* = is_enforced */, std::string(), GetAccountType(),
212 policy_util::IsAccountManaged(ArcSessionManager::Get()->profile())); 220 policy_util::IsAccountManaged(ArcSessionManager::Get()->profile()));
213 return; 221 return;
214 } 222 }
215 223
216 // Hereafter asynchronous operation. Remember the notifier. 224 // Hereafter asynchronous operation. Remember the notifier.
217 notifier_ = std::move(notifier); 225 notifier_ = std::move(notifier);
218 226
219 // In Kiosk mode, use Robot auth code fetching.
220 if (ArcSessionManager::IsArcKioskMode()) { 227 if (ArcSessionManager::IsArcKioskMode()) {
221 arc_robot_auth_.reset(new ArcRobotAuth()); 228 // In Kiosk mode, use Robot auth code fetching.
222 arc_robot_auth_->FetchRobotAuthCode( 229 fetcher_ = base::MakeUnique<ArcRobotAuthCodeFetcher>();
223 base::Bind(&ArcAuthService::OnRobotAuthCodeFetched, 230 } else if (base::FeatureList::IsEnabled(arc::kArcUseAuthEndpointFeature)) {
224 weak_ptr_factory_.GetWeakPtr())); 231 // Optionally retrive auth code in silent mode.
Luis Héctor Chávez 2016/12/03 01:27:54 nit: s/retrive/retrieve/
hidehiko 2016/12/05 06:00:31 Done.
225 return; 232 fetcher_ = base::MakeUnique<ArcBackgroundAuthCodeFetcher>(
226 }
227
228 // Optionally retrive auth code in silent mode.
229 if (base::FeatureList::IsEnabled(arc::kArcUseAuthEndpointFeature)) {
230 DCHECK(!auth_code_fetcher_);
231 auth_code_fetcher_ = base::MakeUnique<ArcAuthCodeFetcher>(
232 ArcSessionManager::Get()->profile(), 233 ArcSessionManager::Get()->profile(),
233 ArcSessionManager::Get()->auth_context()); 234 ArcSessionManager::Get()->auth_context());
234 auth_code_fetcher_->Fetch(base::Bind(&ArcAuthService::OnAuthCodeFetched, 235 } else {
235 weak_ptr_factory_.GetWeakPtr())); 236 // Otherwise, show LSO page and let user click "Sign in" button.
236 return; 237 // Here, support_host should be available always. The case support_host is
238 // not created is when 1) IsOptInVerificationDisabled() is true or 2)
239 // IsArcKioskMode() is true. Both cases are handled above.
240 fetcher_ = base::MakeUnique<ArcManualAuthCodeFetcher>(
241 ArcSessionManager::Get()->auth_context(),
242 ArcSessionManager::Get()->support_host());
237 } 243 }
238 244 fetcher_->Fetch(base::Bind(&ArcAuthService::OnAuthCodeFetched,
239 // Otherwise, show LSO page to user after HTTP context preparation, and let 245 weak_ptr_factory_.GetWeakPtr()));
240 // them click "Sign in" button.
241 ArcSessionManager::Get()->auth_context()->Prepare(base::Bind(
242 &ArcAuthService::OnContextPrepared, weak_ptr_factory_.GetWeakPtr()));
243 }
244
245 void ArcAuthService::OnContextPrepared(
246 net::URLRequestContextGetter* request_context_getter) {
247 ArcSupportHost* support_host = ArcSessionManager::Get()->support_host();
248 // Here, support_host should be available always. The case support_host is
249 // not created is when 1) IsOptInVerificationDisabled() is true or 2)
250 // IsArcKioskMode() is true. Both cases are handled above.
251 DCHECK(support_host);
252 if (!support_host->HasObserver(this))
253 support_host->AddObserver(this);
254
255 if (request_context_getter) {
256 support_host->ShowLso();
257 } else {
258 support_host->ShowError(ArcSupportHost::Error::SIGN_IN_NETWORK_ERROR,
259 false);
260 }
261 }
262
263 void ArcAuthService::OnAccountInfoReady(mojom::AccountInfoPtr account_info) {
264 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
265 auto* instance = arc_bridge_service()->auth()->GetInstanceForMethod(
266 "OnAccountInfoReady", kMinVersionForOnAccountInfoReady);
267 DCHECK(instance);
268 instance->OnAccountInfoReady(std::move(account_info));
269 }
270
271 void ArcAuthService::OnRobotAuthCodeFetched(
272 const std::string& robot_auth_code) {
273 // We fetching robot auth code for ARC kiosk only.
274 DCHECK(ArcSessionManager::IsArcKioskMode());
275
276 // Current instance of ArcRobotAuth became useless.
277 arc_robot_auth_.reset();
278
279 if (robot_auth_code.empty()) {
280 VLOG(1) << "Robot account auth code fetching error";
281 // Log out the user. All the cleanup will be done in Shutdown() method.
282 // The callback is not called because auth code is empty.
283 chrome::AttemptUserExit();
284 return;
285 }
286
287 OnAuthCodeObtained(robot_auth_code);
288 } 246 }
289 247
290 void ArcAuthService::OnAuthCodeFetched(const std::string& auth_code) { 248 void ArcAuthService::OnAuthCodeFetched(const std::string& auth_code) {
291 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 249 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
292 auth_code_fetcher_.reset(); 250 fetcher_.reset();
293 251
294 if (auth_code.empty()) { 252 if (auth_code.empty()) {
295 ArcSessionManager::Get()->OnProvisioningFinished( 253 ArcSessionManager::Get()->OnProvisioningFinished(
296 ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR); 254 ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR);
297 return; 255 return;
298 } 256 }
299 257
300 OnAuthCodeObtained(auth_code);
301 }
302
303 void ArcAuthService::OnAuthCodeObtained(const std::string& auth_code) {
304 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
305 DCHECK(!auth_code.empty());
306
307 notifier_->Notify( 258 notifier_->Notify(
308 !ArcSessionManager::IsOptInVerificationDisabled(), auth_code, 259 !ArcSessionManager::IsOptInVerificationDisabled(), auth_code,
309 GetAccountType(), 260 GetAccountType(),
310 policy_util::IsAccountManaged(ArcSessionManager::Get()->profile())); 261 policy_util::IsAccountManaged(ArcSessionManager::Get()->profile()));
311 notifier_.reset(); 262 notifier_.reset();
312 } 263 }
313 264
314 void ArcAuthService::OnAuthSucceeded(const std::string& auth_code) {
315 OnAuthCodeObtained(auth_code);
316 }
317
318 void ArcAuthService::OnRetryClicked() {
319 ArcSupportHost* support_host = ArcSessionManager::Get()->support_host();
320 // This is the callback for the UI event, so support_host should be always
321 // available here.
322 DCHECK(support_host);
323 if (support_host->ui_page() == ArcSupportHost::UIPage::ERROR) {
324 // This case is handled by ArcSessionManager::OnRetryClicked().
325 return;
326 }
327
328 ArcSessionManager::Get()->auth_context()->Prepare(base::Bind(
329 &ArcAuthService::OnContextPrepared, weak_ptr_factory_.GetWeakPtr()));
330 }
331
332 } // namespace arc 265 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698