Loading services/credentials/java/com/android/server/credentials/GetRequestSession.java +1 −7 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.server.credentials; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.credentials.CredentialOption; import android.credentials.CredentialProviderInfo; import android.credentials.GetCredentialException; import android.credentials.GetCredentialRequest; Loading @@ -36,7 +35,6 @@ import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; import java.util.Set; import java.util.stream.Collectors; /** * Central session for a single getCredentials request. This class listens to the Loading @@ -56,11 +54,7 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest, super(context, sessionCallback, lock, userId, callingUid, request, callback, RequestInfo.TYPE_GET, callingAppInfo, enabledProviders, cancellationSignal, startedTimestamp); int numTypes = (request.getCredentialOptions().stream() .map(CredentialOption::getType).collect( Collectors.toSet())).size(); // Dedupe type strings mRequestSessionMetric.collectGetFlowInitialMetricInfo(numTypes, /*origin=*/request.getOrigin() != null); mRequestSessionMetric.collectGetFlowInitialMetricInfo(request); } /** Loading services/credentials/java/com/android/server/credentials/MetricUtilities.java +23 −5 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ public class MetricUtilities { public static final int UNIT = 1; // Used for zero count metric emits, such as zero amounts of various types public static final int ZERO = 0; // The number of characters at the end of the string to use as a key public static final int DELTA_CUT = 20; /** * This retrieves the uid of any package name, given a context and a component name for the Loading Loading @@ -86,6 +88,18 @@ public class MetricUtilities { return (int) ((t2 - t1) / 1000); } /** * Given the current design, we can designate how the strings in the backend should appear. * This helper method lets us cut strings for our class types. * * @param classtype the classtype string we want to cut to generate a key * @param deltaFromEnd the starting point from the end of the string we wish to begin at * @return the cut up string key we want to use for metric logs */ public static String generateMetricKey(String classtype, int deltaFromEnd) { return classtype.substring(classtype.length() - deltaFromEnd); } /** * A logging utility used primarily for the final phase of the current metric setup. * Loading Loading @@ -158,7 +172,9 @@ public class MetricUtilities { } /** * A logging utility used primarily for the candidate phase of the current metric setup. * A logging utility used primarily for the candidate phase of the current metric setup. This * will primarily focus on track 2, where the session id is associated with known providers, * but NOT the calling app. * * @param providers a map with known providers and their held metric objects * @param emitSequenceId an emitted sequence id for the current session Loading Loading @@ -209,6 +225,7 @@ public class MetricUtilities { candidateActionEntryCountList[index] = metric.getActionEntryCount(); candidateAuthEntryCountList[index] = metric.getAuthenticationEntryCount(); candidateRemoteEntryCountList[index] = metric.getRemoteEntryCount(); // frameworkExceptionList[index] = metric.getFrameworkException(); index++; } FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED, Loading Loading @@ -297,10 +314,11 @@ public class MetricUtilities { initialPhaseMetric.getCredentialServiceStartedTimeNanoseconds(), /* count_credential_request_classtypes */ initialPhaseMetric.getCountRequestClassType(), // TODO(b/271135048) - add total count of request options // TODO(b/271135048) - Uncomment once built past PWG review - DEFAULT_REPEATED_STR, DEFAULT_REPEATED_INT_32, /* request_unique_classtypes */ initialPhaseMetric.getUniqueRequestStrings(), /* per_classtype_counts */ initialPhaseMetric.getUniqueRequestCounts(), /* origin_specified */ initialPhaseMetric.isOriginSpecified() ); } catch (Exception e) { Loading services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java +1 −2 Original line number Diff line number Diff line Loading @@ -59,8 +59,7 @@ public class PrepareGetRequestSession extends GetRequestSession { int numTypes = (request.getCredentialOptions().stream() .map(CredentialOption::getType).collect( Collectors.toSet())).size(); // Dedupe type strings mRequestSessionMetric.collectGetFlowInitialMetricInfo(numTypes, /*origin=*/request.getOrigin() != null); mRequestSessionMetric.collectGetFlowInitialMetricInfo(request); mPrepareGetCredentialCallback = prepareGetCredentialCallback; } Loading services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java +44 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ package com.android.server.credentials.metrics; import android.util.Log; import java.util.LinkedHashMap; import java.util.Map; /** * This handles metrics collected prior to any remote calls to providers. * Some types are redundant across these metric collectors, but that has debug use-cases as Loading @@ -32,7 +37,6 @@ public class InitialPhaseMetric { private int mCallerUid = -1; // The session id to unite multiple atom emits, default to -1 private int mSessionId = -1; private int mCountRequestClassType = -1; // Raw timestamps in nanoseconds, *the only* one logged as such (i.e. 64 bits) since it is a // reference point. Loading @@ -46,6 +50,9 @@ public class InitialPhaseMetric { // TODO(b/271135048) - Emit once metrics approved private boolean mOriginSpecified = false; // Stores the deduped request information, particularly {"req":5}. private Map<String, Integer> mRequestCounts = new LinkedHashMap<>(); public InitialPhaseMetric() { } Loading @@ -55,8 +62,8 @@ public class InitialPhaseMetric { /* -- Direct Latency Utility -- */ public int getServiceStartToQueryLatencyMicroseconds() { return (int) ((this.mCredentialServiceStartedTimeNanoseconds - this.mCredentialServiceBeginQueryTimeNanoseconds) / 1000); return (int) ((mCredentialServiceStartedTimeNanoseconds - mCredentialServiceBeginQueryTimeNanoseconds) / 1000); } /* -- Timestamps -- */ Loading @@ -64,7 +71,7 @@ public class InitialPhaseMetric { public void setCredentialServiceStartedTimeNanoseconds( long credentialServiceStartedTimeNanoseconds ) { this.mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds; mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds; } public void setCredentialServiceBeginQueryTimeNanoseconds( Loading Loading @@ -112,14 +119,12 @@ public class InitialPhaseMetric { /* ------ Count Request Class Types ------ */ public void setCountRequestClassType(int countRequestClassType) { mCountRequestClassType = countRequestClassType; } public int getCountRequestClassType() { return mCountRequestClassType; return mRequestCounts.size(); } /* ------ Origin Specified ------ */ public void setOriginSpecified(boolean originSpecified) { mOriginSpecified = originSpecified; } Loading @@ -127,4 +132,34 @@ public class InitialPhaseMetric { public boolean isOriginSpecified() { return mOriginSpecified; } /* ------ Unique Request Counts Map Information ------ */ public void setRequestCounts(Map<String, Integer> requestCounts) { mRequestCounts = requestCounts; } /** * Reruns the unique, deduped, request classtypes for logging. * @return a string array for deduped classtypes */ public String[] getUniqueRequestStrings() { if (mRequestCounts.isEmpty()) { Log.w(TAG, "There are no unique string request types collected"); } String[] result = new String[mRequestCounts.keySet().size()]; mRequestCounts.keySet().toArray(result); return result; } /** * Reruns the unique, deduped, request classtype counts for logging. * @return a string array for deduped classtype counts */ public int[] getUniqueRequestCounts() { if (mRequestCounts.isEmpty()) { Log.w(TAG, "There are no unique string request type counts collected"); } return mRequestCounts.values().stream().mapToInt(Integer::intValue).toArray(); } } services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java +25 −7 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package com.android.server.credentials.metrics; import static com.android.server.credentials.MetricUtilities.DELTA_CUT; import static com.android.server.credentials.MetricUtilities.generateMetricKey; import static com.android.server.credentials.MetricUtilities.logApiCalledCandidatePhase; import static com.android.server.credentials.MetricUtilities.logApiCalledFinalPhase; import android.annotation.NonNull; import android.credentials.GetCredentialRequest; import android.credentials.ui.UserSelectionDialogResult; import android.os.IBinder; import android.util.Log; Loading @@ -27,6 +29,7 @@ import android.util.Log; import com.android.server.credentials.ProviderSession; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; Loading @@ -48,7 +51,6 @@ public class RequestSessionMetric { protected final ChosenProviderFinalPhaseMetric mChosenProviderFinalPhaseMetric = new ChosenProviderFinalPhaseMetric(); // TODO(b/271135048) - Replace this with a new atom per each browsing emit (V4) @NonNull protected List<CandidateBrowsingPhaseMetric> mCandidateBrowsingPhaseMetric = new ArrayList<>(); public RequestSessionMetric() { Loading Loading @@ -161,16 +163,32 @@ public class RequestSessionMetric { } } // Used by get flows to generate the unique request count maps private Map<String, Integer> getRequestCountMap(GetCredentialRequest request) { Map<String, Integer> uniqueRequestCounts = new LinkedHashMap<>(); try { request.getCredentialOptions().forEach(option -> { String optionKey = generateMetricKey(option.getType(), DELTA_CUT); if (!uniqueRequestCounts.containsKey(optionKey)) { uniqueRequestCounts.put(optionKey, 0); } uniqueRequestCounts.put(optionKey, uniqueRequestCounts.get(optionKey) + 1); }); } catch (Exception e) { Log.w(TAG, "Unexpected error during get request metric logging: " + e); } return uniqueRequestCounts; } /** * Collects initializations for Get flow metrics. * * @param requestClassTypeCount the number of class types in the request * @param origin indicates if an origin was passed in or not * @param request the get credential request containing information to parse for metrics */ public void collectGetFlowInitialMetricInfo(int requestClassTypeCount, boolean origin) { public void collectGetFlowInitialMetricInfo(GetCredentialRequest request) { try { mInitialPhaseMetric.setCountRequestClassType(requestClassTypeCount); mInitialPhaseMetric.setOriginSpecified(origin); mInitialPhaseMetric.setOriginSpecified(request.getOrigin() != null); mInitialPhaseMetric.setRequestCounts(getRequestCountMap(request)); } catch (Exception e) { Log.w(TAG, "Unexpected error during metric logging: " + e); } Loading Loading
services/credentials/java/com/android/server/credentials/GetRequestSession.java +1 −7 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.server.credentials; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.credentials.CredentialOption; import android.credentials.CredentialProviderInfo; import android.credentials.GetCredentialException; import android.credentials.GetCredentialRequest; Loading @@ -36,7 +35,6 @@ import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; import java.util.Set; import java.util.stream.Collectors; /** * Central session for a single getCredentials request. This class listens to the Loading @@ -56,11 +54,7 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest, super(context, sessionCallback, lock, userId, callingUid, request, callback, RequestInfo.TYPE_GET, callingAppInfo, enabledProviders, cancellationSignal, startedTimestamp); int numTypes = (request.getCredentialOptions().stream() .map(CredentialOption::getType).collect( Collectors.toSet())).size(); // Dedupe type strings mRequestSessionMetric.collectGetFlowInitialMetricInfo(numTypes, /*origin=*/request.getOrigin() != null); mRequestSessionMetric.collectGetFlowInitialMetricInfo(request); } /** Loading
services/credentials/java/com/android/server/credentials/MetricUtilities.java +23 −5 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ public class MetricUtilities { public static final int UNIT = 1; // Used for zero count metric emits, such as zero amounts of various types public static final int ZERO = 0; // The number of characters at the end of the string to use as a key public static final int DELTA_CUT = 20; /** * This retrieves the uid of any package name, given a context and a component name for the Loading Loading @@ -86,6 +88,18 @@ public class MetricUtilities { return (int) ((t2 - t1) / 1000); } /** * Given the current design, we can designate how the strings in the backend should appear. * This helper method lets us cut strings for our class types. * * @param classtype the classtype string we want to cut to generate a key * @param deltaFromEnd the starting point from the end of the string we wish to begin at * @return the cut up string key we want to use for metric logs */ public static String generateMetricKey(String classtype, int deltaFromEnd) { return classtype.substring(classtype.length() - deltaFromEnd); } /** * A logging utility used primarily for the final phase of the current metric setup. * Loading Loading @@ -158,7 +172,9 @@ public class MetricUtilities { } /** * A logging utility used primarily for the candidate phase of the current metric setup. * A logging utility used primarily for the candidate phase of the current metric setup. This * will primarily focus on track 2, where the session id is associated with known providers, * but NOT the calling app. * * @param providers a map with known providers and their held metric objects * @param emitSequenceId an emitted sequence id for the current session Loading Loading @@ -209,6 +225,7 @@ public class MetricUtilities { candidateActionEntryCountList[index] = metric.getActionEntryCount(); candidateAuthEntryCountList[index] = metric.getAuthenticationEntryCount(); candidateRemoteEntryCountList[index] = metric.getRemoteEntryCount(); // frameworkExceptionList[index] = metric.getFrameworkException(); index++; } FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED, Loading Loading @@ -297,10 +314,11 @@ public class MetricUtilities { initialPhaseMetric.getCredentialServiceStartedTimeNanoseconds(), /* count_credential_request_classtypes */ initialPhaseMetric.getCountRequestClassType(), // TODO(b/271135048) - add total count of request options // TODO(b/271135048) - Uncomment once built past PWG review - DEFAULT_REPEATED_STR, DEFAULT_REPEATED_INT_32, /* request_unique_classtypes */ initialPhaseMetric.getUniqueRequestStrings(), /* per_classtype_counts */ initialPhaseMetric.getUniqueRequestCounts(), /* origin_specified */ initialPhaseMetric.isOriginSpecified() ); } catch (Exception e) { Loading
services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java +1 −2 Original line number Diff line number Diff line Loading @@ -59,8 +59,7 @@ public class PrepareGetRequestSession extends GetRequestSession { int numTypes = (request.getCredentialOptions().stream() .map(CredentialOption::getType).collect( Collectors.toSet())).size(); // Dedupe type strings mRequestSessionMetric.collectGetFlowInitialMetricInfo(numTypes, /*origin=*/request.getOrigin() != null); mRequestSessionMetric.collectGetFlowInitialMetricInfo(request); mPrepareGetCredentialCallback = prepareGetCredentialCallback; } Loading
services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java +44 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ package com.android.server.credentials.metrics; import android.util.Log; import java.util.LinkedHashMap; import java.util.Map; /** * This handles metrics collected prior to any remote calls to providers. * Some types are redundant across these metric collectors, but that has debug use-cases as Loading @@ -32,7 +37,6 @@ public class InitialPhaseMetric { private int mCallerUid = -1; // The session id to unite multiple atom emits, default to -1 private int mSessionId = -1; private int mCountRequestClassType = -1; // Raw timestamps in nanoseconds, *the only* one logged as such (i.e. 64 bits) since it is a // reference point. Loading @@ -46,6 +50,9 @@ public class InitialPhaseMetric { // TODO(b/271135048) - Emit once metrics approved private boolean mOriginSpecified = false; // Stores the deduped request information, particularly {"req":5}. private Map<String, Integer> mRequestCounts = new LinkedHashMap<>(); public InitialPhaseMetric() { } Loading @@ -55,8 +62,8 @@ public class InitialPhaseMetric { /* -- Direct Latency Utility -- */ public int getServiceStartToQueryLatencyMicroseconds() { return (int) ((this.mCredentialServiceStartedTimeNanoseconds - this.mCredentialServiceBeginQueryTimeNanoseconds) / 1000); return (int) ((mCredentialServiceStartedTimeNanoseconds - mCredentialServiceBeginQueryTimeNanoseconds) / 1000); } /* -- Timestamps -- */ Loading @@ -64,7 +71,7 @@ public class InitialPhaseMetric { public void setCredentialServiceStartedTimeNanoseconds( long credentialServiceStartedTimeNanoseconds ) { this.mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds; mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds; } public void setCredentialServiceBeginQueryTimeNanoseconds( Loading Loading @@ -112,14 +119,12 @@ public class InitialPhaseMetric { /* ------ Count Request Class Types ------ */ public void setCountRequestClassType(int countRequestClassType) { mCountRequestClassType = countRequestClassType; } public int getCountRequestClassType() { return mCountRequestClassType; return mRequestCounts.size(); } /* ------ Origin Specified ------ */ public void setOriginSpecified(boolean originSpecified) { mOriginSpecified = originSpecified; } Loading @@ -127,4 +132,34 @@ public class InitialPhaseMetric { public boolean isOriginSpecified() { return mOriginSpecified; } /* ------ Unique Request Counts Map Information ------ */ public void setRequestCounts(Map<String, Integer> requestCounts) { mRequestCounts = requestCounts; } /** * Reruns the unique, deduped, request classtypes for logging. * @return a string array for deduped classtypes */ public String[] getUniqueRequestStrings() { if (mRequestCounts.isEmpty()) { Log.w(TAG, "There are no unique string request types collected"); } String[] result = new String[mRequestCounts.keySet().size()]; mRequestCounts.keySet().toArray(result); return result; } /** * Reruns the unique, deduped, request classtype counts for logging. * @return a string array for deduped classtype counts */ public int[] getUniqueRequestCounts() { if (mRequestCounts.isEmpty()) { Log.w(TAG, "There are no unique string request type counts collected"); } return mRequestCounts.values().stream().mapToInt(Integer::intValue).toArray(); } }
services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java +25 −7 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package com.android.server.credentials.metrics; import static com.android.server.credentials.MetricUtilities.DELTA_CUT; import static com.android.server.credentials.MetricUtilities.generateMetricKey; import static com.android.server.credentials.MetricUtilities.logApiCalledCandidatePhase; import static com.android.server.credentials.MetricUtilities.logApiCalledFinalPhase; import android.annotation.NonNull; import android.credentials.GetCredentialRequest; import android.credentials.ui.UserSelectionDialogResult; import android.os.IBinder; import android.util.Log; Loading @@ -27,6 +29,7 @@ import android.util.Log; import com.android.server.credentials.ProviderSession; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; Loading @@ -48,7 +51,6 @@ public class RequestSessionMetric { protected final ChosenProviderFinalPhaseMetric mChosenProviderFinalPhaseMetric = new ChosenProviderFinalPhaseMetric(); // TODO(b/271135048) - Replace this with a new atom per each browsing emit (V4) @NonNull protected List<CandidateBrowsingPhaseMetric> mCandidateBrowsingPhaseMetric = new ArrayList<>(); public RequestSessionMetric() { Loading Loading @@ -161,16 +163,32 @@ public class RequestSessionMetric { } } // Used by get flows to generate the unique request count maps private Map<String, Integer> getRequestCountMap(GetCredentialRequest request) { Map<String, Integer> uniqueRequestCounts = new LinkedHashMap<>(); try { request.getCredentialOptions().forEach(option -> { String optionKey = generateMetricKey(option.getType(), DELTA_CUT); if (!uniqueRequestCounts.containsKey(optionKey)) { uniqueRequestCounts.put(optionKey, 0); } uniqueRequestCounts.put(optionKey, uniqueRequestCounts.get(optionKey) + 1); }); } catch (Exception e) { Log.w(TAG, "Unexpected error during get request metric logging: " + e); } return uniqueRequestCounts; } /** * Collects initializations for Get flow metrics. * * @param requestClassTypeCount the number of class types in the request * @param origin indicates if an origin was passed in or not * @param request the get credential request containing information to parse for metrics */ public void collectGetFlowInitialMetricInfo(int requestClassTypeCount, boolean origin) { public void collectGetFlowInitialMetricInfo(GetCredentialRequest request) { try { mInitialPhaseMetric.setCountRequestClassType(requestClassTypeCount); mInitialPhaseMetric.setOriginSpecified(origin); mInitialPhaseMetric.setOriginSpecified(request.getOrigin() != null); mInitialPhaseMetric.setRequestCounts(getRequestCountMap(request)); } catch (Exception e) { Log.w(TAG, "Unexpected error during metric logging: " + e); } Loading