summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/credentials/java/com/android/server/credentials/GetRequestSession.java8
-rw-r--r--services/credentials/java/com/android/server/credentials/MetricUtilities.java28
-rw-r--r--services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java3
-rw-r--r--services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java53
-rw-r--r--services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java32
5 files changed, 94 insertions, 30 deletions
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index f39de43b5076..0271727249b1 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -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;
@@ -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
@@ -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);
}
/**
diff --git a/services/credentials/java/com/android/server/credentials/MetricUtilities.java b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
index 47b45ac1d53d..c07f06b332fb 100644
--- a/services/credentials/java/com/android/server/credentials/MetricUtilities.java
+++ b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
@@ -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
@@ -87,6 +89,18 @@ public class MetricUtilities {
}
/**
+ * 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.
*
* @param finalPhaseMetric the coalesced data of the chosen provider
@@ -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
@@ -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,
@@ -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) {
diff --git a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
index 1c3d213c8072..441c87b1569a 100644
--- a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
@@ -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;
}
diff --git a/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java
index 0210b14943db..0ecd9cc79e48 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java
@@ -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
@@ -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.
@@ -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() {
}
@@ -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 -- */
@@ -64,7 +71,7 @@ public class InitialPhaseMetric {
public void setCredentialServiceStartedTimeNanoseconds(
long credentialServiceStartedTimeNanoseconds
) {
- this.mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds;
+ mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds;
}
public void setCredentialServiceBeginQueryTimeNanoseconds(
@@ -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;
}
@@ -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();
+ }
}
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 10bf56c853f5..18e04df9416a 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
@@ -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;
@@ -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;
@@ -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() {
@@ -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);
}