Merge "Candidate Metric Utilized in Framework" into udc-dev
This commit is contained in:
@@ -168,7 +168,7 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
|
||||
|
||||
private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
|
||||
Log.i(TAG, "respondToClientWithErrorAndFinish");
|
||||
|
||||
// TODO add exception bit
|
||||
if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
|
||||
Log.i(TAG, "Request has already been completed. This is strange.");
|
||||
return;
|
||||
|
||||
@@ -592,9 +592,13 @@ public final class CredentialManagerService
|
||||
}
|
||||
|
||||
private void finalizeAndEmitInitialPhaseMetric(RequestSession session) {
|
||||
var initMetric = session.mInitialPhaseMetric;
|
||||
initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime());
|
||||
MetricUtilities.logApiCalled(initMetric);
|
||||
try {
|
||||
var initMetric = session.mInitialPhaseMetric;
|
||||
initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime());
|
||||
MetricUtilities.logApiCalled(initMetric);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -80,6 +80,34 @@ public class MetricUtilities {
|
||||
return (int) ((t2 - t1) / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* A logging utility used primarily for the candidate phase of the current metric setup.
|
||||
*
|
||||
* @param providers a map with known providers
|
||||
* @param emitSequenceId an emitted sequence id for the current session
|
||||
*/
|
||||
protected static void logApiCalled(Map<String, ProviderSession> providers,
|
||||
int emitSequenceId) {
|
||||
try {
|
||||
var providerSessions = providers.values();
|
||||
int providerSize = providerSessions.size();
|
||||
int[] candidateUidList = new int[providerSize];
|
||||
int[] candidateQueryRoundTripTimeList = new int[providerSize];
|
||||
int[] candidateStatusList = new int[providerSize];
|
||||
int index = 0;
|
||||
for (var session : providerSessions) {
|
||||
CandidatePhaseMetric metric = session.mCandidatePhasePerProviderMetric;
|
||||
candidateUidList[index] = metric.getCandidateUid();
|
||||
candidateQueryRoundTripTimeList[index] = metric.getQueryLatencyMicroseconds();
|
||||
candidateStatusList[index] = metric.getProviderQueryStatus();
|
||||
index++;
|
||||
}
|
||||
// TODO Handle the emit here
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The most common logging helper, handles the overall status of the API request with the
|
||||
* provider status and latencies. Other versions of this method may be more useful depending
|
||||
@@ -90,6 +118,7 @@ public class MetricUtilities {
|
||||
* @param providers a map with known providers
|
||||
* @param callingUid the calling UID of the client app
|
||||
* @param chosenProviderFinalPhaseMetric the metric data type of the final chosen provider
|
||||
* TODO remove soon
|
||||
*/
|
||||
protected static void logApiCalled(ApiName apiName, ApiStatus apiStatus,
|
||||
Map<String, ProviderSession> providers, int callingUid,
|
||||
@@ -133,6 +162,7 @@ public class MetricUtilities {
|
||||
* contain default values for all other optional parameters.
|
||||
*
|
||||
* TODO(b/271135048) - given space requirements, this may be a good candidate for another atom
|
||||
* TODO immediately remove and carry over TODO to new log for this setup
|
||||
*
|
||||
* @param apiName the api name to log
|
||||
* @param apiStatus the status to log
|
||||
|
||||
@@ -33,7 +33,7 @@ import android.util.Slog;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class ProviderClearSession extends ProviderSession<ClearCredentialStateRequest,
|
||||
public final class ProviderClearSession extends ProviderSession<ClearCredentialStateRequest,
|
||||
Void>
|
||||
implements
|
||||
RemoteCredentialService.ProviderCallbacks<Void> {
|
||||
@@ -42,7 +42,8 @@ public final class ProviderClearSession extends ProviderSession<ClearCredential
|
||||
private ClearCredentialStateException mProviderException;
|
||||
|
||||
/** Creates a new provider session to be used by the request session. */
|
||||
@Nullable public static ProviderClearSession createNewSession(
|
||||
@Nullable
|
||||
public static ProviderClearSession createNewSession(
|
||||
Context context,
|
||||
@UserIdInt int userId,
|
||||
CredentialProviderInfo providerInfo,
|
||||
@@ -53,7 +54,7 @@ public final class ProviderClearSession extends ProviderSession<ClearCredential
|
||||
clearRequestSession.mClientRequest,
|
||||
clearRequestSession.mClientAppInfo);
|
||||
return new ProviderClearSession(context, providerInfo, clearRequestSession, userId,
|
||||
remoteCredentialService, providerRequest);
|
||||
remoteCredentialService, providerRequest);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -90,6 +91,7 @@ public final class ProviderClearSession extends ProviderSession<ClearCredential
|
||||
if (exception instanceof ClearCredentialStateException) {
|
||||
mProviderException = (ClearCredentialStateException) exception;
|
||||
}
|
||||
captureCandidateFailure();
|
||||
updateStatusAndInvokeCallback(toStatus(errorCode));
|
||||
}
|
||||
|
||||
@@ -120,14 +122,7 @@ public final class ProviderClearSession extends ProviderSession<ClearCredential
|
||||
@Override
|
||||
protected void invokeSession() {
|
||||
if (mRemoteCredentialService != null) {
|
||||
/*
|
||||
InitialPhaseMetric initMetric = ((RequestSession)mCallbacks).initMetric;
|
||||
TODO immediately once the other change patched through
|
||||
mCandidateProviderMetric.setSessionId(initMetric
|
||||
.mInitialPhaseMetric.getSessionId());
|
||||
mCandidateProviderMetric.setStartTime(initMetric.getStartTime())
|
||||
*/
|
||||
mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
|
||||
startCandidateMetrics();
|
||||
mRemoteCredentialService.onClearCredentialState(mProviderRequest, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.credentials.metrics.EntryEnum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -65,7 +67,8 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
private final ProviderResponseDataHandler mProviderResponseDataHandler;
|
||||
|
||||
/** Creates a new provider session to be used by the request session. */
|
||||
@Nullable public static ProviderCreateSession createNewSession(
|
||||
@Nullable
|
||||
public static ProviderCreateSession createNewSession(
|
||||
Context context,
|
||||
@UserIdInt int userId,
|
||||
CredentialProviderInfo providerInfo,
|
||||
@@ -155,6 +158,7 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
// Store query phase exception for aggregation with final response
|
||||
mProviderException = (CreateCredentialException) exception;
|
||||
}
|
||||
captureCandidateFailure();
|
||||
updateStatusAndInvokeCallback(toStatus(errorCode));
|
||||
}
|
||||
|
||||
@@ -175,14 +179,32 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
mProviderResponseDataHandler.addResponseContent(response.getCreateEntries(),
|
||||
response.getRemoteCreateEntry());
|
||||
if (mProviderResponseDataHandler.isEmptyResponse(response)) {
|
||||
gatheCandidateEntryMetrics(response);
|
||||
updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
|
||||
} else {
|
||||
gatheCandidateEntryMetrics(response);
|
||||
updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED);
|
||||
}
|
||||
}
|
||||
|
||||
private void gatheCandidateEntryMetrics(BeginCreateCredentialResponse response) {
|
||||
try {
|
||||
var createEntries = response.getCreateEntries();
|
||||
int numCreateEntries = createEntries == null ? 0 : createEntries.size();
|
||||
// TODO confirm how to get types from slice
|
||||
if (numCreateEntries > 0) {
|
||||
createEntries.forEach(c ->
|
||||
mCandidatePhasePerProviderMetric.addEntry(EntryEnum.CREDENTIAL_ENTRY));
|
||||
}
|
||||
mCandidatePhasePerProviderMetric.setNumEntriesTotal(numCreateEntries);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable protected CreateCredentialProviderData prepareUiData()
|
||||
@Nullable
|
||||
protected CreateCredentialProviderData prepareUiData()
|
||||
throws IllegalArgumentException {
|
||||
Log.i(TAG, "In prepareUiData");
|
||||
if (!ProviderSession.isUiInvokingStatus(getStatus())) {
|
||||
@@ -226,14 +248,7 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
@Override
|
||||
protected void invokeSession() {
|
||||
if (mRemoteCredentialService != null) {
|
||||
/*
|
||||
InitialPhaseMetric initMetric = ((RequestSession)mCallbacks).initMetric;
|
||||
TODO immediately once the other change patched through
|
||||
mCandidateProviderMetric.setSessionId(initMetric
|
||||
.mInitialPhaseMetric.getSessionId());
|
||||
mCandidateProviderMetric.setStartTime(initMetric.getStartTime())
|
||||
*/
|
||||
mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
|
||||
startCandidateMetrics();
|
||||
mRemoteCredentialService.onCreateCredential(mProviderRequest, this);
|
||||
}
|
||||
}
|
||||
@@ -305,12 +320,14 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
}
|
||||
|
||||
private class ProviderResponseDataHandler {
|
||||
@Nullable private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
@Nullable
|
||||
private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
|
||||
@NonNull
|
||||
private final Map<String, Pair<CreateEntry, Entry>> mUiCreateEntries = new HashMap<>();
|
||||
|
||||
@Nullable private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
|
||||
@Nullable
|
||||
private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
|
||||
|
||||
ProviderResponseDataHandler(@Nullable ComponentName expectedRemoteEntryProviderService) {
|
||||
mExpectedRemoteEntryProviderService = expectedRemoteEntryProviderService;
|
||||
@@ -323,6 +340,7 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
setRemoteEntry(remoteEntry);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCreateEntry(CreateEntry createEntry) {
|
||||
String id = generateUniqueId();
|
||||
Entry entry = new Entry(SAVE_ENTRY_KEY,
|
||||
@@ -373,6 +391,7 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
private boolean isEmptyResponse() {
|
||||
return mUiCreateEntries.isEmpty() && mUiRemoteEntry == null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RemoteEntry getRemoteEntry(String entryKey) {
|
||||
return mUiRemoteEntry == null || mUiRemoteEntry
|
||||
|
||||
@@ -43,6 +43,8 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.credentials.metrics.EntryEnum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -82,7 +84,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
private final ProviderResponseDataHandler mProviderResponseDataHandler;
|
||||
|
||||
/** Creates a new provider session to be used by the request session. */
|
||||
@Nullable public static ProviderGetSession createNewSession(
|
||||
@Nullable
|
||||
public static ProviderGetSession createNewSession(
|
||||
Context context,
|
||||
@UserIdInt int userId,
|
||||
CredentialProviderInfo providerInfo,
|
||||
@@ -113,6 +116,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
Log.i(TAG, "Unable to create provider session");
|
||||
return null;
|
||||
}
|
||||
|
||||
private static BeginGetCredentialRequest constructQueryPhaseRequest(
|
||||
android.credentials.GetCredentialRequest filteredRequest,
|
||||
CallingAppInfo callingAppInfo,
|
||||
@@ -169,7 +173,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
CallingAppInfo callingAppInfo,
|
||||
Map<String, CredentialOption> beginGetOptionToCredentialOptionMap,
|
||||
String hybridService) {
|
||||
super(context, beginGetRequest, callbacks, info.getComponentName() ,
|
||||
super(context, beginGetRequest, callbacks, info.getComponentName(),
|
||||
userId, remoteCredentialService);
|
||||
mCompleteRequest = completeGetRequest;
|
||||
mCallingAppInfo = callingAppInfo;
|
||||
@@ -191,6 +195,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
if (exception instanceof GetCredentialException) {
|
||||
mProviderException = (GetCredentialException) exception;
|
||||
}
|
||||
captureCandidateFailure();
|
||||
updateStatusAndInvokeCallback(toStatus(errorCode));
|
||||
}
|
||||
|
||||
@@ -269,20 +274,14 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
@Override
|
||||
protected void invokeSession() {
|
||||
if (mRemoteCredentialService != null) {
|
||||
/*
|
||||
InitialPhaseMetric initMetric = ((RequestSession)mCallbacks).initMetric;
|
||||
TODO immediately once the other change patched through
|
||||
mCandidateProviderMetric.setSessionId(initMetric
|
||||
.mInitialPhaseMetric.getSessionId());
|
||||
mCandidateProviderMetric.setStartTime(initMetric.getStartTime())
|
||||
*/
|
||||
mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
|
||||
startCandidateMetrics();
|
||||
mRemoteCredentialService.onBeginGetCredential(mProviderRequest, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // Call from request session to data to be shown on the UI
|
||||
@Nullable protected GetCredentialProviderData prepareUiData() throws IllegalArgumentException {
|
||||
@Nullable
|
||||
protected GetCredentialProviderData prepareUiData() throws IllegalArgumentException {
|
||||
Log.i(TAG, "In prepareUiData");
|
||||
if (!ProviderSession.isUiInvokingStatus(getStatus())) {
|
||||
Log.i(TAG, "In prepareUiData - provider does not want to show UI: "
|
||||
@@ -389,6 +388,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
GetCredentialException exception = maybeGetPendingIntentException(
|
||||
providerPendingIntentResponse);
|
||||
if (exception != null) {
|
||||
// TODO (b/271135048), for AuthenticationEntry callback selection, set error
|
||||
invokeCallbackWithError(exception.getType(),
|
||||
exception.getMessage());
|
||||
// Additional content received is in the form of an exception which ends the flow.
|
||||
@@ -439,11 +439,34 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
|
||||
return;
|
||||
}
|
||||
// TODO immediately, add to Candidate Phase counts, repeat across all sessions
|
||||
// Use sets to dedup type counts
|
||||
gatherCandidateEntryMetrics(response);
|
||||
updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
|
||||
}
|
||||
|
||||
private void gatherCandidateEntryMetrics(BeginGetCredentialResponse response) {
|
||||
try {
|
||||
int numCredEntries = response.getCredentialEntries().size();
|
||||
int numActionEntries = response.getActions().size();
|
||||
int numAuthEntries = response.getAuthenticationActions().size();
|
||||
// TODO immediately add remote entries
|
||||
// TODO immediately confirm how to get types from slice to get unique type count via
|
||||
// dedupe
|
||||
response.getCredentialEntries().forEach(c ->
|
||||
mCandidatePhasePerProviderMetric.addEntry(EntryEnum.CREDENTIAL_ENTRY));
|
||||
response.getActions().forEach(c ->
|
||||
mCandidatePhasePerProviderMetric.addEntry(EntryEnum.ACTION_ENTRY));
|
||||
response.getAuthenticationActions().forEach(c ->
|
||||
mCandidatePhasePerProviderMetric.addEntry(EntryEnum.AUTHENTICATION_ENTRY));
|
||||
mCandidatePhasePerProviderMetric.setNumEntriesTotal(numCredEntries + numAuthEntries
|
||||
+ numActionEntries);
|
||||
mCandidatePhasePerProviderMetric.setCredentialEntryCount(numCredEntries);
|
||||
mCandidatePhasePerProviderMetric.setActionEntryCount(numActionEntries);
|
||||
mCandidatePhasePerProviderMetric.setAuthenticationEntryCount(numAuthEntries);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When an invalid state occurs, e.g. entry mismatch or no response from provider,
|
||||
* we send back a TYPE_NO_CREDENTIAL error as to the developer.
|
||||
@@ -471,11 +494,12 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
.STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT
|
||||
|| e.second.getStatus()
|
||||
== AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
private class ProviderResponseDataHandler {
|
||||
@Nullable private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
@Nullable
|
||||
private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
@NonNull
|
||||
private final Map<String, Pair<CredentialEntry, Entry>> mUiCredentialEntries =
|
||||
new HashMap<>();
|
||||
@@ -485,7 +509,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
private final Map<String, Pair<Action, AuthenticationEntry>> mUiAuthenticationEntries =
|
||||
new HashMap<>();
|
||||
|
||||
@Nullable private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
|
||||
@Nullable
|
||||
private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
|
||||
|
||||
ProviderResponseDataHandler(@Nullable ComponentName expectedRemoteEntryProviderService) {
|
||||
mExpectedRemoteEntryProviderService = expectedRemoteEntryProviderService;
|
||||
@@ -509,6 +534,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
setRemoteEntry(remoteEntry);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCredentialEntry(CredentialEntry credentialEntry) {
|
||||
String id = generateUniqueId();
|
||||
Entry entry = new Entry(CREDENTIAL_ENTRY_KEY,
|
||||
@@ -559,7 +585,6 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
}
|
||||
|
||||
|
||||
|
||||
public GetCredentialProviderData toGetCredentialProviderData() {
|
||||
return new GetCredentialProviderData.Builder(
|
||||
mComponentName.flattenToString()).setActionChips(prepareActionEntries())
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.server.credentials.metrics.CandidatePhaseMetric;
|
||||
import com.android.server.credentials.metrics.InitialPhaseMetric;
|
||||
import com.android.server.credentials.metrics.ProviderStatusForMetrics;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -72,8 +73,9 @@ public abstract class ProviderSession<T, R>
|
||||
@NonNull
|
||||
protected Boolean mProviderResponseSet = false;
|
||||
// Specific candidate provider metric for the provider this session handles
|
||||
@Nullable
|
||||
protected CandidatePhaseMetric mCandidatePhasePerProviderMetric;
|
||||
@NonNull
|
||||
protected final CandidatePhaseMetric mCandidatePhasePerProviderMetric =
|
||||
new CandidatePhaseMetric();
|
||||
@NonNull
|
||||
private int mProviderSessionUid;
|
||||
|
||||
@@ -143,7 +145,6 @@ public abstract class ProviderSession<T, R>
|
||||
mUserId = userId;
|
||||
mComponentName = componentName;
|
||||
mRemoteCredentialService = remoteCredentialService;
|
||||
mCandidatePhasePerProviderMetric = new CandidatePhaseMetric();
|
||||
mProviderSessionUid = MetricUtilities.getPackageUid(mContext, mComponentName);
|
||||
}
|
||||
|
||||
@@ -208,6 +209,12 @@ public abstract class ProviderSession<T, R>
|
||||
return mRemoteCredentialService;
|
||||
}
|
||||
|
||||
protected void captureCandidateFailure() {
|
||||
mCandidatePhasePerProviderMetric.setHasException(true);
|
||||
// TODO(b/271135048) - this is a true exception, but what about the empty case?
|
||||
// Add more nuance in next iteration.
|
||||
}
|
||||
|
||||
/** Updates the status . */
|
||||
protected void updateStatusAndInvokeCallback(@NonNull Status status) {
|
||||
setStatus(status);
|
||||
@@ -216,18 +223,37 @@ public abstract class ProviderSession<T, R>
|
||||
}
|
||||
|
||||
private void updateCandidateMetric(Status status) {
|
||||
mCandidatePhasePerProviderMetric.setCandidateUid(mProviderSessionUid);
|
||||
// TODO immediately update the candidate phase here to have more new data
|
||||
mCandidatePhasePerProviderMetric
|
||||
.setQueryFinishTimeNanoseconds(System.nanoTime());
|
||||
if (isTerminatingStatus(status)) {
|
||||
mCandidatePhasePerProviderMetric.setProviderQueryStatus(
|
||||
ProviderStatusForMetrics.QUERY_FAILURE
|
||||
.getMetricCode());
|
||||
} else if (isCompletionStatus(status)) {
|
||||
mCandidatePhasePerProviderMetric.setProviderQueryStatus(
|
||||
ProviderStatusForMetrics.QUERY_SUCCESS
|
||||
.getMetricCode());
|
||||
try {
|
||||
mCandidatePhasePerProviderMetric.setCandidateUid(mProviderSessionUid);
|
||||
// TODO immediately update the candidate phase here to have more new data
|
||||
mCandidatePhasePerProviderMetric
|
||||
.setQueryFinishTimeNanoseconds(System.nanoTime());
|
||||
if (isTerminatingStatus(status)) {
|
||||
mCandidatePhasePerProviderMetric.setQueryReturned(false);
|
||||
mCandidatePhasePerProviderMetric.setProviderQueryStatus(
|
||||
ProviderStatusForMetrics.QUERY_FAILURE
|
||||
.getMetricCode());
|
||||
} else if (isCompletionStatus(status)) {
|
||||
mCandidatePhasePerProviderMetric.setQueryReturned(true);
|
||||
mCandidatePhasePerProviderMetric.setProviderQueryStatus(
|
||||
ProviderStatusForMetrics.QUERY_SUCCESS
|
||||
.getMetricCode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
// Common method to transfer metrics from the initial phase to the candidate phase per provider
|
||||
protected void startCandidateMetrics() {
|
||||
try {
|
||||
InitialPhaseMetric initMetric = ((RequestSession) mCallbacks).mInitialPhaseMetric;
|
||||
mCandidatePhasePerProviderMetric.setSessionId(initMetric.getSessionId());
|
||||
mCandidatePhasePerProviderMetric.setServiceBeganTimeNanoseconds(
|
||||
initMetric.getCredentialServiceStartedTimeNanoseconds());
|
||||
mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
protected final CancellationSignal mCancellationSignal;
|
||||
|
||||
protected final Map<String, ProviderSession> mProviders = new HashMap<>();
|
||||
protected InitialPhaseMetric mInitialPhaseMetric = new InitialPhaseMetric();
|
||||
protected ChosenProviderFinalPhaseMetric
|
||||
protected final InitialPhaseMetric mInitialPhaseMetric = new InitialPhaseMetric();
|
||||
protected final ChosenProviderFinalPhaseMetric
|
||||
mChosenProviderFinalPhaseMetric = new ChosenProviderFinalPhaseMetric();
|
||||
|
||||
// TODO(b/271135048) - Group metrics used in a scope together, such as here in RequestSession
|
||||
@@ -123,9 +123,17 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
mUserId, this);
|
||||
mHybridService = context.getResources().getString(
|
||||
R.string.config_defaultCredentialManagerHybridService);
|
||||
mInitialPhaseMetric.setCredentialServiceStartedTimeNanoseconds(timestampStarted);
|
||||
mInitialPhaseMetric.setSessionId(mRequestId.hashCode());
|
||||
mInitialPhaseMetric.setCallerUid(mCallingUid);
|
||||
initialPhaseMetricSetup(timestampStarted);
|
||||
}
|
||||
|
||||
private void initialPhaseMetricSetup(long timestampStarted) {
|
||||
try {
|
||||
mInitialPhaseMetric.setCredentialServiceStartedTimeNanoseconds(timestampStarted);
|
||||
mInitialPhaseMetric.setSessionId(mRequestId.hashCode());
|
||||
mInitialPhaseMetric.setCallerUid(mCallingUid);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract ProviderSession initiateProviderSession(CredentialProviderInfo providerInfo,
|
||||
@@ -170,13 +178,17 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
|
||||
private void logBrowsingPhasePerSelect(UserSelectionDialogResult selection,
|
||||
ProviderSession providerSession) {
|
||||
CandidateBrowsingPhaseMetric browsingPhaseMetric = new CandidateBrowsingPhaseMetric();
|
||||
browsingPhaseMetric.setSessionId(this.mInitialPhaseMetric.getSessionId());
|
||||
browsingPhaseMetric.setEntryEnum(
|
||||
EntryEnum.getMetricCodeFromString(selection.getEntryKey()));
|
||||
browsingPhaseMetric.setProviderUid(providerSession.mCandidatePhasePerProviderMetric
|
||||
.getCandidateUid());
|
||||
this.mCandidateBrowsingPhaseMetric.add(new CandidateBrowsingPhaseMetric());
|
||||
try {
|
||||
CandidateBrowsingPhaseMetric browsingPhaseMetric = new CandidateBrowsingPhaseMetric();
|
||||
browsingPhaseMetric.setSessionId(this.mInitialPhaseMetric.getSessionId());
|
||||
browsingPhaseMetric.setEntryEnum(
|
||||
EntryEnum.getMetricCodeFromString(selection.getEntryKey()));
|
||||
browsingPhaseMetric.setProviderUid(providerSession.mCandidatePhasePerProviderMetric
|
||||
.getCandidateUid());
|
||||
this.mCandidateBrowsingPhaseMetric.add(new CandidateBrowsingPhaseMetric());
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void finishSession(boolean propagateCancellation) {
|
||||
@@ -233,6 +245,7 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
Log.i(TAG, "In getProviderDataAndInitiateUi providers size: " + mProviders.size());
|
||||
|
||||
if (isSessionCancelled()) {
|
||||
MetricUtilities.logApiCalled(mProviders, ++mSequenceCounter);
|
||||
finishSession(/*propagateCancellation=*/true);
|
||||
return;
|
||||
}
|
||||
@@ -248,13 +261,8 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
}
|
||||
if (!providerDataList.isEmpty()) {
|
||||
Log.i(TAG, "provider list not empty about to initiate ui");
|
||||
// TODO immediately Add paths to end it (say it fails)
|
||||
if (isSessionCancelled()) {
|
||||
Log.i(TAG, "In getProviderDataAndInitiateUi but session has been cancelled");
|
||||
// TODO immedaitely Add paths
|
||||
} else {
|
||||
launchUiWithProviderData(providerDataList);
|
||||
}
|
||||
MetricUtilities.logApiCalled(mProviders, ++mSequenceCounter);
|
||||
launchUiWithProviderData(providerDataList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,22 +272,27 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
* @param componentName the componentName to associate with a provider
|
||||
*/
|
||||
protected void setChosenMetric(ComponentName componentName) {
|
||||
CandidatePhaseMetric metric = this.mProviders.get(componentName.flattenToString())
|
||||
.mCandidatePhasePerProviderMetric;
|
||||
try {
|
||||
CandidatePhaseMetric metric = this.mProviders.get(componentName.flattenToString())
|
||||
.mCandidatePhasePerProviderMetric;
|
||||
|
||||
mChosenProviderFinalPhaseMetric.setSessionId(metric.getSessionId());
|
||||
mChosenProviderFinalPhaseMetric.setChosenUid(metric.getCandidateUid());
|
||||
mChosenProviderFinalPhaseMetric.setSessionId(metric.getSessionId());
|
||||
mChosenProviderFinalPhaseMetric.setChosenUid(metric.getCandidateUid());
|
||||
|
||||
mChosenProviderFinalPhaseMetric.setQueryPhaseLatencyMicroseconds(
|
||||
metric.getQueryLatencyMicroseconds());
|
||||
mChosenProviderFinalPhaseMetric.setQueryPhaseLatencyMicroseconds(
|
||||
metric.getQueryLatencyMicroseconds());
|
||||
|
||||
mChosenProviderFinalPhaseMetric.setServiceBeganTimeNanoseconds(
|
||||
metric.getServiceBeganTimeNanoseconds());
|
||||
mChosenProviderFinalPhaseMetric.setQueryStartTimeNanoseconds(
|
||||
metric.getStartQueryTimeNanoseconds());
|
||||
mChosenProviderFinalPhaseMetric.setServiceBeganTimeNanoseconds(
|
||||
metric.getServiceBeganTimeNanoseconds());
|
||||
mChosenProviderFinalPhaseMetric.setQueryStartTimeNanoseconds(
|
||||
metric.getStartQueryTimeNanoseconds());
|
||||
|
||||
// TODO immediately update with the entry count numbers from the candidate metrics
|
||||
// TODO immediately update with the entry count numbers from the candidate metrics
|
||||
// TODO immediately add the exception bit for candidates and providers
|
||||
|
||||
mChosenProviderFinalPhaseMetric.setFinalFinishTimeNanoseconds(System.nanoTime());
|
||||
mChosenProviderFinalPhaseMetric.setFinalFinishTimeNanoseconds(System.nanoTime());
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unexpected error during metric logging: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ import android.util.Log;
|
||||
|
||||
import com.android.server.credentials.MetricUtilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The central candidate provider metric object that mimics our defined metric setup.
|
||||
* Some types are redundant across these metric collectors, but that has debug use-cases as
|
||||
@@ -66,6 +69,8 @@ public class CandidatePhaseMetric {
|
||||
private int mRemoteEntryCount = -1;
|
||||
// The count of authentication entries from this provider, defaults to -1
|
||||
private int mAuthenticationEntryCount = -1;
|
||||
// Gathered to pass on to chosen provider when required
|
||||
private List<EntryEnum> mAvailableEntries = new ArrayList<>();
|
||||
|
||||
public CandidatePhaseMetric() {
|
||||
}
|
||||
@@ -236,4 +241,28 @@ public class CandidatePhaseMetric {
|
||||
public int getAuthenticationEntryCount() {
|
||||
return mAuthenticationEntryCount;
|
||||
}
|
||||
|
||||
/* -------------- The Entries Gathered ---------------- */
|
||||
|
||||
/**
|
||||
* Allows adding an entry record to this metric collector, which can then be propagated to
|
||||
* the final phase to retain information on the data available to the candidate.
|
||||
*
|
||||
* @param e the entry enum collected by the candidate provider associated with this metric
|
||||
* collector
|
||||
*/
|
||||
public void addEntry(EntryEnum e) {
|
||||
this.mAvailableEntries.add(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a safely copied list of the entries captured by this metric collector associated
|
||||
* with a particular candidate provider.
|
||||
*
|
||||
* @return the full collection of entries encountered by the candidate provider associated with
|
||||
* this metric
|
||||
*/
|
||||
public List<EntryEnum> getAvailableEntries() {
|
||||
return new ArrayList<>(this.mAvailableEntries); // no alias copy
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user