Commit 268d26b8 authored by Anastasiia Nikolaienko's avatar Anastasiia Nikolaienko Committed by Commit Bot

ARC: Add a mojo method for getting the primary account

ARC needs to know the identity of the primary account, but it cannot
retrieve that from Android account manager.

Add a mojo method in ArcAuthService for returning the primary account
information from Chrome OS.

Bug: b/141108534
Test: browser_tests --gtest_filter="*Arc*AuthService*Test*"
Change-Id: I01ec976a330d52421ab2ddfe5155c712c81967af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1810359
Commit-Queue: Anastasiia Nikolaienko <anastasiian@chromium.org>
Reviewed-by: default avatarMattias Nissler <mnissler@chromium.org>
Reviewed-by: default avatarYury Khmel <khmel@chromium.org>
Reviewed-by: default avatarKush Sinha <sinhak@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726738}
parent fe55aa91
...@@ -112,6 +112,9 @@ mojom::ChromeAccountType GetAccountType(const Profile* profile) { ...@@ -112,6 +112,9 @@ mojom::ChromeAccountType GetAccountType(const Profile* profile) {
if (profile->IsChild()) if (profile->IsChild())
return mojom::ChromeAccountType::CHILD_ACCOUNT; return mojom::ChromeAccountType::CHILD_ACCOUNT;
if (IsActiveDirectoryUserForProfile(profile))
return mojom::ChromeAccountType::ACTIVE_DIRECTORY_ACCOUNT;
chromeos::DemoSession* demo_session = chromeos::DemoSession::Get(); chromeos::DemoSession* demo_session = chromeos::DemoSession::Get();
if (demo_session && demo_session->started()) { if (demo_session && demo_session->started()) {
// Internally, demo mode is implemented as a public session, and should // Internally, demo mode is implemented as a public session, and should
...@@ -221,6 +224,10 @@ void TriggerAccountManagerMigrationsIfRequired(Profile* profile) { ...@@ -221,6 +224,10 @@ void TriggerAccountManagerMigrationsIfRequired(Profile* profile) {
migrator->Start(); migrator->Start();
} }
std::string GetAuthenticatedUsernameUTF8(Profile* profile) {
return base::UTF16ToUTF8(signin_ui_util::GetAuthenticatedUsername(profile));
}
} // namespace } // namespace
// static // static
...@@ -273,6 +280,12 @@ void ArcAuthService::GetGoogleAccountsInArc( ...@@ -273,6 +280,12 @@ void ArcAuthService::GetGoogleAccountsInArc(
DispatchAccountsInArc(std::move(callback)); DispatchAccountsInArc(std::move(callback));
} }
void ArcAuthService::RequestPrimaryAccount(
RequestPrimaryAccountCallback callback) {
std::move(callback).Run(GetAuthenticatedUsernameUTF8(profile_),
GetAccountType(profile_));
}
void ArcAuthService::OnConnectionReady() { void ArcAuthService::OnConnectionReady() {
// |TriggerAccountsPushToArc()| will not be triggered for the first session, // |TriggerAccountsPushToArc()| will not be triggered for the first session,
// when ARC has not been provisioned yet. For the first session, an account // when ARC has not been provisioned yet. For the first session, an account
...@@ -659,8 +672,7 @@ void ArcAuthService::OnPrimaryAccountAuthCodeFetched( ...@@ -659,8 +672,7 @@ void ArcAuthService::OnPrimaryAccountAuthCodeFetched(
DeletePendingTokenRequest(fetcher); DeletePendingTokenRequest(fetcher);
if (success) { if (success) {
const std::string& full_account_id = const std::string& full_account_id = GetAuthenticatedUsernameUTF8(profile_);
base::UTF16ToUTF8(signin_ui_util::GetAuthenticatedUsername(profile_));
std::move(callback).Run( std::move(callback).Run(
mojom::ArcSignInStatus::SUCCESS, mojom::ArcSignInStatus::SUCCESS,
CreateAccountInfo(!IsArcOptInVerificationDisabled(), auth_code, CreateAccountInfo(!IsArcOptInVerificationDisabled(), auth_code,
......
...@@ -65,6 +65,8 @@ class ArcAuthService : public KeyedService, ...@@ -65,6 +65,8 @@ class ArcAuthService : public KeyedService,
// OS Account Manager. // OS Account Manager.
void GetGoogleAccountsInArc(GetGoogleAccountsInArcCallback callback); void GetGoogleAccountsInArc(GetGoogleAccountsInArcCallback callback);
void RequestPrimaryAccount(RequestPrimaryAccountCallback callback) override;
// For supporting ArcServiceManager::GetService<T>(). // For supporting ArcServiceManager::GetService<T>().
static const char kArcServiceName[]; static const char kArcServiceName[];
......
...@@ -228,9 +228,8 @@ class ArcAuthServiceTest : public InProcessBrowserTest { ...@@ -228,9 +228,8 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
// a dangling pointer to the User. // a dangling pointer to the User.
// TODO(nya): Consider removing all users from ProfileHelper in the // TODO(nya): Consider removing all users from ProfileHelper in the
// destructor of FakeChromeUserManager. // destructor of FakeChromeUserManager.
const AccountId account_id(AccountId::FromUserEmailGaiaId( GetFakeUserManager()->RemoveUserFromList(
kFakeUserName, signin::GetTestGaiaIdForEmail(kFakeUserName))); GetFakeUserManager()->GetActiveUser()->GetAccountId());
GetFakeUserManager()->RemoveUserFromList(account_id);
// Since ArcServiceLauncher is (re-)set up with profile() in // Since ArcServiceLauncher is (re-)set up with profile() in
// SetUpOnMainThread() it is necessary to Shutdown() before the profile() // SetUpOnMainThread() it is necessary to Shutdown() before the profile()
// is destroyed. ArcServiceLauncher::Shutdown() will be called again on // is destroyed. ArcServiceLauncher::Shutdown() will be called again on
...@@ -255,8 +254,14 @@ class ArcAuthServiceTest : public InProcessBrowserTest { ...@@ -255,8 +254,14 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
} }
void SetAccountAndProfile(const user_manager::UserType user_type) { void SetAccountAndProfile(const user_manager::UserType user_type) {
const AccountId account_id(AccountId::FromUserEmailGaiaId( AccountId account_id;
kFakeUserName, signin::GetTestGaiaIdForEmail(kFakeUserName))); if (user_type == user_manager::USER_TYPE_ACTIVE_DIRECTORY) {
account_id = AccountId::AdFromUserEmailObjGuid(
kFakeUserName, "fake-active-directory-guid");
} else {
account_id = AccountId::FromUserEmailGaiaId(
kFakeUserName, signin::GetTestGaiaIdForEmail(kFakeUserName));
}
const user_manager::User* user = nullptr; const user_manager::User* user = nullptr;
switch (user_type) { switch (user_type) {
case user_manager::USER_TYPE_CHILD: case user_manager::USER_TYPE_CHILD:
...@@ -268,6 +273,16 @@ class ArcAuthServiceTest : public InProcessBrowserTest { ...@@ -268,6 +273,16 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
case user_manager::USER_TYPE_PUBLIC_ACCOUNT: case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
user = GetFakeUserManager()->AddPublicAccountUser(account_id); user = GetFakeUserManager()->AddPublicAccountUser(account_id);
break; break;
case user_manager::USER_TYPE_ACTIVE_DIRECTORY:
user = GetFakeUserManager()->AddUserWithAffiliationAndTypeAndProfile(
account_id, true /*is_affiliated*/,
user_manager::USER_TYPE_ACTIVE_DIRECTORY, nullptr /*profile*/);
break;
case user_manager::USER_TYPE_ARC_KIOSK_APP:
user = GetFakeUserManager()->AddUserWithAffiliationAndTypeAndProfile(
account_id, false /*is_affiliated*/,
user_manager::USER_TYPE_ARC_KIOSK_APP, nullptr /*profile*/);
break;
default: default:
ADD_FAILURE() << "Unexpected user type " << user_type; ADD_FAILURE() << "Unexpected user type " << user_type;
return; return;
...@@ -294,7 +309,11 @@ class ArcAuthServiceTest : public InProcessBrowserTest { ...@@ -294,7 +309,11 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
auto* identity_test_env = auto* identity_test_env =
identity_test_environment_adaptor_->identity_test_env(); identity_test_environment_adaptor_->identity_test_env();
identity_test_env->SetAutomaticIssueOfAccessTokens(true); identity_test_env->SetAutomaticIssueOfAccessTokens(true);
if (user_type != user_manager::USER_TYPE_ACTIVE_DIRECTORY) {
// Identity service doesn't have a primary account for Active Directory
// sessions.
identity_test_env->MakePrimaryAccountAvailable(kFakeUserName); identity_test_env->MakePrimaryAccountAvailable(kFakeUserName);
}
profile()->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); profile()->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true);
profile()->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); profile()->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true);
...@@ -325,6 +344,8 @@ class ArcAuthServiceTest : public InProcessBrowserTest { ...@@ -325,6 +344,8 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
DCHECK(arc_bridge_service_); DCHECK(arc_bridge_service_);
arc_bridge_service_->auth()->SetInstance(&auth_instance_); arc_bridge_service_->auth()->SetInstance(&auth_instance_);
WaitForInstanceReady(arc_bridge_service_->auth()); WaitForInstanceReady(arc_bridge_service_->auth());
// Waiting for users and profiles to be setup.
base::RunLoop().RunUntilIdle();
} }
AccountInfo SeedAccountInfo(const std::string& email) { AccountInfo SeedAccountInfo(const std::string& email) {
...@@ -369,6 +390,27 @@ class ArcAuthServiceTest : public InProcessBrowserTest { ...@@ -369,6 +390,27 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
void WaitForGoogleAccountsInArcCallback() { run_loop_->RunUntilIdle(); } void WaitForGoogleAccountsInArcCallback() { run_loop_->RunUntilIdle(); }
std::pair<const std::string&, mojom::ChromeAccountType>
RequestPrimaryAccount() {
base::RunLoop run_loop;
std::string account_name;
mojom::ChromeAccountType account_type = mojom::ChromeAccountType::UNKNOWN;
base::OnceCallback<void(const std::string&, mojom::ChromeAccountType)>
callback = base::BindLambdaForTesting(
[&run_loop, &account_name, &account_type](
const std::string& returned_account_name,
mojom::ChromeAccountType returned_account_type) {
account_name = returned_account_name;
account_type = returned_account_type;
run_loop.Quit();
});
auth_service().RequestPrimaryAccount(std::move(callback));
run_loop.Run();
return std::make_pair(account_name, account_type);
}
Profile* profile() { return profile_.get(); } Profile* profile() { return profile_.get(); }
void set_profile_name(const std::string& username) { void set_profile_name(const std::string& username) {
...@@ -409,6 +451,53 @@ class ArcAuthServiceTest : public InProcessBrowserTest { ...@@ -409,6 +451,53 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
DISALLOW_COPY_AND_ASSIGN(ArcAuthServiceTest); DISALLOW_COPY_AND_ASSIGN(ArcAuthServiceTest);
}; };
IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForGaiaAccounts) {
SetAccountAndProfile(user_manager::USER_TYPE_REGULAR);
const std::pair<const std::string&, mojom::ChromeAccountType>
primary_account = RequestPrimaryAccount();
EXPECT_EQ(kFakeUserName, primary_account.first);
EXPECT_EQ(mojom::ChromeAccountType::USER_ACCOUNT, primary_account.second);
}
IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForChildAccounts) {
SetAccountAndProfile(user_manager::USER_TYPE_CHILD);
const std::pair<const std::string&, mojom::ChromeAccountType>
primary_account = RequestPrimaryAccount();
EXPECT_EQ(kFakeUserName, primary_account.first);
EXPECT_EQ(mojom::ChromeAccountType::CHILD_ACCOUNT, primary_account.second);
}
IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest,
GetPrimaryAccountForActiveDirectoryAccounts) {
SetAccountAndProfile(user_manager::USER_TYPE_ACTIVE_DIRECTORY);
const std::pair<const std::string&, mojom::ChromeAccountType>
primary_account = RequestPrimaryAccount();
EXPECT_EQ(std::string(), primary_account.first);
EXPECT_EQ(mojom::ChromeAccountType::ACTIVE_DIRECTORY_ACCOUNT,
primary_account.second);
}
IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForPublicAccounts) {
SetAccountAndProfile(user_manager::USER_TYPE_PUBLIC_ACCOUNT);
const std::pair<const std::string&, mojom::ChromeAccountType>
primary_account = RequestPrimaryAccount();
EXPECT_EQ(std::string(), primary_account.first);
EXPECT_EQ(mojom::ChromeAccountType::ROBOT_ACCOUNT, primary_account.second);
}
IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest,
GetPrimaryAccountForOfflineDemoAccounts) {
chromeos::DemoSession::SetDemoConfigForTesting(
chromeos::DemoSession::DemoModeConfig::kOffline);
chromeos::DemoSession::StartIfInDemoMode();
SetAccountAndProfile(user_manager::USER_TYPE_PUBLIC_ACCOUNT);
const std::pair<const std::string&, mojom::ChromeAccountType>
primary_account = RequestPrimaryAccount();
EXPECT_EQ(std::string(), primary_account.first);
EXPECT_EQ(mojom::ChromeAccountType::OFFLINE_DEMO_ACCOUNT,
primary_account.second);
}
// Tests that when ARC requests account info for a non-managed account, via // Tests that when ARC requests account info for a non-managed account, via
// |RequestAccountInfoDeprecated| API, Chrome supplies the info configured in // |RequestAccountInfoDeprecated| API, Chrome supplies the info configured in
// SetAccountAndProfile() method. // SetAccountAndProfile() method.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Next MinVersion: 23 // Next MinVersion: 24
module arc.mojom; module arc.mojom;
...@@ -256,7 +256,7 @@ struct ArcAccountInfo { ...@@ -256,7 +256,7 @@ struct ArcAccountInfo {
string gaia_id; string gaia_id;
}; };
// Next Method ID: 18. // Next Method ID: 19.
interface AuthHost { interface AuthHost {
// Notifies Chrome that the authorization flow is completed and provides // Notifies Chrome that the authorization flow is completed and provides
// resulting |status|. If |initial_signin| is true then this indicates that // resulting |status|. If |initial_signin| is true then this indicates that
...@@ -294,6 +294,13 @@ interface AuthHost { ...@@ -294,6 +294,13 @@ interface AuthHost {
[MinVersion=13] ReportSupervisionChangeStatus@11( [MinVersion=13] ReportSupervisionChangeStatus@11(
SupervisionChangeStatus status); SupervisionChangeStatus status);
// Returns the primary account from Chrome.
// |account_name| is the email address of the primary account for consumer and
// managed Gaia accounts and empty for all other cases (like demo sessions,
// Active Directory sessions, etc).
[MinVersion=23] RequestPrimaryAccount@18()
=> (string account_name, ChromeAccountType account_type);
// Requests an authorization code, as well as the account information for the // Requests an authorization code, as well as the account information for the
// Primary/Device Account in Chrome OS Account Manager. // Primary/Device Account in Chrome OS Account Manager.
// This is called for ARC's initial provisioning flow. // This is called for ARC's initial provisioning flow.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment