0

Reland "[signin] Change the "child account" status to tribool"

This is a reland of ea76009387

The original CL was reverted because it conflicted with:
https://chromium-review.googlesource.com/c/chromium/src/+/3006856

Original change's description:
> [signin] Change the "child account" status to tribool
>
> This CL moves the Tribool class out of AccountCapabilities and uses
> it for the child account status.
>
> This CL replaces false by kFalse, true by kTrue, and nullopt by
> kUnknown. This does not change the behavior, as these values have the
> same semantics.
>
> Most notable behavior changes:
> - is_child_account now starts as kUnknown, and is only changed when the
>   status is really known. Before this CL, "false" was used while the
>   status was unknown.
> - the X-Chrome-Connected header now only has the "supervised" parameter
>   when the status is known, and no "supervised" parameter otherwise.
>   Moreover, the old code was considering wrong fields (it
>   was calling IsEmpty(), but this is unrelated to childness).
> - the status is persisted on disk in a new pref, and the previous
>   boolean pref is deprecated (this is a migration).
>
> Bug: 1103228
> Change-Id: I10e6916ef8e1055c51c803d71097537737bc97fb
> Cq-Do-Not-Cancel-Tryjobs: true
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919817
> Commit-Queue: David Roger <droger@chromium.org>
> Auto-Submit: David Roger <droger@chromium.org>
> Reviewed-by: Colin Blundell <blundell@chromium.org>
> Reviewed-by: Alex Ilin <alexilin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#899911}

Bug: 1103228
Change-Id: Id0df3bc6334091f912d7c9821ed05cc92afd55d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3017962
Auto-Submit: David Roger <droger@chromium.org>
Reviewed-by: Colin Blundell <blundell@chromium.org>
Reviewed-by: Alex Ilin <alexilin@chromium.org>
Commit-Queue: David Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#900978}
This commit is contained in:
David Roger
2021-07-13 13:18:48 +00:00
committed by Chromium LUCI CQ
parent d38d56b60a
commit 5b458cad21
42 changed files with 367 additions and 198 deletions

@ -27,6 +27,7 @@
#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/primary_account_mutator.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync/base/pref_names.h"
#include "components/sync/base/user_selectable_type.h"
#include "components/sync/driver/sync_service.h"
@ -64,7 +65,7 @@ bool IsMinorMode(Profile* profile, const user_manager::User* user) {
const AccountInfo account_info =
identity_manager->FindExtendedAccountInfoByGaiaId(gaia_id);
return account_info.capabilities.can_offer_extended_chrome_sync_promos() !=
AccountCapabilities::Tribool::kTrue;
signin::Tribool::kTrue;
}
} // namespace

@ -143,10 +143,12 @@
#include "components/quirks/quirks_manager.h"
#include "components/session_manager/core/session_manager.h"
#include "components/session_manager/session_manager_types.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/accounts_mutator.h"
#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/primary_account_mutator.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync/driver/sync_service.h"
#include "components/user_manager/known_user.h"
#include "components/user_manager/user.h"
@ -1448,13 +1450,15 @@ void UserSessionManager::InitProfilePreferences(
DCHECK(is_child ==
(user_context.GetUserType() == user_manager::USER_TYPE_CHILD));
absl::optional<bool> is_under_advanced_protection;
signin::Tribool is_under_advanced_protection = signin::Tribool::kUnknown;
if (IsOnlineSignin(user_context)) {
is_under_advanced_protection = user_context.IsUnderAdvancedProtection();
is_under_advanced_protection = user_context.IsUnderAdvancedProtection()
? signin::Tribool::kTrue
: signin::Tribool::kFalse;
}
identity_manager->GetAccountsMutator()->UpdateAccountInfo(
account_id, /*is_child_account=*/is_child,
account_id, is_child ? signin::Tribool::kTrue : signin::Tribool::kFalse,
is_under_advanced_protection);
if (is_child &&

@ -273,7 +273,6 @@ class UserImageManagerTestBase : public LoginManagerTest,
account_info.locale = account_info.email;
account_info.picture_url =
embedded_test_server()->GetURL("/avatar.jpg").spec();
account_info.is_child_account = false;
signin::UpdateAccountInfoForAccount(identity_manager, account_info);
}

@ -19,6 +19,7 @@
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/webui_url_constants.h"
#include "components/google/core/common/google_util.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/variations/net/variations_http_headers.h"
#include "net/base/load_flags.h"
#include "net/base/url_util.h"
@ -227,7 +228,7 @@ void OneGoogleBarLoaderImpl::AuthenticatedURLLoader::SetRequestHeaders(
/*is_header_request=*/true, api_url_,
// Gaia ID is only needed for (drive|docs).google.com.
/*gaia_id=*/std::string(),
/* is_child_account=*/absl::nullopt, profile_mode,
/*is_child_account=*/signin::Tribool::kUnknown, profile_mode,
signin::kChromeMirrorHeaderSource,
/*force_account_consistency=*/false);
if (!chrome_connected_header_value.empty()) {

@ -14,10 +14,12 @@
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/accounts_mutator.h"
#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
#include "components/signin/public/identity_manager/scope_set.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/gaia/gaia_constants.h"
@ -271,8 +273,10 @@ void AdvancedProtectionStatusManager::OnGetIDToken(
if (is_under_advanced_protection_ !=
service_flags.is_under_advanced_protection) {
identity_manager_->GetAccountsMutator()->UpdateAccountInfo(
GetUnconsentedPrimaryAccountId(), false,
service_flags.is_under_advanced_protection);
GetUnconsentedPrimaryAccountId(),
/*is_child_account=*/signin::Tribool::kUnknown,
service_flags.is_under_advanced_protection ? signin::Tribool::kTrue
: signin::Tribool::kFalse);
} else if (service_flags.is_under_advanced_protection) {
OnAdvancedProtectionEnabled();
} else {

@ -11,8 +11,10 @@
#include "build/chromeos_buildflags.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/accounts_mutator.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@ -322,9 +324,10 @@ TEST_F(AdvancedProtectionStatusManagerTest, AccountRemoval) {
// Simulates account update.
identity_test_env_.identity_manager()
->GetAccountsMutator()
->UpdateAccountInfo(account_id,
/*is_child_account=*/false,
/*is_under_advanced_protection=*/true);
->UpdateAccountInfo(
account_id,
/*is_child_account=*/signin::Tribool::kUnknown,
/*is_under_advanced_protection=*/signin::Tribool::kTrue);
EXPECT_TRUE(aps_manager.IsUnderAdvancedProtection());
EXPECT_TRUE(aps_manager.IsRefreshScheduled());

@ -593,7 +593,7 @@ void FixAccountConsistencyRequestHeader(
int incognito_availibility,
AccountConsistencyMethod account_consistency,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
signin::Tribool is_child_account,
#if BUILDFLAG(IS_CHROMEOS_ASH)
bool is_secondary_account_addition_allowed,
#endif

@ -34,6 +34,8 @@ class GURL;
// handle signin accordingly.
namespace signin {
enum class Tribool;
// Key for ManageAccountsHeaderReceivedUserData. Exposed for testing.
extern const void* const kManageAccountsHeaderReceivedUserDataKey;
@ -99,7 +101,7 @@ void FixAccountConsistencyRequestHeader(
int incognito_availibility,
AccountConsistencyMethod account_consistency,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
signin::Tribool is_child_account,
#if BUILDFLAG(IS_CHROMEOS_ASH)
bool is_secondary_account_addition_allowed,
#endif

@ -320,7 +320,6 @@ IN_PROC_BROWSER_TEST_F(DiceWebSigninInterceptorBrowserTest, InterceptionTest) {
account_info.hosted_domain = kNoHostedDomainFound;
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
DCHECK(account_info.IsValid());
identity_test_env()->UpdateAccountInfoForAccount(account_info);
@ -408,7 +407,6 @@ IN_PROC_BROWSER_TEST_F(DiceWebSigninInterceptorBrowserTest,
account_info.hosted_domain = "example.com";
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
DCHECK(account_info.IsValid());
identity_test_env()->UpdateAccountInfoForAccount(account_info);
@ -640,7 +638,6 @@ IN_PROC_BROWSER_TEST_F(DiceWebSigninInterceptorBrowserTest, CloseSourceTab) {
account_info.hosted_domain = kNoHostedDomainFound;
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
DCHECK(account_info.IsValid());
identity_test_env()->UpdateAccountInfoForAccount(account_info);
@ -709,7 +706,6 @@ IN_PROC_BROWSER_TEST_F(DiceWebSigninInterceptorEnterpriseSwitchBrowserTest,
account_info.hosted_domain = "example.com";
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
DCHECK(account_info.IsValid());
identity_test_env()->UpdateAccountInfoForAccount(account_info);
@ -790,7 +786,6 @@ IN_PROC_BROWSER_TEST_F(DiceWebSigninInterceptorEnterpriseSwitchBrowserTest,
account_info.hosted_domain = "example.com";
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
DCHECK(account_info.IsValid());
identity_test_env()->UpdateAccountInfoForAccount(account_info);
// Create another profile with a browser window.

@ -86,7 +86,6 @@ void MakeValidAccountInfo(AccountInfo* info) {
info->hosted_domain = kNoHostedDomainFound;
info->locale = "en";
info->picture_url = "https://example.com";
info->is_child_account = false;
DCHECK(info->IsValid());
}

@ -28,6 +28,7 @@
#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync/driver/sync_service.h"
#include "content/public/test/browser_test.h"
#include "google_apis/gaia/core_account_id.h"
@ -741,7 +742,7 @@ IN_PROC_BROWSER_TEST_F(LiveSignInTest,
identity_manager()->FindExtendedAccountInfoByAccountId(
core_account_info.account_id);
EXPECT_EQ(account_info.capabilities.can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kTrue);
Tribool::kTrue);
}
} // namespace test

@ -16,7 +16,9 @@
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync/base/pref_names.h"
#include "components/sync/driver/sync_service.h"
#include "content/public/browser/render_process_host.h"
@ -88,15 +90,9 @@ void HeaderModificationDelegateImpl::ProcessRequest(
IdentityManagerFactory::GetForProfile(profile_);
CoreAccountInfo account =
identity_manager->GetPrimaryAccountInfo(consent_level);
absl::optional<bool> is_child_account = absl::nullopt;
if (!account.IsEmpty()) {
AccountInfo extended_account_info =
identity_manager->FindExtendedAccountInfo(account);
if (!extended_account_info.IsEmpty()) {
is_child_account =
absl::make_optional<bool>(extended_account_info.is_child_account);
}
}
signin::Tribool is_child_account =
// Defaults to kUnknown if the account is not found.
identity_manager->FindExtendedAccountInfo(account).is_child_account;
int incognito_mode_availability =
prefs->GetInteger(prefs::kIncognitoModeAvailability);

@ -26,8 +26,10 @@
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h"
#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_user_settings.h"
#include "content/public/browser/browser_context.h"
@ -276,7 +278,7 @@ void ChildAccountService::OnExtendedAccountInfoUpdated(
if (info.account_id != auth_account_id)
return;
SetIsChildAccount(info.is_child_account);
SetIsChildAccount(info.is_child_account == signin::Tribool::kTrue);
}
void ChildAccountService::OnExtendedAccountInfoRemoved(

@ -95,7 +95,6 @@ AccountInfo FillAccountInfo(
account_info.hosted_domain = hosted_domain;
account_info.locale = "en";
account_info.picture_url = "https://get-avatar.com/foo";
account_info.is_child_account = false;
return account_info;
}

@ -25,6 +25,7 @@
#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
#include "chrome/common/channel_info.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/url_formatter/url_fixer.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
@ -247,7 +248,8 @@ void FamilyLinkUserInternalsMessageHandler::SendBasicInfo() {
AddSectionEntry(section_user, "Given name", account.given_name);
AddSectionEntry(section_user, "Hosted domain", account.hosted_domain);
AddSectionEntry(section_user, "Locale", account.locale);
AddSectionEntry(section_user, "Is child", account.is_child_account);
AddSectionEntry(section_user, "Is child",
TriboolToString(account.is_child_account));
AddSectionEntry(section_user, "Is valid", account.IsValid());
}
}

@ -15,6 +15,7 @@
#include "build/chromeos_buildflags.h"
#include "components/google/core/common/google_util.h"
#include "components/signin/core/browser/cookie_settings_util.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "url/gurl.h"
@ -83,9 +84,9 @@ std::string ChromeConnectedHeaderHelper::BuildRequestCookieIfPossible(
// Child accounts are not supported on iOS, so it is preferred to not include
// this information in the ChromeConnected cookie.
return chrome_connected_helper.BuildRequestHeader(
false /* is_header_request */, url, gaia_id,
absl::nullopt /* is_child_account */, profile_mode_mask, "" /* source */,
false /* force_account_consistency */);
/*is_header_request=*/false, url, gaia_id,
/*is_child_account=*/Tribool::kUnknown, profile_mode_mask,
/*source=*/std::string(), /*force_account_consistency=*/false);
}
// static
@ -188,7 +189,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
bool is_header_request,
const GURL& url,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
Tribool is_child_account,
int profile_mode_mask,
const std::string& source,
bool force_account_consistency) {
@ -232,10 +233,17 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
account_consistency_ == AccountConsistencyMethod::kMirror;
parts.push_back(base::StringPrintf("%s=%s", kEnableAccountConsistencyAttrName,
is_mirror_enabled ? "true" : "false"));
if (is_child_account.has_value()) {
parts.push_back(
base::StringPrintf("%s=%s", kSupervisedAttrName,
is_child_account.value() ? "true" : "false"));
switch (is_child_account) {
case Tribool::kTrue:
parts.push_back(base::StringPrintf("%s=%s", kSupervisedAttrName, "true"));
break;
case Tribool::kFalse:
parts.push_back(
base::StringPrintf("%s=%s", kSupervisedAttrName, "false"));
break;
case Tribool::kUnknown:
// Do not add the supervised parameter.
break;
}
parts.push_back(base::StringPrintf(
"%s=%s", kConsistencyEnabledByDefaultAttrName, "false"));

@ -15,6 +15,8 @@ class GURL;
namespace signin {
enum class Tribool;
// Name of the cookie used by Chrome sign-in to inform GAIA that an
// authenticating user is already signed in to Chrome. Because it is not
// possible to intercept headers from iOS WKWebView, Chrome requires this cookie
@ -47,7 +49,7 @@ class ChromeConnectedHeaderHelper : public SigninHeaderHelper {
std::string BuildRequestHeader(bool is_header_request,
const GURL& url,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
Tribool is_child_account,
int profile_mode_mask,
const std::string& source,
bool force_account_consistency);

@ -170,7 +170,7 @@ void AppendOrRemoveMirrorRequestHeader(
RequestAdapter* request,
const GURL& redirect_url,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
Tribool is_child_account,
AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask,

@ -14,7 +14,6 @@
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/base/signin_buildflags.h"
#include "google_apis/gaia/core_account_id.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
namespace content_settings {
@ -27,6 +26,8 @@ class HttpRequestHeaders;
namespace signin {
enum class Tribool;
// Profile mode flags.
enum ProfileMode {
PROFILE_MODE_DEFAULT = 0,
@ -246,7 +247,7 @@ void AppendOrRemoveMirrorRequestHeader(
RequestAdapter* request,
const GURL& redirect_url,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
Tribool is_child_account,
AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask,

@ -19,6 +19,7 @@
#include "components/signin/core/browser/chrome_connected_header_helper.h"
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/base/signin_buildflags.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/http/http_request_headers.h"
@ -99,10 +100,9 @@ class SigninHeaderHelperTest : public testing::Test {
PROFILE_MODE_DEFAULT));
}
net::HttpRequestHeaders CreateRequest(
const GURL& url,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account) {
net::HttpRequestHeaders CreateRequest(const GURL& url,
const std::string& gaia_id,
Tribool is_child_account) {
net::HttpRequestHeaders original_headers;
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
@ -130,7 +130,7 @@ class SigninHeaderHelperTest : public testing::Test {
void CheckMirrorHeaderRequest(const GURL& url,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
Tribool is_child_account,
const std::string& expected_request) {
net::HttpRequestHeaders headers =
CreateRequest(url, gaia_id, is_child_account);
@ -141,7 +141,7 @@ class SigninHeaderHelperTest : public testing::Test {
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void CheckDiceHeaderRequest(const GURL& url,
const std::string& gaia_id,
const absl::optional<bool>& is_child_account,
Tribool is_child_account,
const std::string& expected_mirror_request,
const std::string& expected_dice_request) {
net::HttpRequestHeaders headers =
@ -184,7 +184,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://docs.google.com"), /*gaia_id=*/"",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), /*gaia_id=*/"",
@ -198,7 +198,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) {
TEST_F(SigninHeaderHelperTest, TestEligibleForConsistencyRequestGaiaOrigin) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,eligible_for_consistency=true");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
"eligible_for_consistency=true");
@ -210,7 +210,7 @@ TEST_F(SigninHeaderHelperTest,
TestNoEligibleForConsistencyRequestNonGaiaOrigin) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), /*gaia_id=*/"",
/*is_child_account=*/absl::nullopt, "");
/*is_child_account=*/Tribool::kUnknown, "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), /*gaia_id=*/"", "");
}
@ -221,7 +221,7 @@ TEST_F(SigninHeaderHelperTest, TestForceAccountConsistencyMobile) {
force_account_consistency_ = true;
CheckMirrorHeaderRequest(
GURL("https://docs.google.com"), /*gaia_id=*/"",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
}
@ -232,7 +232,7 @@ TEST_F(SigninHeaderHelperTest, TestForceAccountConsistencyMobile) {
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), /*gaia_id=*/"",
/*is_child_account=*/absl::nullopt, "");
/*is_child_account=*/Tribool::kUnknown, "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), /*gaia_id=*/"", "");
}
#endif
@ -243,7 +243,7 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
account_consistency_ = AccountConsistencyMethod::kMirror;
cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt, "");
/*is_child_account=*/Tribool::kUnknown, "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "0123456789", "");
}
@ -251,7 +251,7 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestExternalURL) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://foo.com"), "0123456789",
/*is_child_account=*/absl::nullopt, "");
/*is_child_account=*/Tribool::kUnknown, "");
CheckMirrorCookieRequest(GURL("https://foo.com"), "0123456789", "");
}
@ -261,7 +261,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleTLD) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://google.fr"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://google.de"), "0123456789",
@ -275,7 +275,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleCom) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://www.google.com"), "0123456789",
@ -290,7 +290,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComNoProfileConsistency) {
original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), GURL(), "0123456789",
/*is_child_account=*/absl::nullopt, account_consistency_,
/*is_child_account=*/Tribool::kUnknown, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
CheckAccountConsistencyHeaderRequest(request_adapter.GetFinalHeaders(),
@ -305,7 +305,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComProfileConsistency) {
original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), GURL(), "0123456789",
/*is_child_account=*/absl::nullopt, account_consistency_,
/*is_child_account=*/Tribool::kUnknown, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
CheckAccountConsistencyHeaderRequest(
@ -318,17 +318,17 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComSupervised) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
/*is_child_account=*/absl::optional<bool>(true),
/*is_child_account=*/Tribool::kTrue,
"source=TestSource,mode=0,enable_account_consistency=true,"
"supervised=true,consistency_enabled_by_default=false");
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
/*is_child_account=*/absl::optional<bool>(false),
/*is_child_account=*/Tribool::kFalse,
"source=TestSource,mode=0,enable_account_consistency=true,"
"supervised=false,consistency_enabled_by_default=false");
}
@ -341,7 +341,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) {
// No request when account consistency is disabled.
account_consistency_ = AccountConsistencyMethod::kDisabled;
CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
/*expected_request=*/"");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), "0123456789",
/*expected_request=*/"");
@ -350,7 +350,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) {
// No request when Mirror account consistency enabled, but user not signed in
// to Chrome.
CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
/*expected_request=*/"");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
/*expected_request=*/"");
@ -359,7 +359,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) {
// signed in to Chrome.
CheckMirrorHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), "0123456789",
@ -373,7 +373,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
// ChromeConnected but no Dice for Docs URLs.
CheckDiceHeaderRequest(
GURL("https://docs.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,id=0123456789,mode=0,enable_account_consistency=false,"
"consistency_enabled_by_default=false",
/*expected_dice_request=*/"");
@ -384,8 +384,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
ASSERT_FALSE(client_id.empty());
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
/*is_child_account=*/Tribool::kUnknown, /*expected_mirror_request=*/"",
base::StringPrintf(
"version=%s,client_id=%s,device_id=DeviceID,signin_mode=all_accounts,"
"signout_mode=show_confirmation",
@ -395,8 +394,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
sync_enabled_ = true;
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
/*is_child_account=*/Tribool::kUnknown, /*expected_mirror_request=*/"",
base::StringPrintf("version=%s,client_id=%s,device_id=DeviceID,"
"sync_account_id=0123456789,signin_mode=all_accounts,"
"signout_mode=show_confirmation",
@ -405,7 +403,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
// No ChromeConnected and no Dice for other URLs.
CheckDiceHeaderRequest(GURL("https://www.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
/*expected_mirror_request=*/"",
/*expected_dice_request=*/"");
}
@ -419,7 +417,7 @@ TEST_F(SigninHeaderHelperTest, DiceCookiesBlocked) {
ASSERT_FALSE(client_id.empty());
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt, "",
/*is_child_account=*/Tribool::kUnknown, /*expected_mirror_request=*/"",
base::StringPrintf(
"version=%s,client_id=%s,device_id=DeviceID,signin_mode=all_accounts,"
"signout_mode=show_confirmation",
@ -431,10 +429,10 @@ TEST_F(SigninHeaderHelperTest, TestNoDiceRequestWhenDisabled) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false",
"");
/*expected_dice_request=*/"");
}
TEST_F(SigninHeaderHelperTest, TestDiceEmptyDeviceID) {
@ -446,8 +444,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceEmptyDeviceID) {
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
/*is_child_account=*/Tribool::kUnknown, /*expected_mirror_request=*/"",
base::StringPrintf("version=%s,client_id=%s,signin_mode=all_accounts,"
"signout_mode=show_confirmation",
kDiceProtocolVersion, client_id.c_str()));
@ -461,8 +458,7 @@ TEST_F(SigninHeaderHelperTest, TestSignoutConfirmation) {
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
/*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
/*is_child_account=*/Tribool::kUnknown, /*expected_mirror_request=*/"",
base::StringPrintf(
"version=%s,client_id=%s,device_id=DeviceID,signin_mode=all_accounts,"
"signout_mode=show_confirmation",
@ -480,10 +476,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderRequestDriveSignedOut) {
AccountConsistencyMethod::kMirror, AccountConsistencyMethod::kDice}) {
account_consistency_ = account_consistency;
CheckMirrorHeaderRequest(url, /*gaia_id=*/"",
/*is_child_account=*/absl::nullopt,
/*expected_request=*/"");
CheckMirrorCookieRequest(url, /*gaia_id=*/"",
/*is_child_account=*/Tribool::kUnknown,
/*expected_request=*/"");
CheckMirrorCookieRequest(url, /*gaia_id=*/"", /*expected_request=*/"");
}
}
}
@ -496,11 +491,10 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderRequestDriveSignedIn) {
account_consistency_ = AccountConsistencyMethod::kMirror;
// Request with Gaia ID when Mirror account consistency is enabled and user
// is signed in to Chrome.
CheckMirrorHeaderRequest(url, /*gaia_id=*/"0123456789",
/*is_child_account=*/absl::nullopt,
"source=TestSource,id=0123456789,mode=0,enable_"
"account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorHeaderRequest(
url, /*gaia_id=*/"0123456789", /*is_child_account=*/Tribool::kUnknown,
"source=TestSource,id=0123456789,mode=0,"
"enable_account_consistency=true,consistency_enabled_by_default=false");
// Cookie does not include the Gaia ID even when Mirror account consistency
// is enabled and user is signed in to Chrome.
CheckMirrorCookieRequest(url, /*gaia_id=*/"0123456789",
@ -509,11 +503,11 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderRequestDriveSignedIn) {
account_consistency_ = AccountConsistencyMethod::kDice;
// Request with Gaia ID when DICE account consistency is enabled and user is
// opted in to sycn.
// opted in to sync.
CheckMirrorHeaderRequest(url, /*gaia_id=*/"0123456789",
/*is_child_account=*/absl::nullopt,
"source=TestSource,id=0123456789,mode=0,enable_"
"account_consistency=false,"
/*is_child_account=*/Tribool::kUnknown,
"source=TestSource,id=0123456789,mode=0,"
"enable_account_consistency=false,"
"consistency_enabled_by_default=false");
}
}
@ -661,7 +655,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) {
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), redirect_url, gaia_id,
/*is_child_account=*/absl::nullopt, account_consistency_,
/*is_child_account=*/Tribool::kUnknown, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
EXPECT_TRUE(
@ -680,7 +674,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) {
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), redirect_url, gaia_id,
/*is_child_account=*/absl::nullopt, account_consistency_,
/*is_child_account=*/Tribool::kUnknown, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
EXPECT_FALSE(
@ -700,7 +694,7 @@ TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) {
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), redirect_url, gaia_id,
/*is_child_account=*/absl::nullopt, account_consistency_,
/*is_child_account=*/Tribool::kUnknown, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
std::string header;

@ -34,6 +34,7 @@
#if defined(OS_ANDROID)
#include "components/signin/internal/identity_manager/child_account_info_fetcher_android.h"
#include "components/signin/public/identity_manager/tribool.h"
#endif
namespace {
@ -213,8 +214,14 @@ void AccountFetcherService::StartFetchingChildInfo(
}
void AccountFetcherService::ResetChildInfo() {
if (!child_request_account_id_.empty())
SetIsChildAccount(child_request_account_id_, false);
if (!child_request_account_id_.empty()) {
AccountInfo account_info =
account_tracker_service_->GetAccountInfo(child_request_account_id_);
// TODO(https://crbug.com/1226501): Reset the status to kUnknown, rather
// than kFalse.
if (account_info.is_child_account != signin::Tribool::kUnknown)
SetIsChildAccount(child_request_account_id_, false);
}
child_request_account_id_ = CoreAccountId();
child_info_request_.reset();
}

@ -47,6 +47,10 @@ class ImageDecoder;
class ImageFetcherImpl;
} // namespace image_fetcher
namespace signin {
enum class Tribool;
}
class AccountFetcherService : public ProfileOAuth2TokenServiceObserver {
public:
// Name of the preference that tracks the int64_t representation of the last
@ -127,8 +131,8 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver {
#if defined(OS_ANDROID)
void StartFetchingChildInfo(const CoreAccountId& account_id);
// If there is more than one account in a profile, we forcibly reset the
// child status for an account to be false.
// Resets the child status to false if it is true. If there is more than one
// account in a profile, only the main account can be a child.
void ResetChildInfo();
#endif

@ -7,6 +7,7 @@
#include "components/signin/internal/identity_manager/account_capabilities_constants.h"
#include "components/signin/public/identity_manager/account_capabilities.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "testing/platform_test.h"
namespace {
@ -183,7 +184,7 @@ TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue) {
ASSERT_TRUE(capabilities.has_value());
EXPECT_EQ(capabilities->can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kTrue);
signin::Tribool::kTrue);
}
TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue_EmptyList) {
@ -192,7 +193,7 @@ TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue_EmptyList) {
ASSERT_TRUE(capabilities.has_value());
EXPECT_EQ(capabilities->can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kUnknown);
signin::Tribool::kUnknown);
}
TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue_SeveralCapabilities) {
@ -203,7 +204,7 @@ TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue_SeveralCapabilities) {
ASSERT_TRUE(capabilities.has_value());
EXPECT_EQ(capabilities->can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kFalse);
signin::Tribool::kFalse);
}
TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue_NonBooleanValue) {
@ -220,7 +221,7 @@ TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue_NonBooleanValue) {
ASSERT_TRUE(capabilities.has_value());
EXPECT_EQ(capabilities->can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kUnknown);
signin::Tribool::kUnknown);
}
TEST_F(AccountInfoUtilTest, AccountCapabilitiesFromValue_NotADictionary) {

@ -32,6 +32,7 @@
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/signin/public/identity_manager/account_capabilities.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "ui/gfx/image/image.h"
#if defined(OS_ANDROID)
@ -50,10 +51,14 @@ const char kAccountLocalePath[] = "locale";
const char kAccountPictureURLPath[] = "picture_url";
const char kLastDownloadedImageURLWithSizePath[] =
"last_downloaded_image_url_with_size";
const char kAccountChildAccountStatusPath[] = "is_child_account";
const char kAccountChildAttributePath[] = "is_supervised_child";
const char kAdvancedProtectionAccountStatusPath[] =
"is_under_advanced_protection";
// This key is deprecated since 2021/07 and should be removed after migration.
// It was replaced by kAccountChildAttributePath.
const char kDeprecatedChildStatusPath[] = "is_child_account";
// Account folders used for storing account related data at disk.
const base::FilePath::CharType kAccountsFolder[] =
FILE_PATH_LITERAL("Accounts");
@ -104,21 +109,27 @@ void RemoveImage(const base::FilePath& image_path) {
void SetAccountCapabilityPath(base::Value* value,
base::StringPiece path,
AccountCapabilities::Tribool state) {
if (state == AccountCapabilities::Tribool::kUnknown)
value->RemovePath(path);
else
value->SetBoolPath(path, state == AccountCapabilities::Tribool::kTrue);
signin::Tribool state) {
value->SetIntPath(path, static_cast<int>(state));
}
AccountCapabilities::Tribool FindAccountCapabilityPath(const base::Value& value,
base::StringPiece path) {
absl::optional<bool> boolean_value = value.FindBoolPath(path);
if (!boolean_value.has_value())
return AccountCapabilities::Tribool::kUnknown;
return *boolean_value ? AccountCapabilities::Tribool::kTrue
: AccountCapabilities::Tribool::kFalse;
signin::Tribool FindAccountCapabilityPath(const base::Value& value,
base::StringPiece path) {
absl::optional<int> capability = value.FindIntPath(path);
if (!capability.has_value())
return signin::Tribool::kUnknown;
switch (capability.value()) {
case static_cast<int>(signin::Tribool::kTrue):
return signin::Tribool::kTrue;
case static_cast<int>(signin::Tribool::kFalse):
return signin::Tribool::kFalse;
case static_cast<int>(signin::Tribool::kUnknown):
return signin::Tribool::kUnknown;
default:
LOG(ERROR) << "Unexpected capability value (" << capability.value()
<< ") for path: " << path;
return signin::Tribool::kUnknown;
}
}
} // namespace
@ -236,7 +247,6 @@ void AccountTrackerService::StartTrackingAccount(
DVLOG(1) << "StartTracking " << account_id;
AccountInfo account_info;
account_info.account_id = account_id;
account_info.is_child_account = false;
accounts_.insert(std::make_pair(account_id, account_info));
}
}
@ -311,9 +321,11 @@ void AccountTrackerService::SetIsChildAccount(const CoreAccountId& account_id,
bool is_child_account) {
DCHECK(base::Contains(accounts_, account_id)) << account_id.ToString();
AccountInfo& account_info = accounts_[account_id];
if (account_info.is_child_account == is_child_account)
signin::Tribool new_status =
is_child_account ? signin::Tribool::kTrue : signin::Tribool::kFalse;
if (account_info.is_child_account == new_status)
return;
account_info.is_child_account = is_child_account;
account_info.is_child_account = new_status;
if (!account_info.gaia.empty())
NotifyAccountUpdated(account_info);
SaveToPrefs(account_info);
@ -539,7 +551,7 @@ void AccountTrackerService::LoadFromPrefs() {
const base::ListValue* list = pref_service_->GetList(prefs::kAccountInfo);
std::set<CoreAccountId> to_remove;
for (size_t i = 0; i < list->GetSize(); ++i) {
const base::DictionaryValue* dict;
const base::DictionaryValue* dict = nullptr;
if (list->GetDictionary(i, &dict)) {
std::string value;
if (dict->GetString(kAccountKeyPath, &value)) {
@ -571,9 +583,23 @@ void AccountTrackerService::LoadFromPrefs() {
if (dict->GetString(kLastDownloadedImageURLWithSizePath, &value))
account_info.last_downloaded_image_url_with_size = value;
bool is_child_account = false;
if (dict->GetBoolean(kAccountChildAccountStatusPath, &is_child_account))
account_info.is_child_account = is_child_account;
if (absl::optional<bool> is_child_status =
dict->FindBoolKey(kDeprecatedChildStatusPath)) {
account_info.is_child_account = is_child_status.value()
? signin::Tribool::kTrue
: signin::Tribool::kFalse;
// Migrate to kAccountChildAttributePath.
ListPrefUpdate update(pref_service_, prefs::kAccountInfo);
base::DictionaryValue* update_dict = nullptr;
update->GetDictionary(i, &update_dict);
DCHECK(update_dict);
SetAccountCapabilityPath(update_dict, kAccountChildAttributePath,
account_info.is_child_account);
update_dict->RemoveKey(kDeprecatedChildStatusPath);
} else {
account_info.is_child_account =
FindAccountCapabilityPath(*dict, kAccountChildAttributePath);
}
bool is_under_advanced_protection = false;
if (dict->GetBoolean(kAdvancedProtectionAccountStatusPath,
@ -584,13 +610,13 @@ void AccountTrackerService::LoadFromPrefs() {
switch (FindAccountCapabilityPath(
*dict, kCanOfferExtendedChromeSyncPromosCapabilityPrefsPath)) {
case AccountCapabilities::Tribool::kUnknown:
case signin::Tribool::kUnknown:
break;
case AccountCapabilities::Tribool::kTrue:
case signin::Tribool::kTrue:
account_info.capabilities.set_can_offer_extended_chrome_sync_promos(
true);
break;
case AccountCapabilities::Tribool::kFalse:
case signin::Tribool::kFalse:
account_info.capabilities.set_can_offer_extended_chrome_sync_promos(
false);
break;
@ -657,8 +683,8 @@ void AccountTrackerService::SaveToPrefs(const AccountInfo& account_info) {
dict->SetString(kAccountGivenNamePath, account_info.given_name);
dict->SetString(kAccountLocalePath, account_info.locale);
dict->SetString(kAccountPictureURLPath, account_info.picture_url);
dict->SetBoolean(kAccountChildAccountStatusPath,
account_info.is_child_account);
SetAccountCapabilityPath(dict, kAccountChildAttributePath,
account_info.is_child_account);
dict->SetBoolean(kAdvancedProtectionAccountStatusPath,
account_info.is_under_advanced_protection);
// |kLastDownloadedImageURLWithSizePath| should only be set after the GAIA

@ -31,6 +31,7 @@
#include "components/signin/public/base/test_signin_client.h"
#include "components/signin/public/identity_manager/account_capabilities.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "google_apis/gaia/gaia_oauth_client.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
@ -268,8 +269,8 @@ class AccountTrackerServiceTest : public testing::Test {
void CheckAccountCapabilities(AccountKey account_key,
const AccountInfo& info) {
EXPECT_EQ(AccountKeyToAccountCapability(account_key)
? AccountCapabilities::Tribool::kTrue
: AccountCapabilities::Tribool::kFalse,
? signin::Tribool::kTrue
: signin::Tribool::kFalse,
info.capabilities.can_offer_extended_chrome_sync_promos());
}
@ -985,7 +986,7 @@ TEST_F(AccountTrackerServiceTest, Persistence) {
ASSERT_EQ(1u, infos.size());
CheckAccountDetails(kAccountKeyBeta, infos[0]);
CheckAccountCapabilities(kAccountKeyBeta, infos[0]);
EXPECT_TRUE(infos[0].is_child_account);
EXPECT_EQ(signin::Tribool::kTrue, infos[0].is_child_account);
#if !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_ANDROID) && !defined(OS_IOS)
EXPECT_TRUE(infos[0].is_under_advanced_protection);
#else
@ -998,6 +999,60 @@ TEST_F(AccountTrackerServiceTest, Persistence) {
ASSERT_TRUE(scoped_user_data_dir.Delete());
}
TEST_F(AccountTrackerServiceTest, ChildStatusMigration) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(switches::kAccountIdMigration);
#endif
base::ScopedTempDir scoped_user_data_dir;
ASSERT_TRUE(scoped_user_data_dir.CreateUniqueTempDir());
// Create a tracker and add an account. This should cause the account to be
// saved to persistence.
ResetAccountTrackerWithPersistence(scoped_user_data_dir.GetPath());
SimulateTokenAvailable(kAccountKeyAlpha);
ReturnAccountInfoFetchSuccess(kAccountKeyAlpha);
// The child status is unknown, and none of the child-related keys should be
// set.
EXPECT_EQ(signin::Tribool::kUnknown,
account_tracker()
->GetAccountInfo(AccountKeyToAccountId(kAccountKeyAlpha))
.is_child_account);
ListPrefUpdate update(prefs(), prefs::kAccountInfo);
base::DictionaryValue* dict = nullptr;
update->GetDictionary(0, &dict);
ASSERT_TRUE(dict);
const char kDeprecatedChildKey[] = "is_child_account";
const char kNewChildKey[] = "is_supervised_child";
// The deprecated key is not set.
EXPECT_FALSE(dict->FindBoolKey(kDeprecatedChildKey));
// Set the child status using the deprecated key, and reload the account.
dict->SetBoolean(kDeprecatedChildKey, true);
dict->RemoveKey(kNewChildKey);
ClearAccountTrackerEvents();
ResetAccountTrackerWithPersistence(scoped_user_data_dir.GetPath());
EXPECT_TRUE(CheckAccountTrackerEvents(
{TrackingEvent(UPDATED, AccountKeyToAccountId(kAccountKeyAlpha),
AccountKeyToGaiaId(kAccountKeyAlpha),
AccountKeyToEmail(kAccountKeyAlpha))}));
// Check that the migration happened.
std::vector<AccountInfo> infos = account_tracker()->GetAccounts();
ASSERT_EQ(1u, infos.size());
CheckAccountDetails(kAccountKeyAlpha, infos[0]);
// The deprecated key has been read.
EXPECT_EQ(signin::Tribool::kTrue, infos[0].is_child_account);
// The deprecated key has been removed.
EXPECT_FALSE(dict->FindBoolKey(kDeprecatedChildKey));
// The new key has been written.
absl::optional<int> new_key = dict->FindIntKey(kNewChildKey);
ASSERT_TRUE(new_key.has_value());
EXPECT_EQ(static_cast<int>(signin::Tribool::kTrue), new_key.value());
}
TEST_F(AccountTrackerServiceTest, SeedAccountInfo) {
EXPECT_TRUE(account_tracker()->GetAccounts().empty());
@ -1399,7 +1454,7 @@ TEST_F(AccountTrackerServiceTest, ChildAccountBasic) {
EXPECT_TRUE(CheckAccountTrackerEvents({}));
AccountInfo info = account_tracker()->GetAccountInfo(
AccountKeyToAccountId(kAccountKeyChild));
EXPECT_TRUE(info.is_child_account);
EXPECT_EQ(signin::Tribool::kTrue, info.is_child_account);
SimulateTokenRevoked(kAccountKeyChild);
}
@ -1423,7 +1478,7 @@ TEST_F(AccountTrackerServiceTest, ChildAccountUpdatedAndRevoked) {
}));
AccountInfo info = account_tracker()->GetAccountInfo(
AccountKeyToAccountId(kAccountKeyChild));
EXPECT_FALSE(info.is_child_account);
EXPECT_EQ(signin::Tribool::kFalse, info.is_child_account);
SimulateTokenRevoked(kAccountKeyChild);
EXPECT_TRUE(CheckAccountTrackerEvents({
TrackingEvent(REMOVED, AccountKeyToAccountId(kAccountKeyChild),
@ -1452,7 +1507,7 @@ TEST_F(AccountTrackerServiceTest, ChildAccountUpdatedAndRevokedWithUpdate) {
}));
AccountInfo info = account_tracker()->GetAccountInfo(
AccountKeyToAccountId(kAccountKeyChild));
EXPECT_TRUE(info.is_child_account);
EXPECT_EQ(signin::Tribool::kTrue, info.is_child_account);
SimulateTokenRevoked(kAccountKeyChild);
#if defined(OS_ANDROID)
// On Android, is_child_account is set to false before removing it.
@ -1528,7 +1583,7 @@ TEST_F(AccountTrackerServiceTest, ChildAccountGraduation) {
#endif
AccountInfo info = account_tracker()->GetAccountInfo(
AccountKeyToAccountId(kAccountKeyChild));
EXPECT_TRUE(info.is_child_account);
EXPECT_EQ(signin::Tribool::kTrue, info.is_child_account);
ReturnFetchResults(GaiaUrls::GetInstance()->oauth_user_info_url(),
net::HTTP_OK,
GenerateValidTokenInfoResponse(kAccountKeyChild));
@ -1548,7 +1603,7 @@ TEST_F(AccountTrackerServiceTest, ChildAccountGraduation) {
#endif
info = account_tracker()->GetAccountInfo(
AccountKeyToAccountId(kAccountKeyChild));
EXPECT_FALSE(info.is_child_account);
EXPECT_EQ(signin::Tribool::kFalse, info.is_child_account);
EXPECT_TRUE(CheckAccountTrackerEvents({
TrackingEvent(UPDATED, AccountKeyToAccountId(kAccountKeyChild),
AccountKeyToGaiaId(kAccountKeyChild),

@ -12,6 +12,7 @@
#include "components/signin/public/base/device_id_helper.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/gaia_constants.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@ -63,16 +64,17 @@ CoreAccountId AccountsMutatorImpl::AddOrUpdateAccount(
void AccountsMutatorImpl::UpdateAccountInfo(
const CoreAccountId& account_id,
absl::optional<bool> is_child_account,
absl::optional<bool> is_under_advanced_protection) {
if (is_child_account.has_value()) {
account_tracker_service_->SetIsChildAccount(account_id,
is_child_account.value());
Tribool is_child_account,
Tribool is_under_advanced_protection) {
// kUnknown is used by callers when they do not want to update the value.
if (is_child_account != Tribool::kUnknown) {
account_tracker_service_->SetIsChildAccount(
account_id, is_child_account == Tribool::kTrue);
}
if (is_under_advanced_protection.has_value()) {
if (is_under_advanced_protection != Tribool::kUnknown) {
account_tracker_service_->SetIsAdvancedProtectionAccount(
account_id, is_under_advanced_protection.value());
account_id, is_under_advanced_protection == Tribool::kTrue);
}
}

@ -40,10 +40,9 @@ class AccountsMutatorImpl : public AccountsMutator {
const std::string& refresh_token,
bool is_under_advanced_protection,
signin_metrics::SourceForRefreshTokenOperation source) override;
void UpdateAccountInfo(
const CoreAccountId& account_id,
absl::optional<bool> is_child_account,
absl::optional<bool> is_under_advanced_protection) override;
void UpdateAccountInfo(const CoreAccountId& account_id,
Tribool is_child_account,
Tribool is_under_advanced_protection) override;
void RemoveAccount(
const CoreAccountId& account_id,
signin_metrics::SourceForRefreshTokenOperation source) override;

@ -67,7 +67,6 @@ AccountInfo CreateTestAccountInfo(const std::string& name,
}
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
EXPECT_EQ(is_valid, account_info.IsValid());
return account_info;
}

@ -69,7 +69,6 @@ class OAuth2TokenServiceDelegateAndroidTest : public testing::Test {
account_info.hosted_domain = "example.com";
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
account_info.account_id = account_tracker_service_.PickAccountIdForAccount(
account_info.gaia, account_info.email);

@ -257,7 +257,6 @@ class ProfileOAuth2TokenServiceDelegateChromeOSTest : public testing::Test {
account_info.hosted_domain = "example.com";
account_info.locale = "en";
account_info.picture_url = "https://example.com";
account_info.is_child_account = false;
account_info.account_id = account_tracker_service_.PickAccountIdForAccount(
account_info.gaia, account_info.email);

@ -43,6 +43,8 @@ source_set("identity_manager") {
"primary_account_mutator.h",
"scope_set.h",
"set_accounts_in_cookie_result.h",
"tribool.cc",
"tribool.h",
"ubertoken_fetcher.cc",
"ubertoken_fetcher.h",
]

@ -3,15 +3,17 @@
// found in the LICENSE file.
#include "components/signin/public/identity_manager/account_capabilities.h"
#include "components/signin/public/identity_manager/tribool.h"
bool AccountCapabilities::AreAllCapabilitiesKnown() const {
return can_offer_extended_chrome_sync_promos_ != Tribool::kUnknown;
return can_offer_extended_chrome_sync_promos_ != signin::Tribool::kUnknown;
}
bool AccountCapabilities::UpdateWith(const AccountCapabilities& other) {
bool modified = false;
if (other.can_offer_extended_chrome_sync_promos_ != Tribool::kUnknown &&
if (other.can_offer_extended_chrome_sync_promos_ !=
signin::Tribool::kUnknown &&
other.can_offer_extended_chrome_sync_promos_ !=
can_offer_extended_chrome_sync_promos_) {
can_offer_extended_chrome_sync_promos_ =

@ -5,25 +5,25 @@
#ifndef COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_ACCOUNT_CAPABILITIES_H_
#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_ACCOUNT_CAPABILITIES_H_
#include "components/signin/public/identity_manager/tribool.h"
// Stores the information about account capabilities. Capabilities provide
// information about state and features of Gaia accounts.
class AccountCapabilities {
public:
// TODO(https://crbug.com/1213071): share this enum with AccountInfo.
enum class Tribool { kTrue, kFalse, kUnknown };
// Chrome can offer extended promos for turning on Sync to accounts with this
// capability.
Tribool can_offer_extended_chrome_sync_promos() const {
signin::Tribool can_offer_extended_chrome_sync_promos() const {
return can_offer_extended_chrome_sync_promos_;
}
void set_can_offer_extended_chrome_sync_promos(bool value) {
can_offer_extended_chrome_sync_promos_ =
value ? Tribool::kTrue : Tribool::kFalse;
value ? signin::Tribool::kTrue : signin::Tribool::kFalse;
}
// Whether none of the capabilities has `Tribool::kUnknown`.
// Whether none of the capabilities has `signin::Tribool::kUnknown`.
bool AreAllCapabilitiesKnown() const;
// Updates the fields of `this` with known fields of `other`. Returns whether
@ -31,7 +31,8 @@ class AccountCapabilities {
bool UpdateWith(const AccountCapabilities& other);
private:
Tribool can_offer_extended_chrome_sync_promos_ = Tribool::kUnknown;
signin::Tribool can_offer_extended_chrome_sync_promos_ =
signin::Tribool::kUnknown;
};
#endif // COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_ACCOUNT_CAPABILITIES_H_

@ -11,15 +11,15 @@ class AccountCapabilitiesTest : public testing::Test {};
TEST_F(AccountCapabilitiesTest, CanOfferExtendedChromeSyncPromos) {
AccountCapabilities capabilities;
EXPECT_EQ(capabilities.can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kUnknown);
signin::Tribool::kUnknown);
capabilities.set_can_offer_extended_chrome_sync_promos(true);
EXPECT_EQ(capabilities.can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kTrue);
signin::Tribool::kTrue);
capabilities.set_can_offer_extended_chrome_sync_promos(false);
EXPECT_EQ(capabilities.can_offer_extended_chrome_sync_promos(),
AccountCapabilities::Tribool::kFalse);
signin::Tribool::kFalse);
}
TEST_F(AccountCapabilitiesTest, AreAllCapabilitiesKnown_Empty) {
@ -40,7 +40,7 @@ TEST_F(AccountCapabilitiesTest, UpdateWith_UnknownToKnown) {
other.set_can_offer_extended_chrome_sync_promos(true);
EXPECT_TRUE(capabilities.UpdateWith(other));
EXPECT_EQ(AccountCapabilities::Tribool::kTrue,
EXPECT_EQ(signin::Tribool::kTrue,
capabilities.can_offer_extended_chrome_sync_promos());
}
@ -51,7 +51,7 @@ TEST_F(AccountCapabilitiesTest, UpdateWith_KnownToUnknown) {
AccountCapabilities other;
EXPECT_FALSE(capabilities.UpdateWith(other));
EXPECT_EQ(AccountCapabilities::Tribool::kTrue,
EXPECT_EQ(signin::Tribool::kTrue,
capabilities.can_offer_extended_chrome_sync_promos());
}
@ -63,6 +63,6 @@ TEST_F(AccountCapabilitiesTest, UpdateWith_OverwriteKnown) {
other.set_can_offer_extended_chrome_sync_promos(false);
EXPECT_TRUE(capabilities.UpdateWith(other));
EXPECT_EQ(AccountCapabilities::Tribool::kFalse,
EXPECT_EQ(signin::Tribool::kFalse,
capabilities.can_offer_extended_chrome_sync_promos());
}

@ -42,6 +42,16 @@ bool UpdateField(bool* field, bool new_value) {
return true;
}
// Updates |field| with |new_value| if true. Returns whether |field| was
// changed.
bool UpdateField(signin::Tribool* field, signin::Tribool new_value) {
if (*field == new_value || new_value == signin::Tribool::kUnknown)
return false;
*field = new_value;
return true;
}
} // namespace
// This must be a string which can never be a valid domain.

@ -9,6 +9,7 @@
#include "build/build_config.h"
#include "components/signin/public/identity_manager/account_capabilities.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "google_apis/gaia/core_account_id.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/image/image.h"
@ -65,13 +66,16 @@ struct AccountInfo : public CoreAccountInfo {
std::string picture_url;
std::string last_downloaded_image_url_with_size;
gfx::Image account_image;
bool is_child_account = false;
AccountCapabilities capabilities;
signin::Tribool is_child_account = signin::Tribool::kUnknown;
// Returns true if all fields in the account info are empty.
bool IsEmpty() const;
// Returns true if all fields in this account info are filled.
// Returns true if all non-optional fields in this account info are filled.
// Note: IsValid() does not check if `is_child_account` or `capabilities` are
// filled.
bool IsValid() const;
// Updates the empty fields of |this| with |other|. Returns whether at least

@ -30,14 +30,15 @@ TEST_F(AccountInfoTest, IsEmpty) {
}
}
// Tests that IsValid() returns true only when all the fields are non-empty.
// Tests that IsValid() returns true only when all the fields are non-empty
// (except is_child_account).
TEST_F(AccountInfoTest, IsValid) {
AccountInfo info;
EXPECT_EQ(signin::Tribool::kUnknown, info.is_child_account);
EXPECT_FALSE(info.IsValid());
info.gaia = info.email = "test_id";
info.account_id = CoreAccountId("test_id");
EXPECT_FALSE(info.IsValid());
info.full_name = info.given_name = "test_name";
@ -45,9 +46,6 @@ TEST_F(AccountInfoTest, IsValid) {
info.locale = "test_locale";
info.picture_url = "test_picture_url";
EXPECT_TRUE(info.IsValid());
info.is_child_account = true;
EXPECT_TRUE(info.IsValid());
}
// Tests that UpdateWith() correctly ignores parameters with a different
@ -71,17 +69,20 @@ TEST_F(AccountInfoTest, UpdateWithNoModification) {
AccountInfo info;
info.gaia = info.email = "test_id";
info.account_id = CoreAccountId("test_id");
info.is_child_account = true;
info.is_child_account = signin::Tribool::kTrue;
info.is_under_advanced_protection = true;
AccountInfo other;
other.account_id = CoreAccountId("test_id");
other.gaia = other.email = "test_id";
other.is_child_account = false;
EXPECT_EQ(signin::Tribool::kUnknown, other.is_child_account);
other.is_under_advanced_protection = false;
EXPECT_FALSE(info.UpdateWith(other));
EXPECT_EQ("test_id", info.gaia);
EXPECT_EQ("test_id", info.email);
EXPECT_TRUE(info.is_child_account);
EXPECT_EQ(signin::Tribool::kTrue, info.is_child_account);
EXPECT_TRUE(info.is_under_advanced_protection);
}
// Tests that UpdateWith() correctly updates its fields that were not set.
@ -93,7 +94,7 @@ TEST_F(AccountInfoTest, UpdateWithSuccessfulUpdate) {
AccountInfo other;
other.account_id = CoreAccountId("test_id");
other.full_name = other.given_name = "test_name";
other.is_child_account = true;
other.is_child_account = signin::Tribool::kTrue;
other.capabilities.set_can_offer_extended_chrome_sync_promos(true);
EXPECT_TRUE(info.UpdateWith(other));
@ -101,8 +102,8 @@ TEST_F(AccountInfoTest, UpdateWithSuccessfulUpdate) {
EXPECT_EQ("test_id", info.email);
EXPECT_EQ("test_name", info.full_name);
EXPECT_EQ("test_name", info.given_name);
EXPECT_TRUE(info.is_child_account);
EXPECT_EQ(AccountCapabilities::Tribool::kTrue,
EXPECT_EQ(signin::Tribool::kTrue, info.is_child_account);
EXPECT_EQ(signin::Tribool::kTrue,
info.capabilities.can_offer_extended_chrome_sync_promos());
}

@ -20,6 +20,8 @@ struct CoreAccountId;
namespace signin {
enum class Tribool;
// AccountsMutator is the interface to support seeding of account info and
// mutation of refresh tokens for the user's Gaia accounts.
class AccountsMutator {
@ -37,10 +39,10 @@ class AccountsMutator {
signin_metrics::SourceForRefreshTokenOperation source) = 0;
// Updates the information about account identified by |account_id|.
virtual void UpdateAccountInfo(
const CoreAccountId& account_id,
absl::optional<bool> is_child_account,
absl::optional<bool> is_under_advanced_protection) = 0;
// If kUnknown is passed, the attribute is not updated.
virtual void UpdateAccountInfo(const CoreAccountId& account_id,
Tribool is_child_account,
Tribool is_under_advanced_protection) = 0;
// Removes the account given by |account_id|. Also revokes the token
// server-side if needed.

@ -10,10 +10,12 @@
#include "build/chromeos_buildflags.h"
#include "components/signin/public/base/device_id_helper.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "components/signin/public/identity_manager/test_identity_manager_observer.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
@ -150,13 +152,13 @@ TEST_F(AccountsMutatorTest, UpdateAccountInfo) {
identity_manager()->FindExtendedAccountInfoByAccountId(account_id);
EXPECT_EQ(original_account_info.account_id, account_id);
EXPECT_EQ(original_account_info.email, kTestEmail);
EXPECT_FALSE(original_account_info.is_child_account);
EXPECT_EQ(Tribool::kUnknown, original_account_info.is_child_account);
EXPECT_FALSE(original_account_info.is_under_advanced_protection);
accounts_mutator()->UpdateAccountInfo(
account_id,
/*is_child_account=*/true,
/*is_under_advanced_protection=*/absl::nullopt);
/*is_child_account=*/Tribool::kTrue,
/*is_under_advanced_protection=*/Tribool::kUnknown);
AccountInfo updated_account_info_1 =
identity_manager()->FindExtendedAccountInfoByAccountId(account_id);
@ -170,9 +172,9 @@ TEST_F(AccountsMutatorTest, UpdateAccountInfo) {
EXPECT_EQ(updated_account_info_1.is_under_advanced_protection,
original_account_info.is_under_advanced_protection);
accounts_mutator()->UpdateAccountInfo(account_id,
/*is_child_account=*/absl::nullopt,
/*is_under_advanced_protection=*/true);
accounts_mutator()->UpdateAccountInfo(
account_id, /*is_child_account=*/Tribool::kUnknown,
/*is_under_advanced_protection=*/Tribool::kTrue);
AccountInfo updated_account_info_2 =
identity_manager()->FindExtendedAccountInfoByAccountId(account_id);
@ -185,22 +187,22 @@ TEST_F(AccountsMutatorTest, UpdateAccountInfo) {
// Last, reset |is_child_account| and |is_under_advanced_protection| together
// to its initial |false| value, which is no longer the case.
EXPECT_TRUE(updated_account_info_2.is_child_account);
EXPECT_EQ(Tribool::kTrue, updated_account_info_2.is_child_account);
EXPECT_TRUE(updated_account_info_2.is_under_advanced_protection);
accounts_mutator()->UpdateAccountInfo(account_id,
/*is_child_account=*/false,
/*is_under_advanced_protection=*/false);
accounts_mutator()->UpdateAccountInfo(
account_id, /*is_child_account=*/Tribool::kFalse,
/*is_under_advanced_protection=*/Tribool::kFalse);
AccountInfo reset_account_info =
identity_manager()->FindExtendedAccountInfoByAccountId(account_id);
// Everything is back to its original state now.
EXPECT_EQ(reset_account_info.is_child_account,
original_account_info.is_child_account);
// is_under_advanced_protection is back to its original state now.
EXPECT_EQ(reset_account_info.is_under_advanced_protection,
original_account_info.is_under_advanced_protection);
EXPECT_FALSE(reset_account_info.is_child_account);
EXPECT_FALSE(reset_account_info.is_under_advanced_protection);
// It is not possible to reset is_child_account to unknown, it is reset to
// false instead.
EXPECT_EQ(Tribool::kFalse, reset_account_info.is_child_account);
}
#if !BUILDFLAG(IS_CHROMEOS_ASH)

@ -0,0 +1,20 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/public/identity_manager/tribool.h"
namespace signin {
std::string TriboolToString(Tribool tribool) {
switch (tribool) {
case Tribool::kUnknown:
return "Unknown";
case Tribool::kFalse:
return "False";
case Tribool::kTrue:
return "True";
}
}
} // namespace signin

@ -0,0 +1,20 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_TRIBOOL_H_
#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_TRIBOOL_H_
#include <string>
namespace signin {
// The values are persisted to disk and must not be changed.
enum class Tribool { kUnknown = -1, kFalse = 0, kTrue = 1 };
// Returns the string representation of a tribool.
std::string TriboolToString(Tribool tribool);
} // namespace signin
#endif // COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_TRIBOOL_H_

@ -7,6 +7,7 @@
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/identity_manager/tribool.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
@ -147,12 +148,12 @@ void SigninURLLoaderThrottle::ProcessRequest(
// be sent in the Mirror request header from WebLayer.
signin::AppendOrRemoveMirrorRequestHeader(
&request_adapter, new_url, delegate->GetGaiaId(),
absl::nullopt /* is_child_account */,
/*is_child_account=*/signin::Tribool::kUnknown,
signin::AccountConsistencyMethod::kMirror,
CookieSettingsFactory::GetForBrowserContext(browser_context_).get(),
signin::PROFILE_MODE_INCOGNITO_DISABLED |
signin::PROFILE_MODE_ADD_ACCOUNT_DISABLED,
kWebLayerMirrorHeaderSource, true /* force_account_consistency */);
kWebLayerMirrorHeaderSource, /*force_account_consistency=*/true);
original_headers->MergeFrom(*modified_headers);
for (const std::string& name : *headers_to_remove)