Chromium Code Reviews| Index: chrome/browser/chromeos/arc/arc_auth_service.cc |
| diff --git a/chrome/browser/chromeos/arc/arc_auth_service.cc b/chrome/browser/chromeos/arc/arc_auth_service.cc |
| index ed8322b5492e76e9447249f769d40035f91dd0ad..6f071e44e84d6af99d586d38e037ff74e30c58d3 100644 |
| --- a/chrome/browser/chromeos/arc/arc_auth_service.cc |
| +++ b/chrome/browser/chromeos/arc/arc_auth_service.cc |
| @@ -7,13 +7,17 @@ |
| #include <utility> |
| #include "base/bind.h" |
| -#include "base/bind_helpers.h" |
| #include "base/command_line.h" |
| #include "base/lazy_instance.h" |
| +#include "base/logging.h" |
| +#include "base/strings/string16.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/threading/thread_checker.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/browser_process_platform_part.h" |
| #include "chrome/browser/chromeos/arc/arc_auth_notification.h" |
| #include "chrome/browser/chromeos/arc/arc_optin_uma.h" |
| +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| #include "chrome/browser/extensions/extension_util.h" |
| #include "chrome/browser/policy/profile_policy_connector.h" |
| @@ -29,6 +33,8 @@ |
| #include "chrome/grit/generated_resources.h" |
| #include "chromeos/chromeos_switches.h" |
| #include "components/arc/arc_bridge_service.h" |
| +#include "components/policy/core/browser/browser_policy_connector.h" |
| +#include "components/policy/core/common/cloud/device_management_service.h" |
| #include "components/pref_registry/pref_registry_syncable.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| @@ -60,13 +66,18 @@ const char kArcSupportStorageId[] = "arc_support"; |
| // Skip creating UI in unit tests |
| bool disable_ui_for_testing = false; |
| +// The Android management check is disabled by default, it's used only for |
| +// testing. |
| +bool enable_check_android_management_for_testing = false; |
| + |
| const char kStateStopped[] = "STOPPED"; |
| const char kStateFetchingCode[] = "FETCHING_CODE"; |
| const char kStateActive[] = "ACTIVE"; |
| + |
| } // namespace |
| ArcAuthService::ArcAuthService(ArcBridgeService* bridge_service) |
| - : ArcService(bridge_service), binding_(this) { |
| + : ArcService(bridge_service), binding_(this), weak_ptr_factory_(this) { |
| DCHECK(!arc_auth_service); |
| DCHECK(thread_checker.Get().CalledOnValidThread()); |
| @@ -111,6 +122,11 @@ bool ArcAuthService::IsOptInVerificationDisabled() { |
| chromeos::switches::kDisableArcOptInVerification); |
| } |
| +// static |
| +void ArcAuthService::EnableCheckAndroidManagementForTesting() { |
| + enable_check_android_management_for_testing = true; |
| +} |
| + |
| void ArcAuthService::OnAuthInstanceReady() { |
| arc_bridge_service()->auth_instance()->Init( |
| binding_.CreateInterfacePtrAndBind()); |
| @@ -242,13 +258,23 @@ void ArcAuthService::OnPrimaryUserProfilePrepared(Profile* profile) { |
| profile_, GURL(site_url)); |
| CHECK(storage_partition_); |
| + // Get token service and account ID to fetch auth tokens. |
| + token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
| + const SigninManagerBase* const signin_manager = |
| + SigninManagerFactory::GetForProfile(profile_); |
| + CHECK(token_service_ && signin_manager); |
| + account_id_ = signin_manager->GetAuthenticatedAccountId(); |
| + |
| // In case UI is disabled we assume that ARC is opted-in. |
| if (!IsOptInVerificationDisabled()) { |
| + if (!disable_ui_for_testing || enable_check_android_management_for_testing) |
| + StartAndroidManagementClient(); |
| + |
| pref_change_registrar_.Init(profile_->GetPrefs()); |
| pref_change_registrar_.Add( |
| prefs::kArcEnabled, |
| base::Bind(&ArcAuthService::OnOptInPreferenceChanged, |
| - base::Unretained(this))); |
| + weak_ptr_factory_.GetWeakPtr())); |
| if (profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled)) { |
| OnOptInPreferenceChanged(); |
| } else { |
| @@ -258,7 +284,7 @@ void ArcAuthService::OnPrimaryUserProfilePrepared(Profile* profile) { |
| } |
| } else { |
| auth_code_.clear(); |
| - StartArc(); |
| + CheckAndroidManagement(); |
| } |
| } |
| @@ -317,7 +343,7 @@ void ArcAuthService::OnMergeSessionSuccess(const std::string& data) { |
| DCHECK(!initial_opt_in_); |
| context_prepared_ = true; |
| - ShowUI(UIPage::LSO_PROGRESS, base::string16()); |
| + CheckAndroidManagement(); |
| } |
| void ArcAuthService::OnMergeSessionFailure( |
| @@ -367,8 +393,13 @@ void ArcAuthService::OnOptInPreferenceChanged() { |
| initial_opt_in_ = true; |
| StartUI(); |
| } else { |
| - // Ready to start Arc. |
| - StartArc(); |
| + // Ready to start Arc, but check android management first. |
| + if (!disable_ui_for_testing || |
| + enable_check_android_management_for_testing) { |
| + CheckAndroidManagement(); |
| + } else { |
| + StartArc(); |
| + } |
| } |
| UpdateEnabledStateUMA(true); |
| @@ -381,10 +412,13 @@ void ArcAuthService::OnOptInPreferenceChanged() { |
| } |
| void ArcAuthService::ShutdownBridge() { |
| + FOR_EACH_OBSERVER(Observer, observer_list_, OnShutdownBridge()); |
|
xiyuan
2016/05/03 16:57:23
nit: move this to the end of the function?
Polina Bondarenko
2016/05/04 10:38:11
Done.
|
| playstore_launcher_.reset(); |
| auth_callback_.reset(); |
| ubertoken_fethcher_.reset(); |
| merger_fetcher_.reset(); |
| + token_service_ = nullptr; |
| + account_id_ = ""; |
| arc_bridge_service()->Shutdown(); |
| SetState(State::STOPPED); |
| } |
| @@ -468,7 +502,7 @@ void ArcAuthService::StartLso() { |
| void ArcAuthService::CancelAuthCode() { |
| DCHECK(thread_checker.Get().CalledOnValidThread()); |
| - if (state_ != State::FETCHING_CODE) |
| + if (state_ != State::FETCHING_CODE && ui_page_ != UIPage::ERROR) |
| return; |
| // Update UMA with user cancel only if error is not currently shown. |
| @@ -491,17 +525,10 @@ void ArcAuthService::DisableArc() { |
| void ArcAuthService::PrepareContext() { |
| DCHECK(thread_checker.Get().CalledOnValidThread()); |
| - // Get auth token to continue. |
| - ProfileOAuth2TokenService* token_service = |
| - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
| - SigninManagerBase* signin_manager = |
| - SigninManagerFactory::GetForProfile(profile_); |
| - CHECK(token_service && signin_manager); |
| - const std::string& account_id = signin_manager->GetAuthenticatedAccountId(); |
| ubertoken_fethcher_.reset( |
| - new UbertokenFetcher(token_service, this, GaiaConstants::kChromeOSSource, |
| + new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource, |
| storage_partition_->GetURLRequestContext())); |
| - ubertoken_fethcher_->StartFetchingToken(account_id); |
| + ubertoken_fethcher_->StartFetchingToken(account_id_); |
| } |
| void ArcAuthService::StartUI() { |
| @@ -513,7 +540,7 @@ void ArcAuthService::StartUI() { |
| initial_opt_in_ = false; |
| ShowUI(UIPage::START, base::string16()); |
| } else if (context_prepared_) { |
| - ShowUI(UIPage::LSO_PROGRESS, base::string16()); |
| + CheckAndroidManagement(); |
| } else { |
| PrepareContext(); |
| } |
| @@ -528,6 +555,68 @@ void ArcAuthService::OnPrepareContextFailed() { |
| UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); |
| } |
| +void ArcAuthService::StartAndroidManagementClient() { |
| + policy::BrowserPolicyConnectorChromeOS* const connector = |
| + g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
| + policy::DeviceManagementService* const service = |
| + connector->device_management_service(); |
| + service->ScheduleInitialization(0); |
| + android_management_client_.reset(new policy::AndroidManagementClient( |
| + service, g_browser_process->system_request_context(), account_id_, |
| + token_service_)); |
| +} |
| + |
| +void ArcAuthService::CheckAndroidManagement() { |
| + // Do not send requests for Chrome OS managed users. |
| + if (policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile_) |
| + ->IsManaged()) { |
| + StartArcIfSignedIn(); |
| + return; |
| + } |
| + |
| + // Do not send requests for well-known consumer domains. |
| + if (policy::BrowserPolicyConnector::IsNonEnterpriseUser( |
| + profile_->GetProfileUserName())) { |
| + StartArcIfSignedIn(); |
| + return; |
| + } |
| + |
| + android_management_client_->StartCheckAndroidManagement( |
| + base::Bind(&ArcAuthService::OnAndroidManagementChecked, |
| + weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +void ArcAuthService::OnAndroidManagementChecked( |
| + policy::AndroidManagementClient::Result result) { |
| + switch (result) { |
| + case policy::AndroidManagementClient::Result::RESULT_UNMANAGED: |
| + StartArcIfSignedIn(); |
| + break; |
| + case policy::AndroidManagementClient::Result::RESULT_MANAGED: |
| + ShutdownBridgeAndShowUI( |
| + UIPage::ERROR, |
| + l10n_util::GetStringUTF16(IDS_ARC_ANDROID_MANAGEMENT_REQUIRED_ERROR)); |
| + UpdateOptInCancelUMA(OptInCancelReason::ANDROID_MANAGEMENT_REQUIRED); |
| + break; |
| + case policy::AndroidManagementClient::Result::RESULT_ERROR: |
| + ShutdownBridgeAndShowUI( |
| + UIPage::ERROR, |
| + l10n_util::GetStringUTF16(IDS_ARC_SERVER_COMMUNICATION_ERROR)); |
| + UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); |
| + break; |
| + default: |
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +void ArcAuthService::StartArcIfSignedIn() { |
| + if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn) || |
|
bartfab (slow)
2016/05/03 16:53:44
Nit: Multi-line conditionals require curly braces.
Polina Bondarenko
2016/05/04 10:38:10
Done.
|
| + IsOptInVerificationDisabled()) |
| + StartArc(); |
| + else |
| + ShowUI(UIPage::LSO_PROGRESS, base::string16()); |
| +} |
| + |
| std::ostream& operator<<(std::ostream& os, const ArcAuthService::State& state) { |
| switch (state) { |
| case ArcAuthService::State::STOPPED: |