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) {
if (profile->IsChild())
return mojom::ChromeAccountType::CHILD_ACCOUNT;
if (IsActiveDirectoryUserForProfile(profile))
return mojom::ChromeAccountType::ACTIVE_DIRECTORY_ACCOUNT;
chromeos::DemoSession* demo_session = chromeos::DemoSession::Get();
if (demo_session && demo_session->started()) {
// Internally, demo mode is implemented as a public session, and should
......@@ -221,6 +224,10 @@ void TriggerAccountManagerMigrationsIfRequired(Profile* profile) {
migrator->Start();
}
std::string GetAuthenticatedUsernameUTF8(Profile* profile) {
return base::UTF16ToUTF8(signin_ui_util::GetAuthenticatedUsername(profile));
}
} // namespace
// static
......@@ -273,6 +280,12 @@ void ArcAuthService::GetGoogleAccountsInArc(
DispatchAccountsInArc(std::move(callback));
}
void ArcAuthService::RequestPrimaryAccount(
RequestPrimaryAccountCallback callback) {
std::move(callback).Run(GetAuthenticatedUsernameUTF8(profile_),
GetAccountType(profile_));
}
void ArcAuthService::OnConnectionReady() {
// |TriggerAccountsPushToArc()| will not be triggered for the first session,
// when ARC has not been provisioned yet. For the first session, an account
......@@ -659,8 +672,7 @@ void ArcAuthService::OnPrimaryAccountAuthCodeFetched(
DeletePendingTokenRequest(fetcher);
if (success) {
const std::string& full_account_id =
base::UTF16ToUTF8(signin_ui_util::GetAuthenticatedUsername(profile_));
const std::string& full_account_id = GetAuthenticatedUsernameUTF8(profile_);
std::move(callback).Run(
mojom::ArcSignInStatus::SUCCESS,
CreateAccountInfo(!IsArcOptInVerificationDisabled(), auth_code,
......
......@@ -65,6 +65,8 @@ class ArcAuthService : public KeyedService,
// OS Account Manager.
void GetGoogleAccountsInArc(GetGoogleAccountsInArcCallback callback);
void RequestPrimaryAccount(RequestPrimaryAccountCallback callback) override;
// For supporting ArcServiceManager::GetService<T>().
static const char kArcServiceName[];
......
......@@ -228,9 +228,8 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
// a dangling pointer to the User.
// TODO(nya): Consider removing all users from ProfileHelper in the
// destructor of FakeChromeUserManager.
const AccountId account_id(AccountId::FromUserEmailGaiaId(
kFakeUserName, signin::GetTestGaiaIdForEmail(kFakeUserName)));
GetFakeUserManager()->RemoveUserFromList(account_id);
GetFakeUserManager()->RemoveUserFromList(
GetFakeUserManager()->GetActiveUser()->GetAccountId());
// Since ArcServiceLauncher is (re-)set up with profile() in
// SetUpOnMainThread() it is necessary to Shutdown() before the profile()
// is destroyed. ArcServiceLauncher::Shutdown() will be called again on
......@@ -255,8 +254,14 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
}
void SetAccountAndProfile(const user_manager::UserType user_type) {
const AccountId account_id(AccountId::FromUserEmailGaiaId(
kFakeUserName, signin::GetTestGaiaIdForEmail(kFakeUserName)));
AccountId account_id;
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;
switch (user_type) {
case user_manager::USER_TYPE_CHILD:
......@@ -268,6 +273,16 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
user = GetFakeUserManager()->AddPublicAccountUser(account_id);
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:
ADD_FAILURE() << "Unexpected user type " << user_type;
return;
......@@ -294,7 +309,11 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
auto* identity_test_env =
identity_test_environment_adaptor_->identity_test_env();
identity_test_env->SetAutomaticIssueOfAccessTokens(true);
identity_test_env->MakePrimaryAccountAvailable(kFakeUserName);
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);
}
profile()->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true);
profile()->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true);
......@@ -325,6 +344,8 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
DCHECK(arc_bridge_service_);
arc_bridge_service_->auth()->SetInstance(&auth_instance_);
WaitForInstanceReady(arc_bridge_service_->auth());
// Waiting for users and profiles to be setup.
base::RunLoop().RunUntilIdle();
}
AccountInfo SeedAccountInfo(const std::string& email) {
......@@ -369,6 +390,27 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
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(); }
void set_profile_name(const std::string& username) {
......@@ -409,6 +451,53 @@ class ArcAuthServiceTest : public InProcessBrowserTest {
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
// |RequestAccountInfoDeprecated| API, Chrome supplies the info configured in
// SetAccountAndProfile() method.
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Next MinVersion: 23
// Next MinVersion: 24
module arc.mojom;
......@@ -256,7 +256,7 @@ struct ArcAccountInfo {
string gaia_id;
};
// Next Method ID: 18.
// Next Method ID: 19.
interface AuthHost {
// Notifies Chrome that the authorization flow is completed and provides
// resulting |status|. If |initial_signin| is true then this indicates that
......@@ -294,6 +294,13 @@ interface AuthHost {
[MinVersion=13] ReportSupervisionChangeStatus@11(
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
// Primary/Device Account in Chrome OS Account Manager.
// 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