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: |