[FedCM] Add account sign-up/sign-in state to metrics
After fetching accounts from IdP, knowing whether the API is for sign-up or sign-in users can help us better understand user expectation and how FedCM performs differently. e.g. CTR for sign-in users should be higher than sign-up users but it should be quantifiable. UKM review: https://docs.google.com/document/d/1hP0O1CcDgLk3RB_jlYOQtl9xQj9woFBcBpaJy4mFK9Q/edit?resourcekey=0-u4gaHookWBYkgngUxTiDxA&disco=AAABfDiVXoY Bug: 397455375 Change-Id: Icf968e429f723b45f409661a2465a5cdc7ae1b1c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6311101 Commit-Queue: Yi Gu <yigu@chromium.org> Reviewed-by: Christian Biesinger <cbiesinger@chromium.org> Reviewed-by: Sun Yueru <yrsun@chromium.org> Cr-Commit-Position: refs/heads/main@{#1427257}
This commit is contained in:
content/browser/webid
fedcm_metrics.ccfedcm_metrics.hfederated_auth_request_impl.ccfederated_auth_request_impl_unittest.cc
tools/metrics
@ -275,7 +275,8 @@ void FedCmMetrics::RecordRequestTokenStatus(
|
||||
std::optional<FedCmUseOtherAccountResult> use_other_account_result,
|
||||
std::optional<FedCmVerifyingDialogResult> verifying_dialog_result,
|
||||
FedCmThirdPartyCookiesStatus tpc_status,
|
||||
const FedCmRequesterFrameType& requester_frame_type) {
|
||||
const FedCmRequesterFrameType& requester_frame_type,
|
||||
std::optional<bool> has_signin_account) {
|
||||
// The following check is to avoid double recording in the following scenario:
|
||||
// 1. The request has failed but we have not yet rejected the promise, e.g.
|
||||
// when the API is disabled. We record a metric immediately but only post a
|
||||
@ -313,6 +314,9 @@ void FedCmMetrics::RecordRequestTokenStatus(
|
||||
static_cast<int>(*verifying_dialog_result));
|
||||
}
|
||||
ukm_builder.SetFrameType(static_cast<int>(requester_frame_type));
|
||||
if (has_signin_account.has_value()) {
|
||||
ukm_builder.SetHasSigninAccount(*has_signin_account);
|
||||
}
|
||||
ukm_builder.SetFedCmSessionID(session_id_);
|
||||
ukm_builder.Record(ukm::UkmRecorder::Get());
|
||||
};
|
||||
@ -350,6 +354,10 @@ void FedCmMetrics::RecordRequestTokenStatus(
|
||||
base::UmaHistogramEnumeration("Blink.FedCm.VerifyingDialogResult",
|
||||
*verifying_dialog_result);
|
||||
}
|
||||
if (has_signin_account.has_value()) {
|
||||
base::UmaHistogramBoolean("Blink.FedCm.HasSigninAccount",
|
||||
*has_signin_account);
|
||||
}
|
||||
// Reset the `session_id_`. We expect no more metrics from this API call.
|
||||
session_id_ = -1;
|
||||
}
|
||||
|
@ -387,7 +387,8 @@ class CONTENT_EXPORT FedCmMetrics {
|
||||
std::optional<FedCmUseOtherAccountResult> use_other_account_result,
|
||||
std::optional<FedCmVerifyingDialogResult> verifying_dialog_result,
|
||||
FedCmThirdPartyCookiesStatus tpc_status,
|
||||
const FedCmRequesterFrameType& requester_frame_type);
|
||||
const FedCmRequesterFrameType& requester_frame_type,
|
||||
std::optional<bool> has_signin_account);
|
||||
|
||||
// Records whether user sign-in states between IDP and browser match.
|
||||
void RecordSignInStateMatchStatus(const GURL& provider,
|
||||
|
@ -784,7 +784,8 @@ void FederatedAuthRequestImpl::RequestToken(
|
||||
? FedCmThirdPartyCookiesStatus::kEnabledInSettings
|
||||
: FedCmThirdPartyCookiesStatus::kDisabledInSettings,
|
||||
webid::ComputeRequesterFrameType(render_frame_host(), origin(),
|
||||
GetEmbeddingOrigin()));
|
||||
GetEmbeddingOrigin()),
|
||||
/*has_signin_account=*/std::nullopt);
|
||||
|
||||
AddDevToolsIssue(
|
||||
blink::mojom::FederatedAuthRequestResult::kTooManyRequests);
|
||||
@ -2985,6 +2986,18 @@ void FederatedAuthRequestImpl::CompleteRequest(
|
||||
: FedCmVerifyingDialogResult::kDestroyAutoReauthn;
|
||||
}
|
||||
|
||||
std::optional<bool> has_signin_account;
|
||||
// Note: accounts_ does not include the ones that got filtered out. In case
|
||||
// that all accounts are filtered out, we'd show the mismatch UI and skip
|
||||
// recording the account status on the mismatch UI.
|
||||
for (const auto& account : accounts_) {
|
||||
has_signin_account = false;
|
||||
if (account->login_state == LoginState::kSignIn) {
|
||||
has_signin_account = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fedcm_metrics_->RecordRequestTokenStatus(
|
||||
*token_status, mediation_requirement_, idp_order_, num_idps_mismatch,
|
||||
selected_idp_config_url, rp_mode_, use_other_account_result,
|
||||
@ -2993,7 +3006,8 @@ void FederatedAuthRequestImpl::CompleteRequest(
|
||||
? FedCmThirdPartyCookiesStatus::kEnabledInSettings
|
||||
: FedCmThirdPartyCookiesStatus::kDisabledInSettings,
|
||||
webid::ComputeRequesterFrameType(render_frame_host(), origin(),
|
||||
GetEmbeddingOrigin()));
|
||||
GetEmbeddingOrigin()),
|
||||
has_signin_account);
|
||||
}
|
||||
|
||||
if (result == FederatedAuthRequestResult::kSuccess) {
|
||||
|
@ -2156,6 +2156,8 @@ TEST_F(FederatedAuthRequestImplTest, LoginStateShouldBeSignUpForFirstTimeUser) {
|
||||
RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
|
||||
kConfigurationValid);
|
||||
EXPECT_EQ(LoginState::kSignUp, all_accounts_for_display()[0]->login_state);
|
||||
histogram_tester_.ExpectUniqueSample("Blink.FedCm.HasSigninAccount", false,
|
||||
1);
|
||||
}
|
||||
|
||||
TEST_F(FederatedAuthRequestImplTest, LoginStateShouldBeSignInForReturningUser) {
|
||||
@ -2185,6 +2187,8 @@ TEST_F(FederatedAuthRequestImplTest, LoginStateShouldBeSignInForReturningUser) {
|
||||
histogram_tester_.ExpectUniqueTimeSample(
|
||||
"Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch",
|
||||
base::TimeDelta(), 1);
|
||||
|
||||
histogram_tester_.ExpectUniqueSample("Blink.FedCm.HasSigninAccount", true, 1);
|
||||
}
|
||||
|
||||
TEST_F(FederatedAuthRequestImplTest,
|
||||
@ -5449,6 +5453,7 @@ TEST_F(FederatedAuthRequestImplTest, LoginHintSingleAccountNoMatch) {
|
||||
RunAuthTest(parameters, expectations, configuration);
|
||||
EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
|
||||
EXPECT_FALSE(did_show_accounts_dialog());
|
||||
ExpectNoUKMPresence("HasSigninAccount");
|
||||
|
||||
histogram_tester_.ExpectUniqueSample(
|
||||
"Blink.FedCm.LoginHint.NumMatchingAccounts",
|
||||
@ -6529,6 +6534,7 @@ TEST_F(FederatedAuthRequestImplTest, MismatchDialogShownMetric) {
|
||||
FedCmMetrics::MismatchDialogType::kFirstWithoutHints, 1);
|
||||
ExpectUKMPresence("MismatchDialogShown");
|
||||
ExpectNoUKMPresence("AccountsDialogShown");
|
||||
ExpectNoUKMPresence("HasSigninAccount");
|
||||
CheckAllFedCmSessionIDs();
|
||||
}
|
||||
|
||||
@ -7415,6 +7421,8 @@ TEST_F(FederatedAuthRequestImplTest,
|
||||
EXPECT_EQ(all_accounts_for_display()[2]->login_state, LoginState::kSignUp);
|
||||
EXPECT_EQ(all_accounts_for_display()[2]->browser_trusted_login_state,
|
||||
LoginState::kSignUp);
|
||||
|
||||
ExpectUkmValue("HasSigninAccount", true);
|
||||
}
|
||||
|
||||
// Test that IdP claimed SignIn does not affect browser observed SignUp.
|
||||
|
@ -1562,6 +1562,19 @@ chromium-metrics-reviews@google.com.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Blink.FedCm.HasSigninAccount" enum="BooleanYesNo"
|
||||
expires_after="2025-08-12">
|
||||
<owner>yigu@chromium.org</owner>
|
||||
<owner>web-identity-eng@google.com</owner>
|
||||
<summary>
|
||||
Records whether a user is signing up with the API. Records once per
|
||||
successful account fetch from the IdP server after the accounts filtering.
|
||||
If there are multiple accounts, record the user as sign-in if IdP claims at
|
||||
least one of the accounts is sign-in. If an IdP does not share the user's
|
||||
sign-in state, record the state stored in the browser.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Blink.FedCm.IdentityProvidersCount" units="count"
|
||||
expires_after="2025-08-12">
|
||||
<owner>npm@chromium.org</owner>
|
||||
|
@ -3770,6 +3770,15 @@ be describing additional metrics about the same event.
|
||||
category.
|
||||
</summary>
|
||||
</metric>
|
||||
<metric name="HasSigninAccount" enum="Boolean">
|
||||
<summary>
|
||||
Records whether a user is signing up with the API. Records once per
|
||||
successful account fetch from the IdP server after the accounts filtering.
|
||||
If there are multiple accounts, record the user as sign-in if IdP claims
|
||||
at least one of the accounts is sign-in. If an IdP does not share the
|
||||
user's sign-in state, record the state stored in the browser.
|
||||
</summary>
|
||||
</metric>
|
||||
<metric name="LoginHint.NumMatchingAccounts" enum="FedCmNumAccounts">
|
||||
<summary>
|
||||
Records the number of accounts that match a login hint. Records at the
|
||||
@ -4052,6 +4061,15 @@ be describing additional metrics about the same event.
|
||||
category.
|
||||
</summary>
|
||||
</metric>
|
||||
<metric name="HasSigninAccount" enum="Boolean">
|
||||
<summary>
|
||||
Records whether a user is signing up with the API. Records once per
|
||||
successful account fetch from the IdP server after the accounts filtering.
|
||||
If there are multiple accounts, record the user as sign-in if IdP claims
|
||||
at least one of the accounts is sign-in. If an IdP does not share the
|
||||
user's sign-in state, record the state stored in the browser.
|
||||
</summary>
|
||||
</metric>
|
||||
<metric name="MismatchDialogShown" enum="BooleanHit">
|
||||
<summary>
|
||||
Records a 1 each time a mismatch dialog is shown.
|
||||
|
Reference in New Issue
Block a user