Placing InitialPhase Emit in Proper Locations
Note, some details, such as query start, can be optimized in future versions. For example, we could use min(provider_start_1, provider_start_2, ....) = query_start, and emit it. Alternatievely, we could do this in the backend. For now, I've gone and made it a general time that is un-emitted but exists as a utility locally. We may choose to emit it in future versions as more granular backend queries are developed. Bug: 270403549 Test: To be chained in, builds for now Change-Id: I6041bd6fd2d62c7ea501ccb3094a886dd9aa2758
This commit is contained in:
@@ -46,9 +46,11 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta
|
||||
|
||||
public ClearRequestSession(Context context, int userId, int callingUid,
|
||||
IClearCredentialStateCallback callback, ClearCredentialStateRequest request,
|
||||
CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal) {
|
||||
CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal,
|
||||
long startedTimestamp) {
|
||||
super(context, userId, callingUid, request, callback, RequestInfo.TYPE_UNDEFINED,
|
||||
callingAppInfo, cancellationSignal);
|
||||
callingAppInfo, cancellationSignal, startedTimestamp);
|
||||
setupInitialPhaseMetric(ApiName.CLEAR_CREDENTIAL.getMetricCode(), MetricUtilities.ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,9 +53,11 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
|
||||
CreateCredentialRequest request,
|
||||
ICreateCredentialCallback callback,
|
||||
CallingAppInfo callingAppInfo,
|
||||
CancellationSignal cancellationSignal) {
|
||||
CancellationSignal cancellationSignal,
|
||||
long startedTimestamp) {
|
||||
super(context, userId, callingUid, request, callback, RequestInfo.TYPE_CREATE,
|
||||
callingAppInfo, cancellationSignal);
|
||||
callingAppInfo, cancellationSignal, startedTimestamp);
|
||||
setupInitialPhaseMetric(ApiName.CREATE_CREDENTIAL.getMetricCode(), MetricUtilities.UNIT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -230,8 +230,10 @@ public final class CredentialManagerService
|
||||
if (hasPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new SecurityException("Caller is missing permission: QUERY_ALL_PACKAGES or LIST_ENABLED_CREDENTIAL_PROVIDERS");
|
||||
|
||||
throw new SecurityException(
|
||||
"Caller is missing permission: QUERY_ALL_PACKAGES or "
|
||||
+ "LIST_ENABLED_CREDENTIAL_PROVIDERS");
|
||||
}
|
||||
|
||||
private boolean hasPermission(String permission) {
|
||||
@@ -408,6 +410,7 @@ public final class CredentialManagerService
|
||||
GetCredentialRequest request,
|
||||
IGetCredentialCallback callback,
|
||||
final String callingPackage) {
|
||||
final long timestampBegan = System.nanoTime();
|
||||
Log.i(TAG, "starting executeGetCredential with callingPackage: " + callingPackage);
|
||||
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
|
||||
|
||||
@@ -429,7 +432,8 @@ public final class CredentialManagerService
|
||||
callback,
|
||||
request,
|
||||
constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
|
||||
CancellationSignal.fromTransport(cancelTransport));
|
||||
CancellationSignal.fromTransport(cancelTransport),
|
||||
timestampBegan);
|
||||
|
||||
processGetCredential(request, callback, session);
|
||||
return cancelTransport;
|
||||
@@ -508,6 +512,9 @@ public final class CredentialManagerService
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
finalizeAndEmitInitialPhaseMetric(session);
|
||||
// TODO(b/271135048) - May still be worth emitting in the empty cases above.
|
||||
providerSessions.forEach(ProviderSession::invokeSession);
|
||||
}
|
||||
|
||||
@@ -516,6 +523,7 @@ public final class CredentialManagerService
|
||||
CreateCredentialRequest request,
|
||||
ICreateCredentialCallback callback,
|
||||
String callingPackage) {
|
||||
final long timestampBegan = System.nanoTime();
|
||||
Log.i(TAG, "starting executeCreateCredential with callingPackage: "
|
||||
+ callingPackage);
|
||||
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
|
||||
@@ -538,7 +546,8 @@ public final class CredentialManagerService
|
||||
request,
|
||||
callback,
|
||||
constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
|
||||
CancellationSignal.fromTransport(cancelTransport));
|
||||
CancellationSignal.fromTransport(cancelTransport),
|
||||
timestampBegan);
|
||||
|
||||
processCreateCredential(request, callback, session);
|
||||
return cancelTransport;
|
||||
@@ -566,10 +575,17 @@ public final class CredentialManagerService
|
||||
}
|
||||
}
|
||||
|
||||
finalizeAndEmitInitialPhaseMetric(session);
|
||||
// Iterate over all provider sessions and invoke the request
|
||||
providerSessions.forEach(ProviderSession::invokeSession);
|
||||
}
|
||||
|
||||
private void finalizeAndEmitInitialPhaseMetric(RequestSession session) {
|
||||
var initMetric = session.mInitialPhaseMetric;
|
||||
initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime());
|
||||
MetricUtilities.logApiCalled(initMetric);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabledProviders(
|
||||
List<String> providers, int userId, ISetEnabledProvidersCallback callback) {
|
||||
@@ -654,6 +670,7 @@ public final class CredentialManagerService
|
||||
}
|
||||
MetricUtilities.logApiCalled(ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
|
||||
ApiStatus.SUCCESS, callingUid);
|
||||
// TODO(b/271135048) - Update asap to use the new logging types
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -683,12 +700,15 @@ public final class CredentialManagerService
|
||||
mContext, userId, providerFilter, getEnabledProviders());
|
||||
}
|
||||
|
||||
@SuppressWarnings("GuardedBy") // ErrorProne requires service.mLock which is the same
|
||||
// this.mLock
|
||||
private Set<ServiceInfo> getEnabledProviders() {
|
||||
Set<ServiceInfo> enabledProviders = new HashSet<>();
|
||||
synchronized (mLock) {
|
||||
runForUser(
|
||||
(service) -> {
|
||||
enabledProviders.add(service.getCredentialProviderInfo().getServiceInfo());
|
||||
enabledProviders.add(
|
||||
service.getCredentialProviderInfo().getServiceInfo());
|
||||
});
|
||||
}
|
||||
return enabledProviders;
|
||||
@@ -699,6 +719,7 @@ public final class CredentialManagerService
|
||||
ClearCredentialStateRequest request,
|
||||
IClearCredentialStateCallback callback,
|
||||
String callingPackage) {
|
||||
final long timestampBegan = System.nanoTime();
|
||||
Log.i(TAG, "starting clearCredentialState with callingPackage: " + callingPackage);
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
int callingUid = Binder.getCallingUid();
|
||||
@@ -716,7 +737,8 @@ public final class CredentialManagerService
|
||||
callback,
|
||||
request,
|
||||
constructCallingAppInfo(callingPackage, userId, null),
|
||||
CancellationSignal.fromTransport(cancelTransport));
|
||||
CancellationSignal.fromTransport(cancelTransport),
|
||||
timestampBegan);
|
||||
|
||||
// Initiate all provider sessions
|
||||
// TODO: Determine if provider needs to have clear capability in their manifest
|
||||
@@ -735,6 +757,8 @@ public final class CredentialManagerService
|
||||
}
|
||||
}
|
||||
|
||||
finalizeAndEmitInitialPhaseMetric(session);
|
||||
|
||||
// Iterate over all provider sessions and invoke the request
|
||||
providerSessions.forEach(ProviderSession::invokeSession);
|
||||
return cancelTransport;
|
||||
|
||||
@@ -19,6 +19,7 @@ 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,6 +37,7 @@ import com.android.server.credentials.metrics.ApiStatus;
|
||||
import com.android.server.credentials.metrics.ProviderStatusForMetrics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Central session for a single getCredentials request. This class listens to the
|
||||
@@ -47,9 +49,14 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest,
|
||||
private static final String TAG = "GetRequestSession";
|
||||
public GetRequestSession(Context context, int userId, int callingUid,
|
||||
IGetCredentialCallback callback, GetCredentialRequest request,
|
||||
CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal) {
|
||||
CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal,
|
||||
long startedTimestamp) {
|
||||
super(context, userId, callingUid, request, callback, RequestInfo.TYPE_GET,
|
||||
callingAppInfo, cancellationSignal);
|
||||
callingAppInfo, cancellationSignal, startedTimestamp);
|
||||
int numTypes = (request.getCredentialOptions().stream()
|
||||
.map(CredentialOption::getType).collect(
|
||||
Collectors.toSet())).size(); // Dedupe type strings
|
||||
setupInitialPhaseMetric(ApiName.GET_CREDENTIAL.getMetricCode(), numTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.android.server.credentials.metrics.ApiName;
|
||||
import com.android.server.credentials.metrics.ApiStatus;
|
||||
import com.android.server.credentials.metrics.CandidateProviderMetric;
|
||||
import com.android.server.credentials.metrics.ChosenProviderMetric;
|
||||
import com.android.server.credentials.metrics.InitialPhaseMetric;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -39,7 +40,10 @@ public class MetricUtilities {
|
||||
|
||||
public static final int DEFAULT_INT_32 = -1;
|
||||
public static final int[] DEFAULT_REPEATED_INT_32 = new int[0];
|
||||
|
||||
// Used for single count metric emits, such as singular amounts of various types
|
||||
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;
|
||||
|
||||
/**
|
||||
* This retrieves the uid of any package name, given a context and a component name for the
|
||||
@@ -155,4 +159,18 @@ public class MetricUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the metric emit for the initial phase.
|
||||
*
|
||||
* @param initialPhaseMetric contains all the data for this emit
|
||||
*/
|
||||
protected static void logApiCalled(InitialPhaseMetric initialPhaseMetric) {
|
||||
/*
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.INITIAL_PHASE,
|
||||
.. session_id .. initialPhaseMetric.getSessionId(),
|
||||
...
|
||||
TODO Immediately - Fill in asap now that the split atom is checked in.
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.android.server.credentials.metrics.ApiName;
|
||||
import com.android.server.credentials.metrics.ApiStatus;
|
||||
import com.android.server.credentials.metrics.CandidateProviderMetric;
|
||||
import com.android.server.credentials.metrics.ChosenProviderMetric;
|
||||
import com.android.server.credentials.metrics.InitialPhaseMetric;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -75,7 +76,7 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
|
||||
protected final Map<String, ProviderSession> mProviders = new HashMap<>();
|
||||
protected ChosenProviderMetric mChosenProviderMetric = new ChosenProviderMetric();
|
||||
//TODO improve design to allow grouped metrics per request
|
||||
protected InitialPhaseMetric mInitialPhaseMetric = new InitialPhaseMetric();
|
||||
protected final String mHybridService;
|
||||
|
||||
@NonNull
|
||||
@@ -96,7 +97,7 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
@UserIdInt int userId, int callingUid, @NonNull T clientRequest, U clientCallback,
|
||||
@NonNull String requestType,
|
||||
CallingAppInfo callingAppInfo,
|
||||
CancellationSignal cancellationSignal) {
|
||||
CancellationSignal cancellationSignal, long timestampStarted) {
|
||||
mContext = context;
|
||||
mUserId = userId;
|
||||
mCallingUid = callingUid;
|
||||
@@ -111,6 +112,9 @@ 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);
|
||||
}
|
||||
|
||||
public abstract ProviderSession initiateProviderSession(CredentialProviderInfo providerInfo,
|
||||
@@ -118,6 +122,12 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
|
||||
protected abstract void launchUiWithProviderData(ArrayList<ProviderData> providerDataList);
|
||||
|
||||
// Sets up the initial metric collector for use across all request session impls
|
||||
protected void setupInitialPhaseMetric(int metricCode, int requestClassType) {
|
||||
this.mInitialPhaseMetric.setApiName(metricCode);
|
||||
this.mInitialPhaseMetric.setCountRequestClassType(requestClassType);
|
||||
}
|
||||
|
||||
// UI callbacks
|
||||
|
||||
@Override // from CredentialManagerUiCallbacks
|
||||
|
||||
@@ -25,6 +25,8 @@ package com.android.server.credentials.metrics;
|
||||
*/
|
||||
public class InitialPhaseMetric {
|
||||
private static final String TAG = "PreCandidateMetric";
|
||||
// A sequence id to order united emits, due to split, this will statically always be 1
|
||||
public static final int SEQUENCE_ID = 1;
|
||||
|
||||
// The api being called, default set to unknown
|
||||
private int mApiName = ApiName.UNKNOWN.getMetricCode();
|
||||
@@ -32,8 +34,6 @@ public class InitialPhaseMetric {
|
||||
private int mCallerUid = -1;
|
||||
// The session id to unite multiple atom emits, default to -1
|
||||
private long mSessionId = -1;
|
||||
// A sequence id to order united emits, default to -1
|
||||
private int mSequenceId = -1;
|
||||
private int mCountRequestClassType = -1;
|
||||
|
||||
// Raw timestamps in nanoseconds, *the only* one logged as such (i.e. 64 bits) since it is a
|
||||
@@ -50,7 +50,7 @@ public class InitialPhaseMetric {
|
||||
|
||||
/* ---------- Latencies ---------- */
|
||||
|
||||
/* -- Direct Latencies -- */
|
||||
/* -- Direct Latency Utility -- */
|
||||
|
||||
public int getServiceStartToQueryLatencyMicroseconds() {
|
||||
return (int) ((this.mCredentialServiceStartedTimeNanoseconds
|
||||
@@ -108,15 +108,6 @@ public class InitialPhaseMetric {
|
||||
return mSessionId;
|
||||
}
|
||||
|
||||
/* ------ SequenceId ------ */
|
||||
|
||||
public void setSequenceId(int sequenceId) {
|
||||
mSequenceId = sequenceId;
|
||||
}
|
||||
|
||||
public int getSequenceId() {
|
||||
return mSequenceId;
|
||||
}
|
||||
|
||||
/* ------ Count Request Class Types ------ */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user