Collecting query framework exception and origin

This collects, for the candidate phase, specifically for Track 2 (but
this code will collect for both Tracks 1 and 2, with 1 just requiring
aggregators/totals), information about the origin and if a framework
exception occured or not. The length of the exception strings are still
to be decided by the team and this CL should be another place to discuss
that. Further E2E testing may also give good clarifications.

Bug: 271135048
Test: Build and E2E Test in Progress (Won't Submit till done)
Change-Id: Ic7baac708f64c9eea5eaca8c3426fb05286d0c33
This commit is contained in:
Arpan Kaphle
2023-04-17 19:10:26 +00:00
parent dc02288f23
commit 40b3810bc2
12 changed files with 81 additions and 43 deletions

View File

@@ -178,9 +178,11 @@ public class MetricUtilities {
*
* @param providers a map with known providers and their held metric objects
* @param emitSequenceId an emitted sequence id for the current session
* @param initialPhaseMetric contains initial phase data to avoid repetition for candidate
* phase, track 2, logging
*/
public static void logApiCalledCandidatePhase(Map<String, ProviderSession> providers,
int emitSequenceId) {
int emitSequenceId, InitialPhaseMetric initialPhaseMetric) {
try {
if (!LOG_FLAG) {
return;
@@ -200,6 +202,7 @@ public class MetricUtilities {
int[] candidateActionEntryCountList = new int[providerSize];
int[] candidateAuthEntryCountList = new int[providerSize];
int[] candidateRemoteEntryCountList = new int[providerSize];
String[] frameworkExceptionList = new String[providerSize];
int index = 0;
for (var session : providerSessions) {
CandidatePhaseMetric metric = session.mProviderSessionMetric
@@ -225,7 +228,7 @@ public class MetricUtilities {
candidateActionEntryCountList[index] = metric.getActionEntryCount();
candidateAuthEntryCountList[index] = metric.getAuthenticationEntryCount();
candidateRemoteEntryCountList[index] = metric.getRemoteEntryCount();
// frameworkExceptionList[index] = metric.getFrameworkException();
frameworkExceptionList[index] = metric.getFrameworkException();
index++;
}
FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED,
@@ -246,11 +249,16 @@ public class MetricUtilities {
/* candidate_provider_credential_entry_type_count */
candidateCredentialTypeCountList,
/* candidate_provider_remote_entry_count */ candidateRemoteEntryCountList,
/* candidate_provider_authentication_entry_count */ candidateAuthEntryCountList,
DEFAULT_REPEATED_STR,
false,
DEFAULT_REPEATED_STR,
DEFAULT_REPEATED_INT_32
/* candidate_provider_authentication_entry_count */
candidateAuthEntryCountList,
/* framework_exception_per_provider */
frameworkExceptionList,
/* origin_specified originSpecified */
initialPhaseMetric.isOriginSpecified(),
/* request_unique_classtypes */
initialPhaseMetric.getUniqueRequestStrings(),
/* per_classtype_counts */
initialPhaseMetric.getUniqueRequestCounts()
);
} catch (Exception e) {
Log.w(TAG, "Unexpected error during metric logging: " + e);

View File

@@ -91,6 +91,8 @@ public final class ProviderClearSession extends ProviderSession<ClearCredentialS
public void onProviderResponseFailure(int errorCode, Exception exception) {
if (exception instanceof ClearCredentialStateException) {
mProviderException = (ClearCredentialStateException) exception;
// TODO(b/271135048) : Decide on exception type length
mProviderSessionMetric.collectCandidateFrameworkException(mProviderException.getType());
}
mProviderSessionMetric.collectCandidateExceptionStatus(/*hasException=*/true);
updateStatusAndInvokeCallback(toStatus(errorCode),

View File

@@ -155,6 +155,8 @@ public final class ProviderCreateSession extends ProviderSession<
if (exception instanceof CreateCredentialException) {
// Store query phase exception for aggregation with final response
mProviderException = (CreateCredentialException) exception;
// TODO(b/271135048) : Decide on exception type length
mProviderSessionMetric.collectCandidateFrameworkException(mProviderException.getType());
}
mProviderSessionMetric.collectCandidateExceptionStatus(/*hasException=*/true);
updateStatusAndInvokeCallback(toStatus(errorCode),

View File

@@ -217,6 +217,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
public void onProviderResponseFailure(int errorCode, Exception exception) {
if (exception instanceof GetCredentialException) {
mProviderException = (GetCredentialException) exception;
// TODO(b/271135048) : Decide on exception type length
mProviderSessionMetric.collectCandidateFrameworkException(mProviderException.getType());
}
mProviderSessionMetric.collectCandidateExceptionStatus(/*hasException=*/true);
updateStatusAndInvokeCallback(toStatus(errorCode),

View File

@@ -57,7 +57,7 @@ CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_IS_ENABLED_CREDENT
);
ApiName(int innerMetricCode) {
this.mInnerMetricCode = innerMetricCode;
mInnerMetricCode = innerMetricCode;
}
/**
@@ -66,7 +66,7 @@ CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_IS_ENABLED_CREDENT
* @return a code corresponding to the west world metric name
*/
public int getMetricCode() {
return this.mInnerMetricCode;
return mInnerMetricCode;
}
/**

View File

@@ -32,7 +32,7 @@ public enum ApiStatus {
private final int mInnerMetricCode;
ApiStatus(int innerMetricCode) {
this.mInnerMetricCode = innerMetricCode;
mInnerMetricCode = innerMetricCode;
}
/**
@@ -41,6 +41,6 @@ public enum ApiStatus {
* @return a code corresponding to the west world metric name
*/
public int getMetricCode() {
return this.mInnerMetricCode;
return mInnerMetricCode;
}
}

View File

@@ -73,6 +73,8 @@ public class CandidatePhaseMetric {
private int mAuthenticationEntryCount = -1;
// Gathered to pass on to chosen provider when required
private final IntArray mAvailableEntries = new IntArray();
// The *framework only* exception held by this provider, empty string by default
private String mFrameworkException = "";
public CandidatePhaseMetric() {
}
@@ -82,27 +84,27 @@ public class CandidatePhaseMetric {
/* -- Timestamps -- */
public void setServiceBeganTimeNanoseconds(long serviceBeganTimeNanoseconds) {
this.mServiceBeganTimeNanoseconds = serviceBeganTimeNanoseconds;
mServiceBeganTimeNanoseconds = serviceBeganTimeNanoseconds;
}
public void setStartQueryTimeNanoseconds(long startQueryTimeNanoseconds) {
this.mStartQueryTimeNanoseconds = startQueryTimeNanoseconds;
mStartQueryTimeNanoseconds = startQueryTimeNanoseconds;
}
public void setQueryFinishTimeNanoseconds(long queryFinishTimeNanoseconds) {
this.mQueryFinishTimeNanoseconds = queryFinishTimeNanoseconds;
mQueryFinishTimeNanoseconds = queryFinishTimeNanoseconds;
}
public long getServiceBeganTimeNanoseconds() {
return this.mServiceBeganTimeNanoseconds;
return mServiceBeganTimeNanoseconds;
}
public long getStartQueryTimeNanoseconds() {
return this.mStartQueryTimeNanoseconds;
return mStartQueryTimeNanoseconds;
}
public long getQueryFinishTimeNanoseconds() {
return this.mQueryFinishTimeNanoseconds;
return mQueryFinishTimeNanoseconds;
}
/* -- Actual time delta latencies (for local utility) -- */
@@ -111,8 +113,8 @@ public class CandidatePhaseMetric {
* Returns the latency in microseconds for the query phase.
*/
public int getQueryLatencyMicroseconds() {
return (int) ((this.getQueryFinishTimeNanoseconds()
- this.getStartQueryTimeNanoseconds()) / 1000);
return (int) ((getQueryFinishTimeNanoseconds()
- getStartQueryTimeNanoseconds()) / 1000);
}
/* --- Time Stamp Conversion to Microseconds from Reference --- */
@@ -126,32 +128,32 @@ public class CandidatePhaseMetric {
* @return the microsecond integer timestamp from service start to query began
*/
public int getTimestampFromReferenceStartMicroseconds(long specificTimestamp) {
if (specificTimestamp < this.mServiceBeganTimeNanoseconds) {
if (specificTimestamp < mServiceBeganTimeNanoseconds) {
Log.i(TAG, "The timestamp is before service started, falling back to default int");
return MetricUtilities.DEFAULT_INT_32;
}
return (int) ((specificTimestamp
- this.mServiceBeganTimeNanoseconds) / 1000);
- mServiceBeganTimeNanoseconds) / 1000);
}
/* ------------- Provider Query Status ------------ */
public void setProviderQueryStatus(int providerQueryStatus) {
this.mProviderQueryStatus = providerQueryStatus;
mProviderQueryStatus = providerQueryStatus;
}
public int getProviderQueryStatus() {
return this.mProviderQueryStatus;
return mProviderQueryStatus;
}
/* -------------- Candidate Uid ---------------- */
public void setCandidateUid(int candidateUid) {
this.mCandidateUid = candidateUid;
mCandidateUid = candidateUid;
}
public int getCandidateUid() {
return this.mCandidateUid;
return mCandidateUid;
}
/* -------------- Session Id ---------------- */
@@ -254,7 +256,7 @@ public class CandidatePhaseMetric {
* collector
*/
public void addEntry(EntryEnum e) {
this.mAvailableEntries.add(e.getMetricCode());
mAvailableEntries.add(e.getMetricCode());
}
/**
@@ -267,4 +269,14 @@ public class CandidatePhaseMetric {
public List<Integer> getAvailableEntries() {
return Arrays.stream(mAvailableEntries.toArray()).boxed().collect(Collectors.toList());
}
/* ------ Framework Exception for this Candidate ------ */
public void setFrameworkException(String frameworkException) {
mFrameworkException = frameworkException;
}
public String getFrameworkException() {
return mFrameworkException;
}
}

View File

@@ -138,8 +138,8 @@ public class ChosenProviderFinalPhaseMetric {
}
public int getUiPhaseLatencyMicroseconds() {
return (int) ((this.mUiCallEndTimeNanoseconds
- this.mUiCallStartTimeNanoseconds) / 1000);
return (int) ((mUiCallEndTimeNanoseconds
- mUiCallStartTimeNanoseconds) / 1000);
}
/**
@@ -147,8 +147,8 @@ public class ChosenProviderFinalPhaseMetric {
* start time to be provided, such as from {@link CandidatePhaseMetric}.
*/
public int getEntireProviderLatencyMicroseconds() {
return (int) ((this.mFinalFinishTimeNanoseconds
- this.mQueryStartTimeNanoseconds) / 1000);
return (int) ((mFinalFinishTimeNanoseconds
- mQueryStartTimeNanoseconds) / 1000);
}
/**
@@ -156,8 +156,8 @@ public class ChosenProviderFinalPhaseMetric {
* start time to be provided, such as from {@link InitialPhaseMetric}.
*/
public int getEntireLatencyMicroseconds() {
return (int) ((this.mFinalFinishTimeNanoseconds
- this.mServiceBeganTimeNanoseconds) / 1000);
return (int) ((mFinalFinishTimeNanoseconds
- mServiceBeganTimeNanoseconds) / 1000);
}
/* ----- Timestamps for Latency ----- */
@@ -183,11 +183,11 @@ public class ChosenProviderFinalPhaseMetric {
}
public void setUiCallStartTimeNanoseconds(long uiCallStartTimeNanoseconds) {
this.mUiCallStartTimeNanoseconds = uiCallStartTimeNanoseconds;
mUiCallStartTimeNanoseconds = uiCallStartTimeNanoseconds;
}
public void setUiCallEndTimeNanoseconds(long uiCallEndTimeNanoseconds) {
this.mUiCallEndTimeNanoseconds = uiCallEndTimeNanoseconds;
mUiCallEndTimeNanoseconds = uiCallEndTimeNanoseconds;
}
public void setFinalFinishTimeNanoseconds(long finalFinishTimeNanoseconds) {
@@ -229,12 +229,12 @@ public class ChosenProviderFinalPhaseMetric {
* @return the microsecond integer timestamp from service start to query began
*/
public int getTimestampFromReferenceStartMicroseconds(long specificTimestamp) {
if (specificTimestamp < this.mServiceBeganTimeNanoseconds) {
if (specificTimestamp < mServiceBeganTimeNanoseconds) {
Log.i(TAG, "The timestamp is before service started, falling back to default int");
return MetricUtilities.DEFAULT_INT_32;
}
return (int) ((specificTimestamp
- this.mServiceBeganTimeNanoseconds) / 1000);
- mServiceBeganTimeNanoseconds) / 1000);
}
/* ----------- Provider Status -------------- */
@@ -334,7 +334,7 @@ public class ChosenProviderFinalPhaseMetric {
* chosen phase in a semantically correct way.
*/
public void setAvailableEntries(List<Integer> entries) {
this.mAvailableEntries = new ArrayList<>(entries); // no alias copy
mAvailableEntries = new ArrayList<>(entries); // no alias copy
}
/**
@@ -345,7 +345,7 @@ public class ChosenProviderFinalPhaseMetric {
* candidate phase.
*/
public List<Integer> getAvailableEntries() {
return new ArrayList<>(this.mAvailableEntries); // no alias copy
return new ArrayList<>(mAvailableEntries); // no alias copy
}
/* -------------- Has Exception ---------------- */

View File

@@ -56,7 +56,7 @@ public enum EntryEnum {
);
EntryEnum(int innerMetricCode) {
this.mInnerMetricCode = innerMetricCode;
mInnerMetricCode = innerMetricCode;
}
/**
@@ -65,7 +65,7 @@ public enum EntryEnum {
* @return a code corresponding to the west world metric name
*/
public int getMetricCode() {
return this.mInnerMetricCode;
return mInnerMetricCode;
}
/**

View File

@@ -60,6 +60,18 @@ public class ProviderSessionMetric {
mCandidatePhasePerProviderMetric.setHasException(hasException);
}
/**
* Collects the framework only exception encountered in a candidate flow.
* @param exceptionType the string, cut to desired length, of the exception type
*/
public void collectCandidateFrameworkException(String exceptionType) {
try {
mCandidatePhasePerProviderMetric.setFrameworkException(exceptionType);
} catch (Exception e) {
Log.w(TAG, "Unexpected error during metric logging: " + e);
}
}
/**
* Used to collect metrics at the update stage when a candidate provider gives back an update.
*

View File

@@ -38,7 +38,7 @@ public enum ProviderStatusForMetrics {
private final int mInnerMetricCode;
ProviderStatusForMetrics(int innerMetricCode) {
this.mInnerMetricCode = innerMetricCode;
mInnerMetricCode = innerMetricCode;
}
/**
@@ -47,6 +47,6 @@ public enum ProviderStatusForMetrics {
* @return a code corresponding to the west world metric name
*/
public int getMetricCode() {
return this.mInnerMetricCode;
return mInnerMetricCode;
}
}

View File

@@ -324,7 +324,7 @@ public class RequestSessionMetric {
*/
public void logCandidatePhaseMetrics(Map<String, ProviderSession> providers) {
try {
logApiCalledCandidatePhase(providers, ++mSequenceCounter);
logApiCalledCandidatePhase(providers, ++mSequenceCounter, mInitialPhaseMetric);
} catch (Exception e) {
Log.w(TAG, "Unexpected error during metric logging: " + e);
}