Loading services/credentials/java/com/android/server/credentials/ClearRequestSession.java +16 −54 Original line number Diff line number Diff line Loading @@ -29,10 +29,6 @@ import android.os.RemoteException; import android.service.credentials.CallingAppInfo; import android.util.Log; import com.android.server.credentials.metrics.ApiName; import com.android.server.credentials.metrics.ApiStatus; import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; /** Loading @@ -40,7 +36,7 @@ import java.util.ArrayList; * responses from providers, and updates the provider(S) state. */ public final class ClearRequestSession extends RequestSession<ClearCredentialStateRequest, IClearCredentialStateCallback> IClearCredentialStateCallback, Void> implements ProviderSession.ProviderInternalCallback<Void> { private static final String TAG = "GetRequestSession"; Loading @@ -50,7 +46,6 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta long startedTimestamp) { super(context, userId, callingUid, request, callback, RequestInfo.TYPE_UNDEFINED, callingAppInfo, cancellationSignal, startedTimestamp); setupInitialPhaseMetric(ApiName.CLEAR_CREDENTIAL.getMetricCode(), MetricUtilities.ZERO); } /** Loading Loading @@ -92,8 +87,10 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta public void onFinalResponseReceived( ComponentName componentName, Void response) { setChosenMetric(componentName); respondToClientWithResponseAndFinish(); mRequestSessionMetric.collectChosenMetricViaCandidateTransfer( mProviders.get(componentName.flattenToString()) .mCandidatePhasePerProviderMetric); respondToClientWithResponseAndFinish(null); } protected void onProviderResponseComplete(ComponentName componentName) { Loading @@ -114,55 +111,20 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta } @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { //Not applicable for clearCredential as response is not picked by the user } private void respondToClientWithResponseAndFinish() { Log.i(TAG, "respondToClientWithResponseAndFinish"); collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS); if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { protected void invokeClientCallbackSuccess(Void response) throws RemoteException { mClientCallback.onSuccess(); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.SUCCESS.getMetricCode()); } catch (RemoteException e) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); Log.i(TAG, "Issue while propagating the response to the client"); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } finishSession(/*propagateCancellation=*/false); } private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) { Log.i(TAG, "respondToClientWithErrorAndFinish"); collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { @Override protected void invokeClientCallbackError(String errorType, String errorMsg) throws RemoteException { mClientCallback.onError(errorType, errorMsg); } catch (RemoteException e) { e.printStackTrace(); } logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); finishSession(/*propagateCancellation=*/false); @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { //Not applicable for clearCredential as response is not picked by the user } private void processResponses() { Loading @@ -170,7 +132,7 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta if (session.isProviderResponseSet()) { // If even one provider responded successfully, send back the response // TODO: Aggregate other exceptions respondToClientWithResponseAndFinish(); respondToClientWithResponseAndFinish(null); return; } } Loading services/credentials/java/com/android/server/credentials/CreateRequestSession.java +21 −80 Original line number Diff line number Diff line Loading @@ -35,8 +35,6 @@ import android.service.credentials.CallingAppInfo; import android.service.credentials.PermissionUtils; import android.util.Log; import com.android.server.credentials.metrics.ApiName; import com.android.server.credentials.metrics.ApiStatus; import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; Loading @@ -47,7 +45,7 @@ import java.util.ArrayList; * provider(s) state maintained in {@link ProviderCreateSession}. */ public final class CreateRequestSession extends RequestSession<CreateCredentialRequest, ICreateCredentialCallback> ICreateCredentialCallback, CreateCredentialResponse> implements ProviderSession.ProviderInternalCallback<CreateCredentialResponse> { private static final String TAG = "CreateRequestSession"; Loading @@ -59,7 +57,6 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR long startedTimestamp) { super(context, userId, callingUid, request, callback, RequestInfo.TYPE_CREATE, callingAppInfo, cancellationSignal, startedTimestamp); setupInitialPhaseMetric(ApiName.CREATE_CREDENTIAL.getMetricCode(), MetricUtilities.UNIT); } /** Loading @@ -85,7 +82,7 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR @Override protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) { mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(System.nanoTime()); mRequestSessionMetric.collectUiCallStartTime(System.nanoTime()); try { mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent( RequestInfo.newCreateRequestInfo( Loading @@ -95,26 +92,39 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS)), providerDataList)); } catch (RemoteException e) { mChosenProviderFinalPhaseMetric.setUiReturned(false); mRequestSessionMetric.collectUiReturnedFinalPhase(/*uiReturned=*/ false); respondToClientWithErrorAndFinish( CreateCredentialException.TYPE_UNKNOWN, "Unable to invoke selector"); } } @Override protected void invokeClientCallbackSuccess(CreateCredentialResponse response) throws RemoteException { mClientCallback.onResponse(response); } @Override protected void invokeClientCallbackError(String errorType, String errorMsg) throws RemoteException { mClientCallback.onError(errorType, errorMsg); } @Override public void onFinalResponseReceived(ComponentName componentName, @Nullable CreateCredentialResponse response) { mChosenProviderFinalPhaseMetric.setUiReturned(true); mChosenProviderFinalPhaseMetric.setUiCallEndTimeNanoseconds(System.nanoTime()); Log.i(TAG, "onFinalCredentialReceived from: " + componentName.flattenToString()); setChosenMetric(componentName); mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime()); mRequestSessionMetric.collectChosenMetricViaCandidateTransfer(mProviders.get( componentName.flattenToString()) .mCandidatePhasePerProviderMetric); if (response != null) { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode()); respondToClientWithResponseAndFinish(response); } else { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_FAILURE.getMetricCode()); respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS, "Invalid response"); Loading Loading @@ -144,75 +154,6 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR "No create options available."); } private void respondToClientWithResponseAndFinish(CreateCredentialResponse response) { Log.i(TAG, "respondToClientWithResponseAndFinish"); // TODO(b/271135048) - Improve Metrics super/sub class setup and emit. collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { // TODO(b/271135048) - Migrate to superclass utilities (post beta1 cleanup) - applies // for all logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onResponse(response); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.SUCCESS.getMetricCode()); } catch (RemoteException e) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); Log.i(TAG, "Issue while responding to client: " + e.getMessage()); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } finishSession(/*propagateCancellation=*/false); } private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) { Log.i(TAG, "respondToClientWithErrorAndFinish"); collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onError(errorType, errorMsg); } catch (RemoteException e) { Log.i(TAG, "Issue while responding to client: " + e.getMessage()); } logFailureOrUserCancel(errorType); finishSession(/*propagateCancellation=*/false); } private void logFailureOrUserCancel(String errorType) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (CreateCredentialException.TYPE_USER_CANCELED.equals(errorType)) { mChosenProviderFinalPhaseMetric.setHasException(false); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.USER_CANCELED.getMetricCode()); } else { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } } @Override public void onProviderStatusChanged(ProviderSession.Status status, ComponentName componentName) { Loading services/credentials/java/com/android/server/credentials/CredentialManagerService.java +6 −4 Original line number Diff line number Diff line Loading @@ -707,9 +707,10 @@ public final class CredentialManagerService private void finalizeAndEmitInitialPhaseMetric(RequestSession session) { try { var initMetric = session.mInitialPhaseMetric; var initMetric = session.mRequestSessionMetric.getInitialPhaseMetric(); initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime()); MetricUtilities.logApiCalled(initMetric, ++session.mSequenceCounter); MetricUtilities.logApiCalledInitialPhase(initMetric, session.mRequestSessionMetric.returnIncrementSequence()); } catch (Exception e) { Log.w(TAG, "Unexpected error during metric logging: " + e); } Loading Loading @@ -788,7 +789,7 @@ public final class CredentialManagerService if (serviceComponentName.equals(componentName)) { if (!s.getServicePackageName().equals(callingPackage)) { // The component name and the package name do not match. MetricUtilities.logApiCalled( MetricUtilities.logApiCalledSimpleV1( ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE, ApiStatus.FAILURE, callingUid); Log.w( Loading @@ -797,7 +798,8 @@ public final class CredentialManagerService + " match package name."); return false; } MetricUtilities.logApiCalled(ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE, MetricUtilities.logApiCalledSimpleV1( ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE, ApiStatus.SUCCESS, callingUid); // TODO(b/271135048) - Update asap to use the new logging types return true; Loading services/credentials/java/com/android/server/credentials/GetRequestSession.java +26 −83 Original line number Diff line number Diff line Loading @@ -27,14 +27,11 @@ import android.credentials.GetCredentialResponse; import android.credentials.IGetCredentialCallback; import android.credentials.ui.ProviderData; import android.credentials.ui.RequestInfo; import android.os.Binder; import android.os.CancellationSignal; import android.os.RemoteException; import android.service.credentials.CallingAppInfo; import android.util.Log; import com.android.server.credentials.metrics.ApiName; import com.android.server.credentials.metrics.ApiStatus; import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; Loading @@ -45,7 +42,7 @@ import java.util.stream.Collectors; * responses from providers, and the UX app, and updates the provider(S) state. */ public class GetRequestSession extends RequestSession<GetCredentialRequest, IGetCredentialCallback> IGetCredentialCallback, GetCredentialResponse> implements ProviderSession.ProviderInternalCallback<GetCredentialResponse> { private static final String TAG = "GetRequestSession"; public GetRequestSession(Context context, int userId, int callingUid, Loading @@ -57,7 +54,7 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest, int numTypes = (request.getCredentialOptions().stream() .map(CredentialOption::getType).collect( Collectors.toSet())).size(); // Dedupe type strings setupInitialPhaseMetric(ApiName.GET_CREDENTIAL.getMetricCode(), numTypes); mRequestSessionMetric.collectGetFlowInitialMetricInfo(numTypes); } /** Loading @@ -83,112 +80,58 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest, @Override protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) { mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(System.nanoTime()); mRequestSessionMetric.collectUiCallStartTime(System.nanoTime()); try { Binder.withCleanCallingIdentity(() -> mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent( RequestInfo.newGetRequestInfo( mRequestId, mClientRequest, mClientAppInfo.getPackageName()), providerDataList))); } catch (RuntimeException e) { mChosenProviderFinalPhaseMetric.setUiReturned(false); providerDataList)); } catch (RemoteException e) { mRequestSessionMetric.collectUiReturnedFinalPhase(/*uiReturned=*/ false); respondToClientWithErrorAndFinish( GetCredentialException.TYPE_UNKNOWN, "Unable to instantiate selector"); } } @Override protected void invokeClientCallbackSuccess(GetCredentialResponse response) throws RemoteException { mClientCallback.onResponse(response); } @Override protected void invokeClientCallbackError(String errorType, String errorMsg) throws RemoteException { mClientCallback.onError(errorType, errorMsg); } @Override public void onFinalResponseReceived(ComponentName componentName, @Nullable GetCredentialResponse response) { mChosenProviderFinalPhaseMetric.setUiReturned(true); mChosenProviderFinalPhaseMetric.setUiCallEndTimeNanoseconds(System.nanoTime()); Log.i(TAG, "onFinalCredentialReceived from: " + componentName.flattenToString()); setChosenMetric(componentName); mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime()); mRequestSessionMetric.collectChosenMetricViaCandidateTransfer( mProviders.get(componentName.flattenToString()) .mCandidatePhasePerProviderMetric); if (response != null) { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode()); respondToClientWithResponseAndFinish(response); } else { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_FAILURE.getMetricCode()); respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL, "Invalid response from provider"); } } //TODO: Try moving the three error & response methods below to RequestSession to be shared // between get & create. //TODO(b/274954697): Further shorten the three below to completely migrate to superclass @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { respondToClientWithErrorAndFinish(errorType, message); } private void respondToClientWithResponseAndFinish(GetCredentialResponse response) { collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onResponse(response); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.SUCCESS.getMetricCode()); } catch (RemoteException e) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); Log.i(TAG, "Issue while responding to client with a response : " + e.getMessage()); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } finishSession(/*propagateCancellation=*/false); } private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onError(errorType, errorMsg); } catch (RemoteException e) { Log.i(TAG, "Issue while responding to client with error : " + e.getMessage()); } logFailureOrUserCancel(errorType); finishSession(/*propagateCancellation=*/false); } private void logFailureOrUserCancel(String errorType) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (GetCredentialException.TYPE_USER_CANCELED.equals(errorType)) { mChosenProviderFinalPhaseMetric.setHasException(false); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.USER_CANCELED.getMetricCode()); } else { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } } @Override public void onUiCancellation(boolean isUserCancellation) { if (isUserCancellation) { Loading services/credentials/java/com/android/server/credentials/MetricUtilities.java +20 −5 Original line number Diff line number Diff line Loading @@ -37,8 +37,10 @@ import java.util.Map; * from {@link com.android.internal.util.FrameworkStatsLog}. */ public class MetricUtilities { private static final boolean LOG_FLAG = true; private static final String TAG = "MetricUtilities"; public static final String USER_CANCELED_SUBSTRING = "TYPE_USER_CANCELED"; public static final int DEFAULT_INT_32 = -1; public static final int[] DEFAULT_REPEATED_INT_32 = new int[0]; Loading Loading @@ -90,10 +92,13 @@ public class MetricUtilities { * @param apiStatus the final status of this particular api call * @param emitSequenceId an emitted sequence id for the current session */ protected static void logApiCalled(ChosenProviderFinalPhaseMetric finalPhaseMetric, public static void logApiCalledFinalPhase(ChosenProviderFinalPhaseMetric finalPhaseMetric, List<CandidateBrowsingPhaseMetric> browsingPhaseMetrics, int apiStatus, int emitSequenceId) { try { if (!LOG_FLAG) { return; } int browsedSize = browsingPhaseMetrics.size(); int[] browsedClickedEntries = new int[browsedSize]; int[] browsedProviderUid = new int[browsedSize]; Loading Loading @@ -151,9 +156,12 @@ 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 */ protected static void logApiCalled(Map<String, ProviderSession> providers, public static void logApiCalledCandidatePhase(Map<String, ProviderSession> providers, int emitSequenceId) { try { if (!LOG_FLAG) { return; } var providerSessions = providers.values(); int providerSize = providerSessions.size(); int sessionId = -1; Loading Loading @@ -225,14 +233,18 @@ 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 * @param callingUid the calling uid */ protected static void logApiCalled(ApiName apiName, ApiStatus apiStatus, public static void logApiCalledSimpleV1(ApiName apiName, ApiStatus apiStatus, int callingUid) { try { if (!LOG_FLAG) { return; } FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED, /* api_name */apiName.getMetricCode(), /* caller_uid */ callingUid, Loading @@ -258,8 +270,12 @@ public class MetricUtilities { * @param initialPhaseMetric contains all the data for this emit * @param sequenceNum the sequence number for this api call session emit */ protected static void logApiCalled(InitialPhaseMetric initialPhaseMetric, int sequenceNum) { public static void logApiCalledInitialPhase(InitialPhaseMetric initialPhaseMetric, int sequenceNum) { try { if (!LOG_FLAG) { return; } FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_INIT_PHASE, /* api_name */ initialPhaseMetric.getApiName(), /* caller_uid */ initialPhaseMetric.getCallerUid(), Loading @@ -275,5 +291,4 @@ public class MetricUtilities { Log.w(TAG, "Unexpected error during metric logging: " + e); } } } Loading
services/credentials/java/com/android/server/credentials/ClearRequestSession.java +16 −54 Original line number Diff line number Diff line Loading @@ -29,10 +29,6 @@ import android.os.RemoteException; import android.service.credentials.CallingAppInfo; import android.util.Log; import com.android.server.credentials.metrics.ApiName; import com.android.server.credentials.metrics.ApiStatus; import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; /** Loading @@ -40,7 +36,7 @@ import java.util.ArrayList; * responses from providers, and updates the provider(S) state. */ public final class ClearRequestSession extends RequestSession<ClearCredentialStateRequest, IClearCredentialStateCallback> IClearCredentialStateCallback, Void> implements ProviderSession.ProviderInternalCallback<Void> { private static final String TAG = "GetRequestSession"; Loading @@ -50,7 +46,6 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta long startedTimestamp) { super(context, userId, callingUid, request, callback, RequestInfo.TYPE_UNDEFINED, callingAppInfo, cancellationSignal, startedTimestamp); setupInitialPhaseMetric(ApiName.CLEAR_CREDENTIAL.getMetricCode(), MetricUtilities.ZERO); } /** Loading Loading @@ -92,8 +87,10 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta public void onFinalResponseReceived( ComponentName componentName, Void response) { setChosenMetric(componentName); respondToClientWithResponseAndFinish(); mRequestSessionMetric.collectChosenMetricViaCandidateTransfer( mProviders.get(componentName.flattenToString()) .mCandidatePhasePerProviderMetric); respondToClientWithResponseAndFinish(null); } protected void onProviderResponseComplete(ComponentName componentName) { Loading @@ -114,55 +111,20 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta } @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { //Not applicable for clearCredential as response is not picked by the user } private void respondToClientWithResponseAndFinish() { Log.i(TAG, "respondToClientWithResponseAndFinish"); collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS); if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { protected void invokeClientCallbackSuccess(Void response) throws RemoteException { mClientCallback.onSuccess(); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.SUCCESS.getMetricCode()); } catch (RemoteException e) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); Log.i(TAG, "Issue while propagating the response to the client"); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } finishSession(/*propagateCancellation=*/false); } private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) { Log.i(TAG, "respondToClientWithErrorAndFinish"); collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { @Override protected void invokeClientCallbackError(String errorType, String errorMsg) throws RemoteException { mClientCallback.onError(errorType, errorMsg); } catch (RemoteException e) { e.printStackTrace(); } logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); finishSession(/*propagateCancellation=*/false); @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { //Not applicable for clearCredential as response is not picked by the user } private void processResponses() { Loading @@ -170,7 +132,7 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta if (session.isProviderResponseSet()) { // If even one provider responded successfully, send back the response // TODO: Aggregate other exceptions respondToClientWithResponseAndFinish(); respondToClientWithResponseAndFinish(null); return; } } Loading
services/credentials/java/com/android/server/credentials/CreateRequestSession.java +21 −80 Original line number Diff line number Diff line Loading @@ -35,8 +35,6 @@ import android.service.credentials.CallingAppInfo; import android.service.credentials.PermissionUtils; import android.util.Log; import com.android.server.credentials.metrics.ApiName; import com.android.server.credentials.metrics.ApiStatus; import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; Loading @@ -47,7 +45,7 @@ import java.util.ArrayList; * provider(s) state maintained in {@link ProviderCreateSession}. */ public final class CreateRequestSession extends RequestSession<CreateCredentialRequest, ICreateCredentialCallback> ICreateCredentialCallback, CreateCredentialResponse> implements ProviderSession.ProviderInternalCallback<CreateCredentialResponse> { private static final String TAG = "CreateRequestSession"; Loading @@ -59,7 +57,6 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR long startedTimestamp) { super(context, userId, callingUid, request, callback, RequestInfo.TYPE_CREATE, callingAppInfo, cancellationSignal, startedTimestamp); setupInitialPhaseMetric(ApiName.CREATE_CREDENTIAL.getMetricCode(), MetricUtilities.UNIT); } /** Loading @@ -85,7 +82,7 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR @Override protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) { mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(System.nanoTime()); mRequestSessionMetric.collectUiCallStartTime(System.nanoTime()); try { mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent( RequestInfo.newCreateRequestInfo( Loading @@ -95,26 +92,39 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS)), providerDataList)); } catch (RemoteException e) { mChosenProviderFinalPhaseMetric.setUiReturned(false); mRequestSessionMetric.collectUiReturnedFinalPhase(/*uiReturned=*/ false); respondToClientWithErrorAndFinish( CreateCredentialException.TYPE_UNKNOWN, "Unable to invoke selector"); } } @Override protected void invokeClientCallbackSuccess(CreateCredentialResponse response) throws RemoteException { mClientCallback.onResponse(response); } @Override protected void invokeClientCallbackError(String errorType, String errorMsg) throws RemoteException { mClientCallback.onError(errorType, errorMsg); } @Override public void onFinalResponseReceived(ComponentName componentName, @Nullable CreateCredentialResponse response) { mChosenProviderFinalPhaseMetric.setUiReturned(true); mChosenProviderFinalPhaseMetric.setUiCallEndTimeNanoseconds(System.nanoTime()); Log.i(TAG, "onFinalCredentialReceived from: " + componentName.flattenToString()); setChosenMetric(componentName); mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime()); mRequestSessionMetric.collectChosenMetricViaCandidateTransfer(mProviders.get( componentName.flattenToString()) .mCandidatePhasePerProviderMetric); if (response != null) { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode()); respondToClientWithResponseAndFinish(response); } else { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_FAILURE.getMetricCode()); respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS, "Invalid response"); Loading Loading @@ -144,75 +154,6 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR "No create options available."); } private void respondToClientWithResponseAndFinish(CreateCredentialResponse response) { Log.i(TAG, "respondToClientWithResponseAndFinish"); // TODO(b/271135048) - Improve Metrics super/sub class setup and emit. collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { // TODO(b/271135048) - Migrate to superclass utilities (post beta1 cleanup) - applies // for all logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onResponse(response); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.SUCCESS.getMetricCode()); } catch (RemoteException e) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); Log.i(TAG, "Issue while responding to client: " + e.getMessage()); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } finishSession(/*propagateCancellation=*/false); } private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) { Log.i(TAG, "respondToClientWithErrorAndFinish"); collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onError(errorType, errorMsg); } catch (RemoteException e) { Log.i(TAG, "Issue while responding to client: " + e.getMessage()); } logFailureOrUserCancel(errorType); finishSession(/*propagateCancellation=*/false); } private void logFailureOrUserCancel(String errorType) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (CreateCredentialException.TYPE_USER_CANCELED.equals(errorType)) { mChosenProviderFinalPhaseMetric.setHasException(false); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.USER_CANCELED.getMetricCode()); } else { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } } @Override public void onProviderStatusChanged(ProviderSession.Status status, ComponentName componentName) { Loading
services/credentials/java/com/android/server/credentials/CredentialManagerService.java +6 −4 Original line number Diff line number Diff line Loading @@ -707,9 +707,10 @@ public final class CredentialManagerService private void finalizeAndEmitInitialPhaseMetric(RequestSession session) { try { var initMetric = session.mInitialPhaseMetric; var initMetric = session.mRequestSessionMetric.getInitialPhaseMetric(); initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime()); MetricUtilities.logApiCalled(initMetric, ++session.mSequenceCounter); MetricUtilities.logApiCalledInitialPhase(initMetric, session.mRequestSessionMetric.returnIncrementSequence()); } catch (Exception e) { Log.w(TAG, "Unexpected error during metric logging: " + e); } Loading Loading @@ -788,7 +789,7 @@ public final class CredentialManagerService if (serviceComponentName.equals(componentName)) { if (!s.getServicePackageName().equals(callingPackage)) { // The component name and the package name do not match. MetricUtilities.logApiCalled( MetricUtilities.logApiCalledSimpleV1( ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE, ApiStatus.FAILURE, callingUid); Log.w( Loading @@ -797,7 +798,8 @@ public final class CredentialManagerService + " match package name."); return false; } MetricUtilities.logApiCalled(ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE, MetricUtilities.logApiCalledSimpleV1( ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE, ApiStatus.SUCCESS, callingUid); // TODO(b/271135048) - Update asap to use the new logging types return true; Loading
services/credentials/java/com/android/server/credentials/GetRequestSession.java +26 −83 Original line number Diff line number Diff line Loading @@ -27,14 +27,11 @@ import android.credentials.GetCredentialResponse; import android.credentials.IGetCredentialCallback; import android.credentials.ui.ProviderData; import android.credentials.ui.RequestInfo; import android.os.Binder; import android.os.CancellationSignal; import android.os.RemoteException; import android.service.credentials.CallingAppInfo; import android.util.Log; import com.android.server.credentials.metrics.ApiName; import com.android.server.credentials.metrics.ApiStatus; import com.android.server.credentials.metrics.ProviderStatusForMetrics; import java.util.ArrayList; Loading @@ -45,7 +42,7 @@ import java.util.stream.Collectors; * responses from providers, and the UX app, and updates the provider(S) state. */ public class GetRequestSession extends RequestSession<GetCredentialRequest, IGetCredentialCallback> IGetCredentialCallback, GetCredentialResponse> implements ProviderSession.ProviderInternalCallback<GetCredentialResponse> { private static final String TAG = "GetRequestSession"; public GetRequestSession(Context context, int userId, int callingUid, Loading @@ -57,7 +54,7 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest, int numTypes = (request.getCredentialOptions().stream() .map(CredentialOption::getType).collect( Collectors.toSet())).size(); // Dedupe type strings setupInitialPhaseMetric(ApiName.GET_CREDENTIAL.getMetricCode(), numTypes); mRequestSessionMetric.collectGetFlowInitialMetricInfo(numTypes); } /** Loading @@ -83,112 +80,58 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest, @Override protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) { mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(System.nanoTime()); mRequestSessionMetric.collectUiCallStartTime(System.nanoTime()); try { Binder.withCleanCallingIdentity(() -> mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent( RequestInfo.newGetRequestInfo( mRequestId, mClientRequest, mClientAppInfo.getPackageName()), providerDataList))); } catch (RuntimeException e) { mChosenProviderFinalPhaseMetric.setUiReturned(false); providerDataList)); } catch (RemoteException e) { mRequestSessionMetric.collectUiReturnedFinalPhase(/*uiReturned=*/ false); respondToClientWithErrorAndFinish( GetCredentialException.TYPE_UNKNOWN, "Unable to instantiate selector"); } } @Override protected void invokeClientCallbackSuccess(GetCredentialResponse response) throws RemoteException { mClientCallback.onResponse(response); } @Override protected void invokeClientCallbackError(String errorType, String errorMsg) throws RemoteException { mClientCallback.onError(errorType, errorMsg); } @Override public void onFinalResponseReceived(ComponentName componentName, @Nullable GetCredentialResponse response) { mChosenProviderFinalPhaseMetric.setUiReturned(true); mChosenProviderFinalPhaseMetric.setUiCallEndTimeNanoseconds(System.nanoTime()); Log.i(TAG, "onFinalCredentialReceived from: " + componentName.flattenToString()); setChosenMetric(componentName); mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime()); mRequestSessionMetric.collectChosenMetricViaCandidateTransfer( mProviders.get(componentName.flattenToString()) .mCandidatePhasePerProviderMetric); if (response != null) { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode()); respondToClientWithResponseAndFinish(response); } else { mChosenProviderFinalPhaseMetric.setChosenProviderStatus( mRequestSessionMetric.collectChosenProviderStatus( ProviderStatusForMetrics.FINAL_FAILURE.getMetricCode()); respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL, "Invalid response from provider"); } } //TODO: Try moving the three error & response methods below to RequestSession to be shared // between get & create. //TODO(b/274954697): Further shorten the three below to completely migrate to superclass @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { respondToClientWithErrorAndFinish(errorType, message); } private void respondToClientWithResponseAndFinish(GetCredentialResponse response) { collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onResponse(response); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.SUCCESS.getMetricCode()); } catch (RemoteException e) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); Log.i(TAG, "Issue while responding to client with a response : " + e.getMessage()); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } finishSession(/*propagateCancellation=*/false); } private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Log.i(TAG, "Request has already been completed. This is strange."); return; } if (isSessionCancelled()) { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode()); finishSession(/*propagateCancellation=*/true); return; } try { mClientCallback.onError(errorType, errorMsg); } catch (RemoteException e) { Log.i(TAG, "Issue while responding to client with error : " + e.getMessage()); } logFailureOrUserCancel(errorType); finishSession(/*propagateCancellation=*/false); } private void logFailureOrUserCancel(String errorType) { collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE); if (GetCredentialException.TYPE_USER_CANCELED.equals(errorType)) { mChosenProviderFinalPhaseMetric.setHasException(false); logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.USER_CANCELED.getMetricCode()); } else { logApiCall(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric, /* apiStatus */ ApiStatus.FAILURE.getMetricCode()); } } @Override public void onUiCancellation(boolean isUserCancellation) { if (isUserCancellation) { Loading
services/credentials/java/com/android/server/credentials/MetricUtilities.java +20 −5 Original line number Diff line number Diff line Loading @@ -37,8 +37,10 @@ import java.util.Map; * from {@link com.android.internal.util.FrameworkStatsLog}. */ public class MetricUtilities { private static final boolean LOG_FLAG = true; private static final String TAG = "MetricUtilities"; public static final String USER_CANCELED_SUBSTRING = "TYPE_USER_CANCELED"; public static final int DEFAULT_INT_32 = -1; public static final int[] DEFAULT_REPEATED_INT_32 = new int[0]; Loading Loading @@ -90,10 +92,13 @@ public class MetricUtilities { * @param apiStatus the final status of this particular api call * @param emitSequenceId an emitted sequence id for the current session */ protected static void logApiCalled(ChosenProviderFinalPhaseMetric finalPhaseMetric, public static void logApiCalledFinalPhase(ChosenProviderFinalPhaseMetric finalPhaseMetric, List<CandidateBrowsingPhaseMetric> browsingPhaseMetrics, int apiStatus, int emitSequenceId) { try { if (!LOG_FLAG) { return; } int browsedSize = browsingPhaseMetrics.size(); int[] browsedClickedEntries = new int[browsedSize]; int[] browsedProviderUid = new int[browsedSize]; Loading Loading @@ -151,9 +156,12 @@ 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 */ protected static void logApiCalled(Map<String, ProviderSession> providers, public static void logApiCalledCandidatePhase(Map<String, ProviderSession> providers, int emitSequenceId) { try { if (!LOG_FLAG) { return; } var providerSessions = providers.values(); int providerSize = providerSessions.size(); int sessionId = -1; Loading Loading @@ -225,14 +233,18 @@ 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 * @param callingUid the calling uid */ protected static void logApiCalled(ApiName apiName, ApiStatus apiStatus, public static void logApiCalledSimpleV1(ApiName apiName, ApiStatus apiStatus, int callingUid) { try { if (!LOG_FLAG) { return; } FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED, /* api_name */apiName.getMetricCode(), /* caller_uid */ callingUid, Loading @@ -258,8 +270,12 @@ public class MetricUtilities { * @param initialPhaseMetric contains all the data for this emit * @param sequenceNum the sequence number for this api call session emit */ protected static void logApiCalled(InitialPhaseMetric initialPhaseMetric, int sequenceNum) { public static void logApiCalledInitialPhase(InitialPhaseMetric initialPhaseMetric, int sequenceNum) { try { if (!LOG_FLAG) { return; } FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_INIT_PHASE, /* api_name */ initialPhaseMetric.getApiName(), /* caller_uid */ initialPhaseMetric.getCallerUid(), Loading @@ -275,5 +291,4 @@ public class MetricUtilities { Log.w(TAG, "Unexpected error during metric logging: " + e); } } }