From 6ca8ce8ab289ef0777862bd7f0a52df55808391f Mon Sep 17 00:00:00 2001 From: Arpan Kaphle Date: Mon, 1 May 2023 23:11:05 +0000 Subject: [PATCH] Sets up Emit for Auth Entry This CL focuses on setting up the emit for the authentication entry metrics, by identifying where in the API flow this may occur. Further CLs will add more details. Bug: 271135048 Test: Build + Won't Submit before E2E Test Change-Id: I82c2f7477f585b0c43a6cf06e7a1f4982cbf5907 --- .../server/credentials/MetricUtilities.java | 135 +++++++++++------- .../server/credentials/RequestSession.java | 11 ++ .../metrics/RequestSessionMetric.java | 27 +++- 3 files changed, 118 insertions(+), 55 deletions(-) diff --git a/services/credentials/java/com/android/server/credentials/MetricUtilities.java b/services/credentials/java/com/android/server/credentials/MetricUtilities.java index 58c6fa9a9bf1a..ed0c88709aff2 100644 --- a/services/credentials/java/com/android/server/credentials/MetricUtilities.java +++ b/services/credentials/java/com/android/server/credentials/MetricUtilities.java @@ -195,10 +195,37 @@ public class MetricUtilities { * This emits the authentication entry metrics for track 2, where the provider uid is known. * * @param authenticationMetric the authentication metric collection to emit with + * @param emitSequenceId an emitted sequence id for the current session */ public static void logApiCalledAuthenticationMetric( - BrowsedAuthenticationMetric authenticationMetric) { - // TODO(immediately) - Add in this emit + BrowsedAuthenticationMetric authenticationMetric, + int emitSequenceId) { + try { + if (!LOG_FLAG) { + return; + } + FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED, + /* session_id */ authenticationMetric.getSessionIdProvider(), + /* sequence_num */ emitSequenceId, + /* chosen_provider_uid */ authenticationMetric.getProviderUid(), + /* unique_response_classtypes */ + authenticationMetric.getAuthEntryCollective().getUniqueResponseStrings(), + /* per_classtype_counts */ + authenticationMetric.getAuthEntryCollective().getUniqueResponseCounts(), + /* unique_entries */ + authenticationMetric.getAuthEntryCollective().getUniqueEntries(), + /* auth_per_entry_counts */ + authenticationMetric.getAuthEntryCollective().getUniqueEntryCounts(), + /* framework_exception_unique_classtype */ + DEFAULT_STRING, + /* exception_specified */ false, + /* auth_provider_status TODO(immediately) change */ DEFAULT_INT_32, + /* query_returned */ + false + ); + } catch (Exception e) { + Slog.w(TAG, "Unexpected error during candidate get metric logging: " + e); + } } /** @@ -214,7 +241,10 @@ public class MetricUtilities { public static void logApiCalledCandidateGetMetric(Map providers, int emitSequenceId) { try { - // TODO(b/future) - Switch to Log format + // TODO(b/274954697) : To queue format in future optimizations (metrics POC support) + if (!LOG_FLAG) { + return; + } var sessions = providers.values(); for (var session : sessions) { try { @@ -411,56 +441,57 @@ public class MetricUtilities { int sequenceNum) { try { if (!LOG_FLAG) { - FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_TOTAL_REPORTED, - /*session_id*/ candidateAggregateMetric.getSessionIdProvider(), - /*sequence_num*/ sequenceNum, - /*query_returned*/ candidateAggregateMetric.isQueryReturned(), - /*num_query_providers*/ candidateAggregateMetric.getNumProviders(), - /*min_query_start_timestamp_microseconds*/ - DEFAULT_INT_32, - /*max_query_end_timestamp_microseconds*/ - DEFAULT_INT_32, - /*query_response_unique_classtypes*/ - candidateAggregateMetric.getAggregateCollectiveQuery() - .getUniqueResponseStrings(), - /*query_per_classtype_counts*/ - candidateAggregateMetric.getAggregateCollectiveQuery() - .getUniqueResponseCounts(), - /*query_unique_entries*/ - candidateAggregateMetric.getAggregateCollectiveQuery() - .getUniqueEntries(), - /*query_per_entry_counts*/ - candidateAggregateMetric.getAggregateCollectiveQuery() - .getUniqueEntryCounts(), - /*query_total_candidate_failure*/ - DEFAULT_INT_32, - /*query_framework_exception_unique_classtypes*/ - DEFAULT_REPEATED_STR, - /*query_per_exception_classtype_counts*/ - DEFAULT_REPEATED_INT_32, - /*auth_response_unique_classtypes*/ - candidateAggregateMetric.getAggregateCollectiveAuth() - .getUniqueResponseStrings(), - /*auth_per_classtype_counts*/ - candidateAggregateMetric.getAggregateCollectiveAuth() - .getUniqueResponseCounts(), - /*auth_unique_entries*/ - candidateAggregateMetric.getAggregateCollectiveAuth() - .getUniqueEntries(), - /*auth_per_entry_counts*/ - candidateAggregateMetric.getAggregateCollectiveAuth() - .getUniqueEntryCounts(), - /*auth_total_candidate_failure*/ - DEFAULT_INT_32, - /*auth_framework_exception_unique_classtypes*/ - DEFAULT_REPEATED_STR, - /*auth_per_exception_classtype_counts*/ - DEFAULT_REPEATED_INT_32, - /*num_auth_clicks*/ - candidateAggregateMetric.getNumAuthEntriesTapped(), - /*auth_returned*/ false - ); + return; } + FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_TOTAL_REPORTED, + /*session_id*/ candidateAggregateMetric.getSessionIdProvider(), + /*sequence_num*/ sequenceNum, + /*query_returned*/ candidateAggregateMetric.isQueryReturned(), + /*num_query_providers*/ candidateAggregateMetric.getNumProviders(), + /*min_query_start_timestamp_microseconds*/ + DEFAULT_INT_32, + /*max_query_end_timestamp_microseconds*/ + DEFAULT_INT_32, + /*query_response_unique_classtypes*/ + candidateAggregateMetric.getAggregateCollectiveQuery() + .getUniqueResponseStrings(), + /*query_per_classtype_counts*/ + candidateAggregateMetric.getAggregateCollectiveQuery() + .getUniqueResponseCounts(), + /*query_unique_entries*/ + candidateAggregateMetric.getAggregateCollectiveQuery() + .getUniqueEntries(), + /*query_per_entry_counts*/ + candidateAggregateMetric.getAggregateCollectiveQuery() + .getUniqueEntryCounts(), + /*query_total_candidate_failure*/ + DEFAULT_INT_32, + /*query_framework_exception_unique_classtypes*/ + DEFAULT_REPEATED_STR, + /*query_per_exception_classtype_counts*/ + DEFAULT_REPEATED_INT_32, + /*auth_response_unique_classtypes*/ + candidateAggregateMetric.getAggregateCollectiveAuth() + .getUniqueResponseStrings(), + /*auth_per_classtype_counts*/ + candidateAggregateMetric.getAggregateCollectiveAuth() + .getUniqueResponseCounts(), + /*auth_unique_entries*/ + candidateAggregateMetric.getAggregateCollectiveAuth() + .getUniqueEntries(), + /*auth_per_entry_counts*/ + candidateAggregateMetric.getAggregateCollectiveAuth() + .getUniqueEntryCounts(), + /*auth_total_candidate_failure*/ + DEFAULT_INT_32, + /*auth_framework_exception_unique_classtypes*/ + DEFAULT_REPEATED_STR, + /*auth_per_exception_classtype_counts*/ + DEFAULT_REPEATED_INT_32, + /*num_auth_clicks*/ + candidateAggregateMetric.getNumAuthEntriesTapped(), + /*auth_returned*/ false + ); } catch (Exception e) { Slog.w(TAG, "Unexpected error during metric logging: " + e); } diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java index a41b5713ee145..c332c426e3315 100644 --- a/services/credentials/java/com/android/server/credentials/RequestSession.java +++ b/services/credentials/java/com/android/server/credentials/RequestSession.java @@ -38,6 +38,7 @@ import android.util.Slog; import com.android.internal.R; import com.android.server.credentials.metrics.ApiName; import com.android.server.credentials.metrics.ApiStatus; +import com.android.server.credentials.metrics.ProviderSessionMetric; import com.android.server.credentials.metrics.ProviderStatusForMetrics; import com.android.server.credentials.metrics.RequestSessionMetric; @@ -199,10 +200,20 @@ abstract class RequestSession implements CredentialManagerUi.Credential Slog.w(TAG, "providerSession not found in onUiSelection. This is strange."); return; } + ProviderSessionMetric providerSessionMetric = providerSession.mProviderSessionMetric; + int initialAuthMetricsProvider = providerSessionMetric.getBrowsedAuthenticationMetric() + .size(); mRequestSessionMetric.collectMetricPerBrowsingSelect(selection, providerSession.mProviderSessionMetric.getCandidatePhasePerProviderMetric()); providerSession.onUiEntrySelected(selection.getEntryKey(), selection.getEntrySubkey(), selection.getPendingIntentProviderResponse()); + int numAuthPerProvider = providerSessionMetric.getBrowsedAuthenticationMetric().size(); + boolean authMetricLogged = (numAuthPerProvider - initialAuthMetricsProvider) == 1; + if (authMetricLogged) { + mRequestSessionMetric.logAuthEntry( + providerSession.mProviderSessionMetric.getBrowsedAuthenticationMetric() + .get(numAuthPerProvider - 1)); + } } protected void finishSession(boolean propagateCancellation) { diff --git a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java index 3c8d2e58f265f..4fb2d207b112b 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java @@ -16,9 +16,11 @@ package com.android.server.credentials.metrics; +import static com.android.server.credentials.MetricUtilities.DEFAULT_INT_32; import static com.android.server.credentials.MetricUtilities.DELTA_EXCEPTION_CUT; import static com.android.server.credentials.MetricUtilities.DELTA_RESPONSES_CUT; import static com.android.server.credentials.MetricUtilities.generateMetricKey; +import static com.android.server.credentials.MetricUtilities.logApiCalledAuthenticationMetric; import static com.android.server.credentials.MetricUtilities.logApiCalledCandidateGetMetric; import static com.android.server.credentials.MetricUtilities.logApiCalledCandidatePhase; import static com.android.server.credentials.MetricUtilities.logApiCalledFinalPhase; @@ -100,8 +102,6 @@ public class RequestSessionMetric { * @param timestampStarted the timestamp the service begins at * @param mCallingUid the calling process's uid * @param metricCode typically pulled from {@link ApiName} - * @param callingAppFlowUniqueInt the unique integer used as the session id for the calling app - * known flow */ public void collectInitialPhaseMetricInfo(long timestampStarted, int mCallingUid, int metricCode) { @@ -214,7 +214,8 @@ public class RequestSessionMetric { /** * During browsing, where multiple entries can be selected, this collects the browsing phase - * metric information. + * metric information. This is emitted together with the final phase, and the recursive path + * with authentication entries, which may occur in rare circumstances, are captured. * * @param selection contains the selected entry key type * @param selectedProviderPhaseMetric contains the utility information of the selected provider @@ -361,6 +362,26 @@ public class RequestSessionMetric { } } + /** + * This logs the authentication entry when browsed. Combined with the known browsed clicks + * in the {@link ChosenProviderFinalPhaseMetric}, this fully captures the authentication entry + * logic for multiple loops. + * + * @param browsedAuthenticationMetric the authentication metric information to emit + */ + public void logAuthEntry(BrowsedAuthenticationMetric browsedAuthenticationMetric) { + try { + if (browsedAuthenticationMetric.getProviderUid() == DEFAULT_INT_32) { + Slog.v(TAG, "An authentication entry was not clicked"); + return; + } + logApiCalledAuthenticationMetric(browsedAuthenticationMetric, ++mSequenceCounter); + } catch (Exception e) { + Slog.i(TAG, "Unexpected error during metric logging: " + e); + } + + } + /** * Handles the final logging for RequestSession context for the final phase. *