Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "ash/common/shelf/shelf_delegate.h" | 9 #include "ash/common/shelf/shelf_delegate.h" |
| 10 #include "ash/common/wm_shell.h" | 10 #include "ash/common/wm_shell.h" |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 // No other auth code-related operation may be in progress. | 382 // No other auth code-related operation may be in progress. |
| 383 DCHECK(!account_info_notifier_); | 383 DCHECK(!account_info_notifier_); |
| 384 | 384 |
| 385 if (IsOptInVerificationDisabled()) { | 385 if (IsOptInVerificationDisabled()) { |
| 386 account_info_notifier->Notify(false /* = is_enforced */, std::string(), | 386 account_info_notifier->Notify(false /* = is_enforced */, std::string(), |
| 387 GetAccountType(), | 387 GetAccountType(), |
| 388 policy_util::IsAccountManaged(profile_)); | 388 policy_util::IsAccountManaged(profile_)); |
| 389 return; | 389 return; |
| 390 } | 390 } |
| 391 | 391 |
| 392 // Hereafter asynchronous operation. Remember the notifier. | |
| 392 account_info_notifier_ = std::move(account_info_notifier); | 393 account_info_notifier_ = std::move(account_info_notifier); |
| 393 | 394 |
| 395 // In Kiosk mode, use Robot auth code fetching. | |
| 394 if (IsArcKioskMode()) { | 396 if (IsArcKioskMode()) { |
| 395 arc_robot_auth_.reset(new ArcRobotAuth()); | 397 arc_robot_auth_.reset(new ArcRobotAuth()); |
| 396 arc_robot_auth_->FetchRobotAuthCode( | 398 arc_robot_auth_->FetchRobotAuthCode( |
| 397 base::Bind(&ArcAuthService::OnRobotAuthCodeFetched, | 399 base::Bind(&ArcAuthService::OnRobotAuthCodeFetched, |
| 398 weak_ptr_factory_.GetWeakPtr())); | 400 weak_ptr_factory_.GetWeakPtr())); |
| 399 } else { | 401 return; |
| 400 PrepareContextForAuthCodeRequest(); | |
| 401 } | 402 } |
| 403 | |
| 404 // If endpoint is passed via command line flag, use automatic auth code | |
| 405 // fetching. | |
| 406 const base::CommandLine* command_line = | |
| 407 base::CommandLine::ForCurrentProcess(); | |
| 408 std::string auth_endpoint; | |
| 409 if (command_line->HasSwitch(chromeos::switches::kArcUseAuthEndpoint)) { | |
| 410 auth_endpoint = command_line->GetSwitchValueASCII( | |
| 411 chromeos::switches::kArcUseAuthEndpoint); | |
| 412 } | |
| 413 if (!auth_endpoint.empty()) { | |
|
Luis Héctor Chávez
2016/11/15 23:27:37
IIUC this can only be true in L411. Is it possible
hidehiko
2016/11/16 01:00:34
Done. Can we work on making L411 DCHECK() in a sep
Luis Héctor Chávez
2016/11/16 03:29:58
sgtm
| |
| 414 DCHECK(!auth_code_fetcher_); | |
| 415 auth_code_fetcher_ = base::MakeUnique<ArcAuthCodeFetcher>( | |
| 416 profile_, context_.get(), auth_endpoint); | |
| 417 auth_code_fetcher_->Fetch(base::Bind(&ArcAuthService::OnAuthCodeFetched, | |
| 418 weak_ptr_factory_.GetWeakPtr())); | |
| 419 return; | |
| 420 } | |
| 421 | |
| 422 // Otherwise, show LSO page to user, and let them click "Sign in" button. | |
| 423 if (support_host_) | |
| 424 support_host_->ShowLso(); | |
| 402 } | 425 } |
| 403 | 426 |
| 404 void ArcAuthService::OnRobotAuthCodeFetched( | 427 void ArcAuthService::OnRobotAuthCodeFetched( |
| 405 const std::string& robot_auth_code) { | 428 const std::string& robot_auth_code) { |
| 406 // We fetching robot auth code for ARC kiosk only. | 429 // We fetching robot auth code for ARC kiosk only. |
| 407 DCHECK(IsArcKioskMode()); | 430 DCHECK(IsArcKioskMode()); |
| 408 | 431 |
| 409 // Current instance of ArcRobotAuth became useless. | 432 // Current instance of ArcRobotAuth became useless. |
| 410 arc_robot_auth_.reset(); | 433 arc_robot_auth_.reset(); |
| 411 | 434 |
| 412 if (robot_auth_code.empty()) { | 435 if (robot_auth_code.empty()) { |
| 413 VLOG(1) << "Robot account auth code fetching error"; | 436 VLOG(1) << "Robot account auth code fetching error"; |
| 414 // Log out the user. All the cleanup will be done in Shutdown() method. | 437 // Log out the user. All the cleanup will be done in Shutdown() method. |
| 415 // The callback is not called because auth code is empty. | 438 // The callback is not called because auth code is empty. |
| 416 chrome::AttemptUserExit(); | 439 chrome::AttemptUserExit(); |
| 417 return; | 440 return; |
| 418 } | 441 } |
| 419 | 442 |
| 420 account_info_notifier_->Notify( | 443 OnAuthCodeObtained(robot_auth_code); |
| 421 !IsOptInVerificationDisabled(), robot_auth_code, | |
| 422 mojom::ChromeAccountType::ROBOT_ACCOUNT, false); | |
| 423 account_info_notifier_.reset(); | |
| 424 } | 444 } |
| 425 | 445 |
| 426 bool ArcAuthService::IsAuthCodeRequest() const { | 446 void ArcAuthService::OnAuthCodeFetched(const std::string& auth_code) { |
| 427 return account_info_notifier_ != nullptr; | 447 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 428 } | 448 auth_code_fetcher_.reset(); |
| 429 | 449 |
| 430 void ArcAuthService::PrepareContextForAuthCodeRequest() { | 450 if (auth_code.empty()) { |
| 431 // Requesting auth code on demand happens in following cases: | 451 OnProvisioningFinished( |
| 432 // 1. To handle account password revoke. | 452 ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR); |
| 433 // 2. In case Arc is activated in OOBE flow. | 453 return; |
| 434 // 3. For any other state on Android side that leads device appears in | 454 } |
| 435 // non-signed state. | 455 |
| 436 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 456 OnAuthCodeObtained(auth_code); |
| 437 DCHECK(state_ == State::ACTIVE); | |
| 438 DCHECK(IsAuthCodeRequest()); | |
| 439 DCHECK(!IsArcKioskMode()); | |
| 440 context_->PrepareContext(); | |
| 441 } | 457 } |
| 442 | 458 |
| 443 void ArcAuthService::OnSignInComplete() { | 459 void ArcAuthService::OnSignInComplete() { |
| 444 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 460 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 445 DCHECK_EQ(state_, State::ACTIVE); | 461 DCHECK_EQ(state_, State::ACTIVE); |
| 446 OnProvisioningFinished(ProvisioningResult::SUCCESS); | 462 OnProvisioningFinished(ProvisioningResult::SUCCESS); |
| 447 } | 463 } |
| 448 | 464 |
| 449 void ArcAuthService::OnSignInFailed(mojom::ArcSignInFailureReason reason) { | 465 void ArcAuthService::OnSignInFailed(mojom::ArcSignInFailureReason reason) { |
| 450 OnProvisioningFinished( | 466 OnProvisioningFinished( |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 // This automatically updates all preferences. | 618 // This automatically updates all preferences. |
| 603 preference_handler_->Start(); | 619 preference_handler_->Start(); |
| 604 } | 620 } |
| 605 | 621 |
| 606 DCHECK_EQ(State::NOT_INITIALIZED, state_); | 622 DCHECK_EQ(State::NOT_INITIALIZED, state_); |
| 607 SetState(State::STOPPED); | 623 SetState(State::STOPPED); |
| 608 | 624 |
| 609 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( | 625 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( |
| 610 prefs::kArcEnabled, this); | 626 prefs::kArcEnabled, this); |
| 611 | 627 |
| 612 context_.reset(new ArcAuthContext(this, profile_)); | 628 context_.reset(new ArcAuthContext(profile_)); |
| 613 | 629 |
| 614 // In case UI is disabled we assume that ARC is opted-in. For ARC Kiosk we | 630 // In case UI is disabled we assume that ARC is opted-in. For ARC Kiosk we |
| 615 // skip ToS because it is very likely that near the device there will be | 631 // skip ToS because it is very likely that near the device there will be |
| 616 // no one who is eligible to accept them. We skip if Android management check | 632 // no one who is eligible to accept them. We skip if Android management check |
| 617 // because there are no managed human users for Kiosk exist. | 633 // because there are no managed human users for Kiosk exist. |
| 618 if (IsOptInVerificationDisabled() || IsArcKioskMode()) { | 634 if (IsOptInVerificationDisabled() || IsArcKioskMode()) { |
| 619 StartArc(); | 635 StartArc(); |
| 620 return; | 636 return; |
| 621 } | 637 } |
| 622 | 638 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 pref_service_syncable->RemoveObserver(this); | 675 pref_service_syncable->RemoveObserver(this); |
| 660 pref_service_syncable->RemoveSyncedPrefObserver(prefs::kArcEnabled, this); | 676 pref_service_syncable->RemoveSyncedPrefObserver(prefs::kArcEnabled, this); |
| 661 } | 677 } |
| 662 pref_change_registrar_.RemoveAll(); | 678 pref_change_registrar_.RemoveAll(); |
| 663 context_.reset(); | 679 context_.reset(); |
| 664 profile_ = nullptr; | 680 profile_ = nullptr; |
| 665 arc_robot_auth_.reset(); | 681 arc_robot_auth_.reset(); |
| 666 SetState(State::NOT_INITIALIZED); | 682 SetState(State::NOT_INITIALIZED); |
| 667 } | 683 } |
| 668 | 684 |
| 669 void ArcAuthService::OnContextReady() { | |
| 670 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 671 FetchAuthCode(); | |
| 672 } | |
| 673 | |
| 674 void ArcAuthService::OnSyncedPrefChanged(const std::string& path, | 685 void ArcAuthService::OnSyncedPrefChanged(const std::string& path, |
| 675 bool from_sync) { | 686 bool from_sync) { |
| 676 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 687 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 677 | 688 |
| 678 // Update UMA only for local changes | 689 // Update UMA only for local changes |
| 679 if (!from_sync) { | 690 if (!from_sync) { |
| 680 const bool arc_enabled = | 691 const bool arc_enabled = |
| 681 profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled); | 692 profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled); |
| 682 UpdateOptInActionUMA(arc_enabled ? OptInActionType::OPTED_IN | 693 UpdateOptInActionUMA(arc_enabled ? OptInActionType::OPTED_IN |
| 683 : OptInActionType::OPTED_OUT); | 694 : OptInActionType::OPTED_OUT); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 887 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); | 898 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); |
| 888 } | 899 } |
| 889 return; | 900 return; |
| 890 } | 901 } |
| 891 | 902 |
| 892 SetState(State::SHOWING_TERMS_OF_SERVICE); | 903 SetState(State::SHOWING_TERMS_OF_SERVICE); |
| 893 if (support_host_) | 904 if (support_host_) |
| 894 support_host_->ShowTermsOfService(); | 905 support_host_->ShowTermsOfService(); |
| 895 } | 906 } |
| 896 | 907 |
| 897 void ArcAuthService::OnPrepareContextFailed() { | |
| 898 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 899 OnProvisioningFinished(ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR); | |
| 900 } | |
| 901 | |
| 902 void ArcAuthService::OnAuthCodeSuccess(const std::string& auth_code) { | |
| 903 OnAuthCodeObtained(auth_code); | |
| 904 } | |
| 905 | |
| 906 void ArcAuthService::OnAuthCodeFailed() { | |
| 907 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 908 OnProvisioningFinished(ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR); | |
| 909 } | |
| 910 | |
| 911 void ArcAuthService::StartArcAndroidManagementCheck() { | 908 void ArcAuthService::StartArcAndroidManagementCheck() { |
| 912 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 909 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 913 DCHECK(arc_bridge_service()->stopped()); | 910 DCHECK(arc_bridge_service()->stopped()); |
| 914 DCHECK(state_ == State::SHOWING_TERMS_OF_SERVICE || | 911 DCHECK(state_ == State::SHOWING_TERMS_OF_SERVICE || |
| 915 state_ == State::CHECKING_ANDROID_MANAGEMENT); | 912 state_ == State::CHECKING_ANDROID_MANAGEMENT); |
| 916 SetState(State::CHECKING_ANDROID_MANAGEMENT); | 913 SetState(State::CHECKING_ANDROID_MANAGEMENT); |
| 917 | 914 |
| 918 android_management_checker_.reset(new ArcAndroidManagementChecker( | 915 android_management_checker_.reset(new ArcAndroidManagementChecker( |
| 919 profile_, context_->token_service(), context_->account_id(), | 916 profile_, context_->token_service(), context_->account_id(), |
| 920 false /* retry_on_error */)); | 917 false /* retry_on_error */)); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 966 case policy::AndroidManagementClient::Result::MANAGED: | 963 case policy::AndroidManagementClient::Result::MANAGED: |
| 967 DisableArc(); | 964 DisableArc(); |
| 968 break; | 965 break; |
| 969 case policy::AndroidManagementClient::Result::ERROR: | 966 case policy::AndroidManagementClient::Result::ERROR: |
| 970 // This code should not be reached. For background check, | 967 // This code should not be reached. For background check, |
| 971 // retry_on_error should be set. | 968 // retry_on_error should be set. |
| 972 NOTREACHED(); | 969 NOTREACHED(); |
| 973 } | 970 } |
| 974 } | 971 } |
| 975 | 972 |
| 976 void ArcAuthService::FetchAuthCode() { | |
| 977 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 978 | |
| 979 const base::CommandLine* command_line = | |
| 980 base::CommandLine::ForCurrentProcess(); | |
| 981 std::string auth_endpoint; | |
| 982 if (command_line->HasSwitch(chromeos::switches::kArcUseAuthEndpoint)) { | |
| 983 auth_endpoint = command_line->GetSwitchValueASCII( | |
| 984 chromeos::switches::kArcUseAuthEndpoint); | |
| 985 } | |
| 986 | |
| 987 if (!auth_endpoint.empty()) { | |
| 988 auth_code_fetcher_.reset(new ArcAuthCodeFetcher( | |
| 989 this, context_->GetURLRequestContext(), profile_, auth_endpoint)); | |
| 990 } else { | |
| 991 if (support_host_) | |
| 992 support_host_->ShowLso(); | |
| 993 } | |
| 994 } | |
| 995 | |
| 996 void ArcAuthService::OnWindowClosed() { | 973 void ArcAuthService::OnWindowClosed() { |
| 997 DCHECK(support_host_); | 974 DCHECK(support_host_); |
| 998 CancelAuthCode(); | 975 CancelAuthCode(); |
| 999 } | 976 } |
| 1000 | 977 |
| 1001 void ArcAuthService::OnTermsAgreed(bool is_metrics_enabled, | 978 void ArcAuthService::OnTermsAgreed(bool is_metrics_enabled, |
| 1002 bool is_backup_and_restore_enabled, | 979 bool is_backup_and_restore_enabled, |
| 1003 bool is_location_service_enabled) { | 980 bool is_location_service_enabled) { |
| 1004 DCHECK(support_host_); | 981 DCHECK(support_host_); |
| 1005 | 982 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1036 // ERROR_WITH_FEEDBACK is set in OnSignInFailed(). In the case, stopping | 1013 // ERROR_WITH_FEEDBACK is set in OnSignInFailed(). In the case, stopping |
| 1037 // ARC was postponed to contain its internal state into the report. | 1014 // ARC was postponed to contain its internal state into the report. |
| 1038 // Here, on retry, stop it, then restart. | 1015 // Here, on retry, stop it, then restart. |
| 1039 DCHECK_EQ(State::ACTIVE, state_); | 1016 DCHECK_EQ(State::ACTIVE, state_); |
| 1040 support_host_->ShowArcLoading(); | 1017 support_host_->ShowArcLoading(); |
| 1041 ShutdownBridge(); | 1018 ShutdownBridge(); |
| 1042 reenable_arc_ = true; | 1019 reenable_arc_ = true; |
| 1043 } else if (state_ == State::ACTIVE) { | 1020 } else if (state_ == State::ACTIVE) { |
| 1044 // This happens when ARC support Chrome app reports an error on "Sign in" | 1021 // This happens when ARC support Chrome app reports an error on "Sign in" |
| 1045 // page. | 1022 // page. |
| 1046 // TODO(hidehiko): Currently, due to the existing code structure, we need | 1023 support_host_->ShowLso(); |
| 1047 // to call PrepareContextForAuthCodeRequest() always. However, to fetch | |
| 1048 // an authtoken via LSO page, it is not necessary to call PrepareContext(). | |
| 1049 // Instead, it is possible to show LSO page, immediately. | |
| 1050 support_host_->ShowArcLoading(); | |
| 1051 PrepareContextForAuthCodeRequest(); | |
| 1052 } else { | 1024 } else { |
| 1053 // Otherwise, we restart ARC. Note: this is the first boot case. | 1025 // Otherwise, we restart ARC. Note: this is the first boot case. |
| 1054 // For second or later boot, either ERROR_WITH_FEEDBACK case or ACTIVE | 1026 // For second or later boot, either ERROR_WITH_FEEDBACK case or ACTIVE |
| 1055 // case must hit. | 1027 // case must hit. |
| 1056 support_host_->ShowArcLoading(); | 1028 support_host_->ShowArcLoading(); |
| 1057 StartArcAndroidManagementCheck(); | 1029 StartArcAndroidManagementCheck(); |
| 1058 } | 1030 } |
| 1059 } | 1031 } |
| 1060 | 1032 |
| 1061 void ArcAuthService::OnSendFeedbackClicked() { | 1033 void ArcAuthService::OnSendFeedbackClicked() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1095 return os << "ACTIVE"; | 1067 return os << "ACTIVE"; |
| 1096 } | 1068 } |
| 1097 | 1069 |
| 1098 // Some compiler reports an error even if all values of an enum-class are | 1070 // Some compiler reports an error even if all values of an enum-class are |
| 1099 // covered indivisually in a switch statement. | 1071 // covered indivisually in a switch statement. |
| 1100 NOTREACHED(); | 1072 NOTREACHED(); |
| 1101 return os; | 1073 return os; |
| 1102 } | 1074 } |
| 1103 | 1075 |
| 1104 } // namespace arc | 1076 } // namespace arc |
| OLD | NEW |