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. *