Loading core/java/android/view/View.java +11 −0 Original line number Diff line number Diff line Loading @@ -9957,6 +9957,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, getCredentialManagerCallback().onResult(response); } /** * @hide */ public void onGetCredentialException(String errorType, String errorMsg) { if (getCredentialManagerCallback() == null) { Log.w(AUTOFILL_LOG_TAG, "onGetCredentialException called but no callback found"); return; } getCredentialManagerCallback().onError(new GetCredentialException(errorType, errorMsg)); } /** * Gets the unique, logical identifier of this view in the activity, for autofill purposes. * core/java/android/view/autofill/AutofillManager.java +60 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.credentials.GetCredentialException; import android.credentials.GetCredentialResponse; import android.graphics.Rect; import android.metrics.LogMaker; Loading Loading @@ -105,6 +106,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.PrintWriter; import java.io.Serializable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; Loading Loading @@ -2400,6 +2402,13 @@ public final class AutofillManager { final Bundle responseData = new Bundle(); responseData.putParcelable(EXTRA_AUTHENTICATION_RESULT, result); Serializable exception = data.getSerializableExtra( CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION, GetCredentialException.class); if (exception != null && Flags.autofillCredmanIntegration()) { responseData.putSerializable( CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION, exception); } final Bundle newClientState = data.getBundleExtra(EXTRA_CLIENT_STATE); if (newClientState != null) { responseData.putBundle(EXTRA_CLIENT_STATE, newClientState); Loading Loading @@ -2926,6 +2935,48 @@ public final class AutofillManager { } } private void onGetCredentialException(int sessionId, AutofillId id, String errorType, String errorMsg) { synchronized (mLock) { if (sessionId != mSessionId) { Log.w(TAG, "onGetCredentialException afm sessionIds don't match"); return; } final AutofillClient client = getClient(); if (client == null) { Log.w(TAG, "onGetCredentialException afm client id null"); return; } ArrayList<AutofillId> failedIds = new ArrayList<>(); final View[] views = client.autofillClientFindViewsByAutofillIdTraversal( Helper.toArray(new ArrayList<>(Collections.singleton(id)))); if (views == null || views.length == 0) { Log.w(TAG, "onGetCredentialException afm client view not found"); return; } final View view = views[0]; if (view == null) { Log.i(TAG, "onGetCredentialException View is null"); // Most likely view has been removed after the initial request was sent to the // the service; this is fine, but we need to update the view status in the // server side so it can be triggered again. Log.d(TAG, "onGetCredentialException(): no View with id " + id); failedIds.add(id); } if (id.isVirtualInt()) { Log.i(TAG, "onGetCredentialException afm client id is virtual"); // TODO(b/326314286): Handle virtual views } else { Log.i(TAG, "onGetCredentialException afm client id is NOT virtual"); view.onGetCredentialException(errorType, errorMsg); } handleFailedIdsLocked(failedIds); } } private void onGetCredentialResponse(int sessionId, AutofillId id, GetCredentialResponse response) { synchronized (mLock) { Loading Loading @@ -4381,6 +4432,15 @@ public final class AutofillManager { } } @Override public void onGetCredentialException(int sessionId, AutofillId id, String errorType, String errorMsg) { final AutofillManager afm = mAfm.get(); if (afm != null) { afm.post(() -> afm.onGetCredentialException(sessionId, id, errorType, errorMsg)); } } @Override public void autofillContent(int sessionId, AutofillId id, ClipData content) { final AutofillManager afm = mAfm.get(); Loading core/java/android/view/autofill/IAutoFillManagerClient.aidl +4 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,9 @@ oneway interface IAutoFillManagerClient { void onGetCredentialResponse(int sessionId, in AutofillId id, in GetCredentialResponse response); void onGetCredentialException(int sessionId, in AutofillId id, in String errorType, in String errorMsg); /** * Autofills the activity with rich content data (e.g. an image) from a dataset. */ Loading services/autofill/java/com/android/server/autofill/Session.java +46 −13 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; import java.io.PrintWriter; import java.io.Serializable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; Loading Loading @@ -2802,9 +2803,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState final int datasetIdx = AutofillManager.getDatasetIdFromAuthenticationId( authenticationId); Dataset dataset = null; // Authenticated a dataset - reset view state regardless if we got a response or a dataset if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) { final Dataset dataset = authenticatedResponse.getDatasets().get(datasetIdx); dataset = authenticatedResponse.getDatasets().get(datasetIdx); if (dataset == null) { Slog.w(TAG, "no dataset with index " + datasetIdx + " on fill response"); mPresentationStatsEventLogger.maybeSetAuthenticationResult( Loading @@ -2819,12 +2821,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mSessionFlags.mExpiredResponse = false; final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT); final Serializable exception = data.getSerializable( CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION); final Bundle newClientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE); if (sDebug) { Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result + ", clientState=" + newClientState + ", authenticationId=" + authenticationId); } if (Flags.autofillCredmanDevIntegration() && exception != null && exception instanceof GetCredentialException) { if (dataset != null && dataset.getFieldIds().size() == 1) { if (sDebug) { Slog.d(TAG, "setAuthenticationResultLocked(): result returns with" + "Credential Manager Exception"); } AutofillId autofillId = dataset.getFieldIds().get(0); sendCredentialManagerResponseToApp(/*response=*/ null, (GetCredentialException) exception, autofillId); } return; } if (result instanceof FillResponse) { if (sDebug) { Slog.d(TAG, "setAuthenticationResultLocked(): received FillResponse from" Loading @@ -2840,13 +2858,21 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (Flags.autofillCredmanDevIntegration()) { GetCredentialResponse response = (GetCredentialResponse) result; if (dataset != null && dataset.getFieldIds().size() == 1) { AutofillId autofillId = dataset.getFieldIds().get(0); if (sDebug) { Slog.d(TAG, "Received GetCredentialResponse from authentication flow," + "for autofillId: " + autofillId); } sendCredentialManagerResponseToApp(response, /*exception=*/ null, response.getAutofillId()); /*exception=*/ null, autofillId); } } else if (Flags.autofillCredmanIntegration()) { Dataset dataset = getDatasetFromCredentialResponse( Dataset datasetFromCredentialResponse = getDatasetFromCredentialResponse( (GetCredentialResponse) result); if (dataset != null) { autoFill(requestId, datasetIdx, dataset, false, UI_TYPE_UNKNOWN); if (datasetFromCredentialResponse != null) { autoFill(requestId, datasetIdx, datasetFromCredentialResponse, false, UI_TYPE_UNKNOWN); } } } else if (result instanceof Dataset) { Loading @@ -2863,12 +2889,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (sDebug) Slog.d(TAG, "Updating client state from auth dataset"); mClientState = newClientState; } Dataset dataset = getEffectiveDatasetForAuthentication((Dataset) result); Dataset datasetFromResult = getEffectiveDatasetForAuthentication((Dataset) result); final Dataset oldDataset = authenticatedResponse.getDatasets().get(datasetIdx); if (!isAuthResultDatasetEphemeral(oldDataset, data)) { authenticatedResponse.getDatasets().set(datasetIdx, dataset); authenticatedResponse.getDatasets().set(datasetIdx, datasetFromResult); } autoFill(requestId, datasetIdx, dataset, false, UI_TYPE_UNKNOWN); autoFill(requestId, datasetIdx, datasetFromResult, false, UI_TYPE_UNKNOWN); } else { Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id " + authenticationId); Loading Loading @@ -5052,12 +5078,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } private void addCredentialManagerCallbackForDataset(Dataset dataset, int requestId) { AutofillId autofillId = null; if (dataset != null && dataset.getFieldIds().size() == 1) { autofillId = dataset.getFieldIds().get(0); } final AutofillId finalAutofillId = autofillId; final ResultReceiver resultReceiver = new ResultReceiver(mHandler) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { if (resultCode == SUCCESS_CREDMAN_SELECTOR) { Slog.d(TAG, "onReceiveResult from Credential Manager bottom sheet"); boolean isCredmanCallbackInvoked = false; GetCredentialResponse getCredentialResponse = resultData.getParcelable( CredentialProviderService.EXTRA_GET_CREDENTIAL_RESPONSE, Loading @@ -5065,7 +5095,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (Flags.autofillCredmanDevIntegration()) { sendCredentialManagerResponseToApp(getCredentialResponse, /*exception=*/ null, getCredentialResponse.getAutofillId()); /*exception=*/ null, finalAutofillId); } else { Dataset datasetFromCredential = getDatasetFromCredentialResponse( getCredentialResponse); Loading @@ -5082,7 +5112,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.w(TAG, "Credman bottom sheet from pinned " + "entry failed with: + " + exception[0] + " , " + exception[1]); // TODO(b/326313420): Propagate exception sendCredentialManagerResponseToApp(/*response=*/ null, new GetCredentialException(exception[0], exception[1]), finalAutofillId); } } else { Slog.d(TAG, "Unknown resultCode from credential " Loading Loading @@ -6380,7 +6412,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } } if (exception != null) { // TODO(b/326313420): Add Exception support mClient.onGetCredentialException(id, viewId, exception.getType(), exception.getMessage()); } else if (response != null) { mClient.onGetCredentialResponse(id, viewId, response); } else { Loading services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java +12 −4 Original line number Diff line number Diff line Loading @@ -150,7 +150,8 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { respondToClientWithErrorAndFinish(errorType, message); Slog.d(TAG, "onFinalErrorReceived"); respondToFinalReceiverWithFailureAndFinish(this.mFinalResponseReceiver, errorType, message); } @Override Loading @@ -163,6 +164,13 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ message = "The UI was interrupted - please try again."; } mRequestSessionMetric.collectFrameworkException(exception); respondToFinalReceiverWithFailureAndFinish(finalResponseReceiver, exception, message); } private void respondToFinalReceiverWithFailureAndFinish( ResultReceiver finalResponseReceiver, String exception, String message ) { if (finalResponseReceiver != null) { Bundle resultData = new Bundle(); resultData.putStringArray( Loading @@ -170,16 +178,16 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ new String[] {exception, message}); finalResponseReceiver.send(Constants.FAILURE_CREDMAN_SELECTOR, resultData); } else { respondToClientWithErrorAndFinish(exception, message); Slog.w(TAG, "onUiCancellation called but finalResponseReceiver not found"); } finishSession(/*propagateCancellation=*/false); } @Override public void onUiSelectorInvocationFailure() { String exception = GetCandidateCredentialsException.TYPE_NO_CREDENTIAL; mRequestSessionMetric.collectFrameworkException(exception); respondToClientWithErrorAndFinish(exception, "No credentials available."); // TODO(): Propagate through final receiver } @Override Loading Loading
core/java/android/view/View.java +11 −0 Original line number Diff line number Diff line Loading @@ -9957,6 +9957,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, getCredentialManagerCallback().onResult(response); } /** * @hide */ public void onGetCredentialException(String errorType, String errorMsg) { if (getCredentialManagerCallback() == null) { Log.w(AUTOFILL_LOG_TAG, "onGetCredentialException called but no callback found"); return; } getCredentialManagerCallback().onError(new GetCredentialException(errorType, errorMsg)); } /** * Gets the unique, logical identifier of this view in the activity, for autofill purposes. *
core/java/android/view/autofill/AutofillManager.java +60 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.credentials.GetCredentialException; import android.credentials.GetCredentialResponse; import android.graphics.Rect; import android.metrics.LogMaker; Loading Loading @@ -105,6 +106,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.PrintWriter; import java.io.Serializable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; Loading Loading @@ -2400,6 +2402,13 @@ public final class AutofillManager { final Bundle responseData = new Bundle(); responseData.putParcelable(EXTRA_AUTHENTICATION_RESULT, result); Serializable exception = data.getSerializableExtra( CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION, GetCredentialException.class); if (exception != null && Flags.autofillCredmanIntegration()) { responseData.putSerializable( CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION, exception); } final Bundle newClientState = data.getBundleExtra(EXTRA_CLIENT_STATE); if (newClientState != null) { responseData.putBundle(EXTRA_CLIENT_STATE, newClientState); Loading Loading @@ -2926,6 +2935,48 @@ public final class AutofillManager { } } private void onGetCredentialException(int sessionId, AutofillId id, String errorType, String errorMsg) { synchronized (mLock) { if (sessionId != mSessionId) { Log.w(TAG, "onGetCredentialException afm sessionIds don't match"); return; } final AutofillClient client = getClient(); if (client == null) { Log.w(TAG, "onGetCredentialException afm client id null"); return; } ArrayList<AutofillId> failedIds = new ArrayList<>(); final View[] views = client.autofillClientFindViewsByAutofillIdTraversal( Helper.toArray(new ArrayList<>(Collections.singleton(id)))); if (views == null || views.length == 0) { Log.w(TAG, "onGetCredentialException afm client view not found"); return; } final View view = views[0]; if (view == null) { Log.i(TAG, "onGetCredentialException View is null"); // Most likely view has been removed after the initial request was sent to the // the service; this is fine, but we need to update the view status in the // server side so it can be triggered again. Log.d(TAG, "onGetCredentialException(): no View with id " + id); failedIds.add(id); } if (id.isVirtualInt()) { Log.i(TAG, "onGetCredentialException afm client id is virtual"); // TODO(b/326314286): Handle virtual views } else { Log.i(TAG, "onGetCredentialException afm client id is NOT virtual"); view.onGetCredentialException(errorType, errorMsg); } handleFailedIdsLocked(failedIds); } } private void onGetCredentialResponse(int sessionId, AutofillId id, GetCredentialResponse response) { synchronized (mLock) { Loading Loading @@ -4381,6 +4432,15 @@ public final class AutofillManager { } } @Override public void onGetCredentialException(int sessionId, AutofillId id, String errorType, String errorMsg) { final AutofillManager afm = mAfm.get(); if (afm != null) { afm.post(() -> afm.onGetCredentialException(sessionId, id, errorType, errorMsg)); } } @Override public void autofillContent(int sessionId, AutofillId id, ClipData content) { final AutofillManager afm = mAfm.get(); Loading
core/java/android/view/autofill/IAutoFillManagerClient.aidl +4 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,9 @@ oneway interface IAutoFillManagerClient { void onGetCredentialResponse(int sessionId, in AutofillId id, in GetCredentialResponse response); void onGetCredentialException(int sessionId, in AutofillId id, in String errorType, in String errorMsg); /** * Autofills the activity with rich content data (e.g. an image) from a dataset. */ Loading
services/autofill/java/com/android/server/autofill/Session.java +46 −13 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; import java.io.PrintWriter; import java.io.Serializable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; Loading Loading @@ -2802,9 +2803,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState final int datasetIdx = AutofillManager.getDatasetIdFromAuthenticationId( authenticationId); Dataset dataset = null; // Authenticated a dataset - reset view state regardless if we got a response or a dataset if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) { final Dataset dataset = authenticatedResponse.getDatasets().get(datasetIdx); dataset = authenticatedResponse.getDatasets().get(datasetIdx); if (dataset == null) { Slog.w(TAG, "no dataset with index " + datasetIdx + " on fill response"); mPresentationStatsEventLogger.maybeSetAuthenticationResult( Loading @@ -2819,12 +2821,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mSessionFlags.mExpiredResponse = false; final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT); final Serializable exception = data.getSerializable( CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION); final Bundle newClientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE); if (sDebug) { Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result + ", clientState=" + newClientState + ", authenticationId=" + authenticationId); } if (Flags.autofillCredmanDevIntegration() && exception != null && exception instanceof GetCredentialException) { if (dataset != null && dataset.getFieldIds().size() == 1) { if (sDebug) { Slog.d(TAG, "setAuthenticationResultLocked(): result returns with" + "Credential Manager Exception"); } AutofillId autofillId = dataset.getFieldIds().get(0); sendCredentialManagerResponseToApp(/*response=*/ null, (GetCredentialException) exception, autofillId); } return; } if (result instanceof FillResponse) { if (sDebug) { Slog.d(TAG, "setAuthenticationResultLocked(): received FillResponse from" Loading @@ -2840,13 +2858,21 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (Flags.autofillCredmanDevIntegration()) { GetCredentialResponse response = (GetCredentialResponse) result; if (dataset != null && dataset.getFieldIds().size() == 1) { AutofillId autofillId = dataset.getFieldIds().get(0); if (sDebug) { Slog.d(TAG, "Received GetCredentialResponse from authentication flow," + "for autofillId: " + autofillId); } sendCredentialManagerResponseToApp(response, /*exception=*/ null, response.getAutofillId()); /*exception=*/ null, autofillId); } } else if (Flags.autofillCredmanIntegration()) { Dataset dataset = getDatasetFromCredentialResponse( Dataset datasetFromCredentialResponse = getDatasetFromCredentialResponse( (GetCredentialResponse) result); if (dataset != null) { autoFill(requestId, datasetIdx, dataset, false, UI_TYPE_UNKNOWN); if (datasetFromCredentialResponse != null) { autoFill(requestId, datasetIdx, datasetFromCredentialResponse, false, UI_TYPE_UNKNOWN); } } } else if (result instanceof Dataset) { Loading @@ -2863,12 +2889,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (sDebug) Slog.d(TAG, "Updating client state from auth dataset"); mClientState = newClientState; } Dataset dataset = getEffectiveDatasetForAuthentication((Dataset) result); Dataset datasetFromResult = getEffectiveDatasetForAuthentication((Dataset) result); final Dataset oldDataset = authenticatedResponse.getDatasets().get(datasetIdx); if (!isAuthResultDatasetEphemeral(oldDataset, data)) { authenticatedResponse.getDatasets().set(datasetIdx, dataset); authenticatedResponse.getDatasets().set(datasetIdx, datasetFromResult); } autoFill(requestId, datasetIdx, dataset, false, UI_TYPE_UNKNOWN); autoFill(requestId, datasetIdx, datasetFromResult, false, UI_TYPE_UNKNOWN); } else { Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id " + authenticationId); Loading Loading @@ -5052,12 +5078,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } private void addCredentialManagerCallbackForDataset(Dataset dataset, int requestId) { AutofillId autofillId = null; if (dataset != null && dataset.getFieldIds().size() == 1) { autofillId = dataset.getFieldIds().get(0); } final AutofillId finalAutofillId = autofillId; final ResultReceiver resultReceiver = new ResultReceiver(mHandler) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { if (resultCode == SUCCESS_CREDMAN_SELECTOR) { Slog.d(TAG, "onReceiveResult from Credential Manager bottom sheet"); boolean isCredmanCallbackInvoked = false; GetCredentialResponse getCredentialResponse = resultData.getParcelable( CredentialProviderService.EXTRA_GET_CREDENTIAL_RESPONSE, Loading @@ -5065,7 +5095,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (Flags.autofillCredmanDevIntegration()) { sendCredentialManagerResponseToApp(getCredentialResponse, /*exception=*/ null, getCredentialResponse.getAutofillId()); /*exception=*/ null, finalAutofillId); } else { Dataset datasetFromCredential = getDatasetFromCredentialResponse( getCredentialResponse); Loading @@ -5082,7 +5112,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.w(TAG, "Credman bottom sheet from pinned " + "entry failed with: + " + exception[0] + " , " + exception[1]); // TODO(b/326313420): Propagate exception sendCredentialManagerResponseToApp(/*response=*/ null, new GetCredentialException(exception[0], exception[1]), finalAutofillId); } } else { Slog.d(TAG, "Unknown resultCode from credential " Loading Loading @@ -6380,7 +6412,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } } if (exception != null) { // TODO(b/326313420): Add Exception support mClient.onGetCredentialException(id, viewId, exception.getType(), exception.getMessage()); } else if (response != null) { mClient.onGetCredentialResponse(id, viewId, response); } else { Loading
services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java +12 −4 Original line number Diff line number Diff line Loading @@ -150,7 +150,8 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ @Override public void onFinalErrorReceived(ComponentName componentName, String errorType, String message) { respondToClientWithErrorAndFinish(errorType, message); Slog.d(TAG, "onFinalErrorReceived"); respondToFinalReceiverWithFailureAndFinish(this.mFinalResponseReceiver, errorType, message); } @Override Loading @@ -163,6 +164,13 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ message = "The UI was interrupted - please try again."; } mRequestSessionMetric.collectFrameworkException(exception); respondToFinalReceiverWithFailureAndFinish(finalResponseReceiver, exception, message); } private void respondToFinalReceiverWithFailureAndFinish( ResultReceiver finalResponseReceiver, String exception, String message ) { if (finalResponseReceiver != null) { Bundle resultData = new Bundle(); resultData.putStringArray( Loading @@ -170,16 +178,16 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ new String[] {exception, message}); finalResponseReceiver.send(Constants.FAILURE_CREDMAN_SELECTOR, resultData); } else { respondToClientWithErrorAndFinish(exception, message); Slog.w(TAG, "onUiCancellation called but finalResponseReceiver not found"); } finishSession(/*propagateCancellation=*/false); } @Override public void onUiSelectorInvocationFailure() { String exception = GetCandidateCredentialsException.TYPE_NO_CREDENTIAL; mRequestSessionMetric.collectFrameworkException(exception); respondToClientWithErrorAndFinish(exception, "No credentials available."); // TODO(): Propagate through final receiver } @Override Loading