Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9cfa89f4 authored by Arpan Kaphle's avatar Arpan Kaphle
Browse files

Handling sequential auth entries in metrics

Since auth entries could repeat multiple times, maybe across multiple
providers, this ensures that the aggregate and single case properly
handle such sequential amounts of calls and emit them accordingly.

Bug: 271135048
Test: Build and Won't Submit without E2E Test
Change-Id: If4b77e0865761c22bd2e63b333bd46647f25d976
parent 39942cfa
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -214,8 +214,7 @@ public class MetricUtilities {
    public static void logApiCalledCandidateGetMetric(Map<String, ProviderSession> providers,
            int emitSequenceId) {
        try {
            // TODO(immediately) - Modify to a Static Queue of Ordered Functions and emit from
            //  queue to adhere to 10 second limit (thread removed given android safe-calling).
            // TODO(b/future) - Switch to Log format
            var sessions = providers.values();
            for (var session : sessions) {
                try {
@@ -416,7 +415,7 @@ public class MetricUtilities {
                        /*session_id*/ candidateAggregateMetric.getSessionIdProvider(),
                        /*sequence_num*/ sequenceNum,
                        /*query_returned*/ candidateAggregateMetric.isQueryReturned(),
                        /*num_providers*/ candidateAggregateMetric.getNumProviders(),
                        /*num_query_providers*/ candidateAggregateMetric.getNumProviders(),
                        /*min_query_start_timestamp_microseconds*/
                        DEFAULT_INT_32,
                        /*max_query_end_timestamp_microseconds*/
@@ -440,13 +439,17 @@ public class MetricUtilities {
                        /*query_per_exception_classtype_counts*/
                        DEFAULT_REPEATED_INT_32,
                        /*auth_response_unique_classtypes*/
                        DEFAULT_REPEATED_STR,
                        candidateAggregateMetric.getAggregateCollectiveAuth()
                                .getUniqueResponseStrings(),
                        /*auth_per_classtype_counts*/
                        DEFAULT_REPEATED_INT_32,
                        candidateAggregateMetric.getAggregateCollectiveAuth()
                                .getUniqueResponseCounts(),
                        /*auth_unique_entries*/
                        DEFAULT_REPEATED_INT_32,
                        candidateAggregateMetric.getAggregateCollectiveAuth()
                                .getUniqueEntries(),
                        /*auth_per_entry_counts*/
                        DEFAULT_REPEATED_INT_32,
                        candidateAggregateMetric.getAggregateCollectiveAuth()
                                .getUniqueEntryCounts(),
                        /*auth_total_candidate_failure*/
                        DEFAULT_INT_32,
                        /*auth_framework_exception_unique_classtypes*/
@@ -454,7 +457,7 @@ public class MetricUtilities {
                        /*auth_per_exception_classtype_counts*/
                        DEFAULT_REPEATED_INT_32,
                        /*num_auth_clicks*/
                        DEFAULT_INT_32,
                        candidateAggregateMetric.getNumAuthEntriesTapped(),
                        /*auth_returned*/ false
                );
            }
+14 −8
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ public class CandidateAggregateMetric {
     * @param providers the providers associated with the candidate flow
     */
    public void collectAverages(Map<String, ProviderSession> providers) {
        // TODO(b/271135048) : Complete this method
        collectQueryAggregates(providers);
        collectAuthAggregates(providers);
    }
@@ -89,14 +88,17 @@ public class CandidateAggregateMetric {
        var providerSessions = providers.values();
        for (var session : providerSessions) {
            var sessionMetric = session.getProviderSessionMetric();
            var authMetric = sessionMetric.getBrowsedAuthenticationMetric();
            mQueryReturned = mQueryReturned; // TODO add auth info
            var authMetrics = sessionMetric.getBrowsedAuthenticationMetric();
            mQueryReturned = mQueryReturned; // TODO add rest of auth info
            mNumAuthEntriesTapped += authMetrics.size();
            for (var authMetric : authMetrics) {
                ResponseCollective authCollective = authMetric.getAuthEntryCollective();
                ResponseCollective.combineTypeCountMaps(responseCountAuth,
                        authCollective.getResponseCountsMap());
                ResponseCollective.combineTypeCountMaps(entryCountAuth,
                        authCollective.getEntryCountsMap());
            }
        }
        mAggregateCollectiveAuth = new ResponseCollective(responseCountAuth, entryCountAuth);
    }

@@ -116,4 +118,8 @@ public class CandidateAggregateMetric {
    public ResponseCollective getAggregateCollectiveQuery() {
        return mAggregateCollectiveQuery;
    }

    public ResponseCollective getAggregateCollectiveAuth() {
        return mAggregateCollectiveAuth;
    }
}
+19 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.util.Slog;
import com.android.server.credentials.MetricUtilities;
import com.android.server.credentials.metrics.shared.ResponseCollective;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -47,13 +48,17 @@ public class ProviderSessionMetric {
    protected final CandidatePhaseMetric mCandidatePhasePerProviderMetric;

    // IFF there was an authentication entry clicked, this stores all required information for
    // that event. This is for the 'get' flow.
    // that event. This is for the 'get' flow. Notice these flows may be repetitive.
    // Thus each provider stores a list of authentication metrics. The time between emits
    // of these metrics should exceed 10 ms (given human reaction time is ~ 100's of ms), so emits
    // will never collide. However, for aggregation, this will store information accordingly.
    @NonNull
    protected final BrowsedAuthenticationMetric mBrowsedAuthenticationMetric;
    protected final List<BrowsedAuthenticationMetric> mBrowsedAuthenticationMetric =
            new ArrayList<>();

    public ProviderSessionMetric(int sessionIdTrackTwo) {
        mCandidatePhasePerProviderMetric = new CandidatePhaseMetric(sessionIdTrackTwo);
        mBrowsedAuthenticationMetric = new BrowsedAuthenticationMetric(sessionIdTrackTwo);
        mBrowsedAuthenticationMetric.add(new BrowsedAuthenticationMetric(sessionIdTrackTwo));
    }

    /**
@@ -66,7 +71,7 @@ public class ProviderSessionMetric {
    /**
     * Retrieves the authentication clicked metric information.
     */
    public BrowsedAuthenticationMetric getBrowsedAuthenticationMetric() {
    public List<BrowsedAuthenticationMetric> getBrowsedAuthenticationMetric() {
        return mBrowsedAuthenticationMetric;
    }

@@ -97,8 +102,10 @@ public class ProviderSessionMetric {
        // TODO(b/271135048) - Mimic typical candidate update, but with authentication metric
        // Collect the final timestamps (and start timestamp), status, exceptions and the provider
        // uid. This occurs typically *after* the collection is complete.
        mBrowsedAuthenticationMetric.setProviderUid(providerSessionUid);
        // TODO(immediately) - add timestamps
        var mostRecentAuthenticationMetric = mBrowsedAuthenticationMetric
                .get(mBrowsedAuthenticationMetric.size() - 1);
        mostRecentAuthenticationMetric.setProviderUid(providerSessionUid);
        // TODO(immediately) - add timestamps (no longer needed!!) but also update below values!
        if (isFailureStatus) {
            mCandidatePhasePerProviderMetric.setQueryReturned(false);
            mCandidatePhasePerProviderMetric.setProviderQueryStatus(
@@ -259,7 +266,12 @@ public class ProviderSessionMetric {
        if (!isAuthEntry) {
            mCandidatePhasePerProviderMetric.setResponseCollective(responseCollective);
        } else {
            mBrowsedAuthenticationMetric.setAuthEntryCollective(responseCollective);
            BrowsedAuthenticationMetric browsedAuthenticationMetric =
                    new BrowsedAuthenticationMetric(mCandidatePhasePerProviderMetric
                            .getSessionIdProvider());
            // to receive an auth entry, the candidate phase must have succeeded
            browsedAuthenticationMetric.setAuthEntryCollective(responseCollective);
            mBrowsedAuthenticationMetric.add(browsedAuthenticationMetric);
        }
    }
}
+0 −3
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ public class RequestSessionMetric {
    protected final InitialPhaseMetric mInitialPhaseMetric;
    protected final ChosenProviderFinalPhaseMetric
            mChosenProviderFinalPhaseMetric;
    // TODO(b/271135048) - Replace this with a new atom per each browsing emit (V4)
    protected List<CandidateBrowsingPhaseMetric> mCandidateBrowsingPhaseMetric = new ArrayList<>();
    // Specific aggregate candidate provider metric for the provider this session handles
    @NonNull
@@ -216,8 +215,6 @@ public class RequestSessionMetric {
    /**
     * During browsing, where multiple entries can be selected, this collects the browsing phase
     * metric information.
     * TODO(b/271135048) - modify asap to account for a new metric emit per browse response to
     * framework.
     *
     * @param selection                   contains the selected entry key type
     * @param selectedProviderPhaseMetric contains the utility information of the selected provider