Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd2a3a8d authored by Daniel's avatar Daniel
Browse files

Dedupe credential options

There is inconsistency in how credential providers process credential
options and returns credential responses. Some providers return entries
for each option while some providers return entries for deduped options.
This results in inconsitent output to users.

To solve this, dedupe credential options in CredentialAutofillService,
and track which autofill ids requested which credential option. Then
make a single credential request with deduped options and when it
receives the entries, duplicate them for each autofill id that requested
the credential option.

Test: atest CtsAutoFillServiceTestCases:android.autofillservice.cts.inline.InlineLoginMixedCredentialActivityTest
Bug: 324126795
Change-Id: Ie236676a756a0bbabca37965a72cd65e25b2065a
parent 0f6369d0
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@ import android.annotation.SystemApi;
import android.app.Activity;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.credentials.CredentialOption;
import android.credentials.GetCredentialException;
import android.credentials.GetCredentialException;
import android.credentials.GetCredentialRequest;
import android.credentials.GetCredentialRequest;
import android.credentials.GetCredentialResponse;
import android.credentials.GetCredentialResponse;
@@ -29,6 +30,7 @@ import android.os.PooledStringWriter;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemClock;
import android.service.autofill.FillRequest;
import android.service.autofill.FillRequest;
import android.service.credentials.CredentialProviderService;
import android.text.InputType;
import android.text.InputType;
import android.text.Spanned;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextUtils;
@@ -2258,6 +2260,17 @@ public class AssistStructure implements Parcelable {
                @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
                @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
            mNode.mGetCredentialRequest = request;
            mNode.mGetCredentialRequest = request;
            mNode.mGetCredentialCallback = callback;
            mNode.mGetCredentialCallback = callback;
            for (CredentialOption option : request.getCredentialOptions()) {
                ArrayList<AutofillId> ids = option.getCandidateQueryData()
                        .getParcelableArrayList(
                                CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId.class);
                ids = ids != null ? ids : new ArrayList<>();
                if (!ids.contains(getAutofillId())) {
                    ids.add(getAutofillId());
                }
                option.getCandidateQueryData()
                        .putParcelableArrayList(CredentialProviderService.EXTRA_AUTOFILL_ID, ids);
            }
        }
        }


        @Override
        @Override
+14 −0
Original line number Original line Diff line number Diff line
@@ -85,6 +85,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.TypedArray;
import android.credentials.CredentialManager;
import android.credentials.CredentialManager;
import android.credentials.CredentialOption;
import android.credentials.GetCredentialException;
import android.credentials.GetCredentialException;
import android.credentials.GetCredentialRequest;
import android.credentials.GetCredentialRequest;
import android.credentials.GetCredentialResponse;
import android.credentials.GetCredentialResponse;
@@ -129,6 +130,7 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.Trace;
import android.os.Vibrator;
import android.os.Vibrator;
import android.os.vibrator.Flags;
import android.os.vibrator.Flags;
import android.service.credentials.CredentialProviderService;
import android.sysprop.DisplayProperties;
import android.sysprop.DisplayProperties;
import android.text.InputType;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextUtils;
@@ -7033,6 +7035,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
            @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
        Preconditions.checkNotNull(request, "request must not be null");
        Preconditions.checkNotNull(request, "request must not be null");
        Preconditions.checkNotNull(callback, "request must not be null");
        Preconditions.checkNotNull(callback, "request must not be null");
        for (CredentialOption option : request.getCredentialOptions()) {
            ArrayList<AutofillId> ids = option.getCandidateQueryData()
                    .getParcelableArrayList(
                            CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId.class);
            ids = ids != null ? ids : new ArrayList<>();
            if (!ids.contains(getAutofillId())) {
                ids.add(getAutofillId());
            }
            option.getCandidateQueryData()
                    .putParcelableArrayList(CredentialProviderService.EXTRA_AUTOFILL_ID, ids);
        }
        mViewCredentialHandler = new ViewCredentialHandler(request, callback);
        mViewCredentialHandler = new ViewCredentialHandler(request, callback);
    }
    }
+86 −37
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import android.service.autofill.Field
import android.service.autofill.FillCallback
import android.service.autofill.FillCallback
import android.service.autofill.FillRequest
import android.service.autofill.FillRequest
import android.service.autofill.FillResponse
import android.service.autofill.FillResponse
import android.service.autofill.Flags
import android.service.autofill.InlinePresentation
import android.service.autofill.InlinePresentation
import android.service.autofill.Presentations
import android.service.autofill.Presentations
import android.service.autofill.SaveCallback
import android.service.autofill.SaveCallback
@@ -479,18 +480,28 @@ class CredentialAutofillService : AutofillService() {
        val autofillIdToCredentialEntries:
        val autofillIdToCredentialEntries:
                MutableMap<AutofillId, ArrayList<Entry>> = mutableMapOf()
                MutableMap<AutofillId, ArrayList<Entry>> = mutableMapOf()
        credentialEntryList.forEach entryLoop@{ credentialEntry ->
        credentialEntryList.forEach entryLoop@{ credentialEntry ->
            val autofillId: AutofillId? = credentialEntry
            val intent = credentialEntry.frameworkExtrasIntent
                    .frameworkExtrasIntent
            intent?.getParcelableExtra(
                    ?.getParcelableExtra(
                        CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
                        android.service.credentials.GetCredentialRequest::class.java)
                    ?.credentialOptions
                    ?.forEach { credentialOption ->
                        credentialOption.candidateQueryData.getParcelableArrayList(
                            CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId::class.java)
                                ?.forEach { autofillId ->
                                    intent.putExtra(
                                        CredentialProviderService.EXTRA_AUTOFILL_ID,
                                        CredentialProviderService.EXTRA_AUTOFILL_ID,
                            AutofillId::class.java)
                                        autofillId)
            if (autofillId == null) {
                                    val entry = Entry(
                Log.e(TAG, "AutofillId is missing from credential entry. Credential" +
                                        credentialEntry.key,
                        " Integration might be disabled.")
                                        credentialEntry.subkey,
                return@entryLoop
                                        credentialEntry.slice,
                                        intent)
                                    autofillIdToCredentialEntries
                                            .getOrPut(autofillId) { ArrayList() }
                                            .add(entry)
                                }
                    }
                    }
            autofillIdToCredentialEntries.getOrPut(autofillId) { ArrayList() }
                    .add(credentialEntry)
        }
        }
        return autofillIdToCredentialEntries
        return autofillIdToCredentialEntries
    }
    }
@@ -573,23 +584,31 @@ class CredentialAutofillService : AutofillService() {
            cmRequests: MutableList<CredentialOption>,
            cmRequests: MutableList<CredentialOption>,
            responseClientState: Bundle
            responseClientState: Bundle
    ) {
    ) {
        val traversedViewNodes: MutableSet<AutofillId> = mutableSetOf()
        val credentialOptionsFromHints: MutableMap<String, CredentialOption> = mutableMapOf()
        val windowNodes: List<AssistStructure.WindowNode> =
        val windowNodes: List<AssistStructure.WindowNode> =
                structure.run {
                structure.run {
                    (0 until windowNodeCount).map { getWindowNodeAt(it) }
                    (0 until windowNodeCount).map { getWindowNodeAt(it) }
                }
                }


        windowNodes.forEach { windowNode: AssistStructure.WindowNode ->
        windowNodes.forEach { windowNode: AssistStructure.WindowNode ->
            traverseNodeForRequest(windowNode.rootViewNode, cmRequests, responseClientState)
            traverseNodeForRequest(
                windowNode.rootViewNode, cmRequests, responseClientState, traversedViewNodes,
                credentialOptionsFromHints)
        }
        }
    }
    }


    private fun traverseNodeForRequest(
    private fun traverseNodeForRequest(
            viewNode: AssistStructure.ViewNode,
            viewNode: AssistStructure.ViewNode,
            cmRequests: MutableList<CredentialOption>,
            cmRequests: MutableList<CredentialOption>,
            responseClientState: Bundle
            responseClientState: Bundle,
            traversedViewNodes: MutableSet<AutofillId>,
            credentialOptionsFromHints: MutableMap<String, CredentialOption>
    ) {
    ) {
        viewNode.autofillId?.let {
        viewNode.autofillId?.let {
            cmRequests.addAll(getCredentialOptionsFromViewNode(viewNode, it, responseClientState))
            cmRequests.addAll(getCredentialOptionsFromViewNode(viewNode, it, responseClientState,
                traversedViewNodes, credentialOptionsFromHints))
            traversedViewNodes.add(it)
        }
        }


        val children: List<AssistStructure.ViewNode> =
        val children: List<AssistStructure.ViewNode> =
@@ -598,26 +617,37 @@ class CredentialAutofillService : AutofillService() {
                }
                }


        children.forEach { childNode: AssistStructure.ViewNode ->
        children.forEach { childNode: AssistStructure.ViewNode ->
            traverseNodeForRequest(childNode, cmRequests, responseClientState)
            traverseNodeForRequest(childNode, cmRequests, responseClientState, traversedViewNodes,
                credentialOptionsFromHints)
        }
        }
    }
    }


    private fun getCredentialOptionsFromViewNode(
    private fun getCredentialOptionsFromViewNode(
            viewNode: AssistStructure.ViewNode,
            viewNode: AssistStructure.ViewNode,
            autofillId: AutofillId,
            autofillId: AutofillId,
            responseClientState: Bundle
            responseClientState: Bundle,
            traversedViewNodes: MutableSet<AutofillId>,
            credentialOptionsFromHints: MutableMap<String, CredentialOption>
    ): MutableList<CredentialOption> {
    ): MutableList<CredentialOption> {
        if (viewNode.credentialManagerRequest != null) {
        val credentialOptions: MutableList<CredentialOption> = mutableListOf()
            val options = viewNode.credentialManagerRequest?.getCredentialOptions()
        if (Flags.autofillCredmanDevIntegration() && viewNode.credentialManagerRequest != null) {
            if (options != null) {
            viewNode.credentialManagerRequest
                for (option in options) {
                    ?.getCredentialOptions()
                    option.candidateQueryData.putParcelable(
                    ?.forEach { credentialOption ->
                            CredentialProviderService.EXTRA_AUTOFILL_ID, autofillId
                credentialOption.candidateQueryData
                    )
                        .getParcelableArrayList(
                            CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId::class.java)
                        ?.let { associatedAutofillIds ->
                            // Check whether any of the associated autofill ids have already been
                            // traversed. If so, skip, to dedupe on duplicate credential options.
                            if ((traversedViewNodes intersect associatedAutofillIds.toSet())
                                        .isEmpty()) {
                                credentialOptions.add(credentialOption)
                            }
                            }
                return options
                        }
                        }
            }
            }
        }
        // TODO(b/325502552): clean up cred option logic in autofill hint
        val credentialHints: MutableList<String> = mutableListOf()
        val credentialHints: MutableList<String> = mutableListOf()


        if (viewNode.autofillHints != null) {
        if (viewNode.autofillHints != null) {
@@ -631,10 +661,10 @@ class CredentialAutofillService : AutofillService() {
            }
            }
        }
        }


        val credentialOptions: MutableList<CredentialOption> = mutableListOf()
        for (credentialHint in credentialHints) {
        for (credentialHint in credentialHints) {
            try {
            try {
                convertJsonToCredentialOption(credentialHint, autofillId)
                convertJsonToCredentialOption(
                    credentialHint, autofillId, credentialOptionsFromHints)
                        .let { credentialOptions.addAll(it) }
                        .let { credentialOptions.addAll(it) }
            } catch (e: JSONException) {
            } catch (e: JSONException) {
                Log.i(TAG, "Exception while parsing response: " + e.message)
                Log.i(TAG, "Exception while parsing response: " + e.message)
@@ -643,10 +673,11 @@ class CredentialAutofillService : AutofillService() {
        return credentialOptions
        return credentialOptions
    }
    }


    private fun convertJsonToCredentialOption(jsonString: String, autofillId: AutofillId):
    private fun convertJsonToCredentialOption(
            List<CredentialOption> {
        jsonString: String,
        // TODO(b/302000646) Move this logic to jetpack so that is consistent
        autofillId: AutofillId,
        //  with building the json
        credentialOptionsFromHints: MutableMap<String, CredentialOption>
    ): List<CredentialOption> {
        val credentialOptions: MutableList<CredentialOption> = mutableListOf()
        val credentialOptions: MutableList<CredentialOption> = mutableListOf()


        val json = JSONObject(jsonString)
        val json = JSONObject(jsonString)
@@ -654,16 +685,34 @@ class CredentialAutofillService : AutofillService() {
        val options = jsonGet.getJSONArray(CRED_OPTIONS_KEY)
        val options = jsonGet.getJSONArray(CRED_OPTIONS_KEY)
        for (i in 0 until options.length()) {
        for (i in 0 until options.length()) {
            val option = options.getJSONObject(i)
            val option = options.getJSONObject(i)
            val optionString = option.toString()
            credentialOptionsFromHints[optionString]
                    ?.let { credentialOption ->
                        // if the current credential option was seen before, add the current
                        // viewNode to the credential option, but do not add it to the option list
                        // again. This will result in the same result as deduping based on
                        // traversed viewNode.
                        credentialOption.candidateQueryData.getParcelableArrayList(
                            CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId::class.java)
                                ?.let {
                                    it.add(autofillId)
                                    credentialOption.candidateQueryData.putParcelableArrayList(
                                        CredentialProviderService.EXTRA_AUTOFILL_ID, it)
                                }
            } ?: run {
                val candidateBundle = convertJsonToBundle(option.getJSONObject(CANDIDATE_DATA_KEY))
                val candidateBundle = convertJsonToBundle(option.getJSONObject(CANDIDATE_DATA_KEY))
            candidateBundle.putParcelable(
                candidateBundle.putParcelableArrayList(
                    CredentialProviderService.EXTRA_AUTOFILL_ID,
                    CredentialProviderService.EXTRA_AUTOFILL_ID,
                    autofillId)
                    arrayListOf(autofillId))
            credentialOptions.add(CredentialOption(
                val credentialOption = CredentialOption(
                    option.getString(TYPE_KEY),
                    option.getString(TYPE_KEY),
                    convertJsonToBundle(option.getJSONObject(REQUEST_DATA_KEY)),
                    convertJsonToBundle(option.getJSONObject(REQUEST_DATA_KEY)),
                    candidateBundle,
                    candidateBundle,
                    option.getBoolean(SYS_PROVIDER_REQ_KEY),
                    option.getBoolean(SYS_PROVIDER_REQ_KEY),
            ))
                )
                credentialOptions.add(credentialOption)
                credentialOptionsFromHints[optionString] = credentialOption
            }
        }
        }
        return credentialOptions
        return credentialOptions
    }
    }
+11 −38
Original line number Original line Diff line number Diff line
@@ -30,9 +30,7 @@ import android.credentials.selection.AuthenticationEntry;
import android.credentials.selection.Entry;
import android.credentials.selection.Entry;
import android.credentials.selection.GetCredentialProviderData;
import android.credentials.selection.GetCredentialProviderData;
import android.credentials.selection.ProviderPendingIntentResponse;
import android.credentials.selection.ProviderPendingIntentResponse;
import android.os.Bundle;
import android.os.ICancellationSignal;
import android.os.ICancellationSignal;
import android.service.autofill.Flags;
import android.service.credentials.Action;
import android.service.credentials.Action;
import android.service.credentials.BeginGetCredentialOption;
import android.service.credentials.BeginGetCredentialOption;
import android.service.credentials.BeginGetCredentialRequest;
import android.service.credentials.BeginGetCredentialRequest;
@@ -44,7 +42,6 @@ import android.service.credentials.GetCredentialRequest;
import android.service.credentials.RemoteEntry;
import android.service.credentials.RemoteEntry;
import android.util.Pair;
import android.util.Pair;
import android.util.Slog;
import android.util.Slog;
import android.view.autofill.AutofillId;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashMap;
@@ -77,10 +74,6 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
    @NonNull
    @NonNull
    private final Map<String, CredentialOption> mBeginGetOptionToCredentialOptionMap;
    private final Map<String, CredentialOption> mBeginGetOptionToCredentialOptionMap;


    @NonNull
    private final Map<String, AutofillId> mCredentialEntryKeyToAutofilLIdMap;


    /** The complete request to be used in the second round. */
    /** The complete request to be used in the second round. */
    private final android.credentials.GetCredentialRequest mCompleteRequest;
    private final android.credentials.GetCredentialRequest mCompleteRequest;
    private final CallingAppInfo mCallingAppInfo;
    private final CallingAppInfo mCallingAppInfo;
@@ -249,7 +242,6 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
        mBeginGetOptionToCredentialOptionMap = new HashMap<>(beginGetOptionToCredentialOptionMap);
        mBeginGetOptionToCredentialOptionMap = new HashMap<>(beginGetOptionToCredentialOptionMap);
        mProviderResponseDataHandler = new ProviderResponseDataHandler(
        mProviderResponseDataHandler = new ProviderResponseDataHandler(
                ComponentName.unflattenFromString(hybridService));
                ComponentName.unflattenFromString(hybridService));
        mCredentialEntryKeyToAutofilLIdMap = new HashMap<>();
    }
    }


    /** Called when the provider response has been updated by an external source. */
    /** Called when the provider response has been updated by an external source. */
@@ -303,7 +295,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
                    invokeCallbackOnInternalInvalidState();
                    invokeCallbackOnInternalInvalidState();
                    return;
                    return;
                }
                }
                onCredentialEntrySelected(providerPendingIntentResponse, entryKey);
                onCredentialEntrySelected(providerPendingIntentResponse);
                break;
                break;
            case ACTION_ENTRY_KEY:
            case ACTION_ENTRY_KEY:
                Action actionEntry = mProviderResponseDataHandler.getActionEntry(entryKey);
                Action actionEntry = mProviderResponseDataHandler.getActionEntry(entryKey);
@@ -312,7 +304,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
                    invokeCallbackOnInternalInvalidState();
                    invokeCallbackOnInternalInvalidState();
                    return;
                    return;
                }
                }
                onActionEntrySelected(providerPendingIntentResponse, entryKey);
                onActionEntrySelected(providerPendingIntentResponse);
                break;
                break;
            case AUTHENTICATION_ACTION_ENTRY_KEY:
            case AUTHENTICATION_ACTION_ENTRY_KEY:
                Action authenticationEntry = mProviderResponseDataHandler
                Action authenticationEntry = mProviderResponseDataHandler
@@ -342,7 +334,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
                break;
                break;
            case REMOTE_ENTRY_KEY:
            case REMOTE_ENTRY_KEY:
                if (mProviderResponseDataHandler.getRemoteEntry(entryKey) != null) {
                if (mProviderResponseDataHandler.getRemoteEntry(entryKey) != null) {
                    onRemoteEntrySelected(providerPendingIntentResponse, entryKey);
                    onRemoteEntrySelected(providerPendingIntentResponse);
                } else {
                } else {
                    Slog.i(TAG, "Unexpected remote entry key");
                    Slog.i(TAG, "Unexpected remote entry key");
                    invokeCallbackOnInternalInvalidState();
                    invokeCallbackOnInternalInvalidState();
@@ -381,7 +373,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
        return null;
        return null;
    }
    }


    private Intent setUpFillInIntentWithFinalRequest(@NonNull String id, String entryKey) {
    private Intent setUpFillInIntentWithFinalRequest(@NonNull String id) {
        // TODO: Determine if we should skip this entry if entry id is not set, or is set
        // TODO: Determine if we should skip this entry if entry id is not set, or is set
        // but does not resolve to a valid option. For now, not skipping it because
        // but does not resolve to a valid option. For now, not skipping it because
        // it may be possible that the provider adds their own extras and expects to receive
        // it may be possible that the provider adds their own extras and expects to receive
@@ -392,13 +384,6 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
            Slog.w(TAG, "Id from Credential Entry does not resolve to a valid option");
            Slog.w(TAG, "Id from Credential Entry does not resolve to a valid option");
            return intent;
            return intent;
        }
        }
        AutofillId autofillId = credentialOption
                .getCandidateQueryData()
                .getParcelable(CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId.class);
        if (autofillId != null && Flags.autofillCredmanIntegration()) {
            intent.putExtra(CredentialProviderService.EXTRA_AUTOFILL_ID, autofillId);
            mCredentialEntryKeyToAutofilLIdMap.put(entryKey, autofillId);
        }
        return intent.putExtra(
        return intent.putExtra(
                CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
                CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
                new GetCredentialRequest(
                new GetCredentialRequest(
@@ -414,13 +399,12 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
    }
    }


    private void onRemoteEntrySelected(
    private void onRemoteEntrySelected(
            ProviderPendingIntentResponse providerPendingIntentResponse, String entryKey) {
            ProviderPendingIntentResponse providerPendingIntentResponse) {
        onCredentialEntrySelected(providerPendingIntentResponse, entryKey);
        onCredentialEntrySelected(providerPendingIntentResponse);
    }
    }


    private void onCredentialEntrySelected(
    private void onCredentialEntrySelected(
            ProviderPendingIntentResponse providerPendingIntentResponse,
            ProviderPendingIntentResponse providerPendingIntentResponse) {
            String entryKey) {
        if (providerPendingIntentResponse == null) {
        if (providerPendingIntentResponse == null) {
            invokeCallbackOnInternalInvalidState();
            invokeCallbackOnInternalInvalidState();
            return;
            return;
@@ -437,18 +421,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
        GetCredentialResponse getCredentialResponse = PendingIntentResultHandler
        GetCredentialResponse getCredentialResponse = PendingIntentResultHandler
                .extractGetCredentialResponse(
                .extractGetCredentialResponse(
                        providerPendingIntentResponse.getResultData());
                        providerPendingIntentResponse.getResultData());
        if (getCredentialResponse != null && getCredentialResponse.getCredential() != null) {
        if (getCredentialResponse != null) {
            Bundle credentialData = getCredentialResponse.getCredential().getData();
            AutofillId autofillId = mCredentialEntryKeyToAutofilLIdMap.get(entryKey);
            if (Flags.autofillCredmanIntegration()
                    && entryKey != null && autofillId != null && credentialData != null
            ) {
                Slog.d(TAG, "Adding autofillId to credential response: " + autofillId);
                credentialData.putParcelable(
                        CredentialProviderService.EXTRA_AUTOFILL_ID,
                        mCredentialEntryKeyToAutofilLIdMap.get(entryKey)
                );
            }
            mCallbacks.onFinalResponseReceived(mComponentName,
            mCallbacks.onFinalResponseReceived(mComponentName,
                    getCredentialResponse);
                    getCredentialResponse);
            return;
            return;
@@ -532,9 +505,9 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential


    /** Returns true if either an exception or a response is found. */
    /** Returns true if either an exception or a response is found. */
    private void onActionEntrySelected(ProviderPendingIntentResponse
    private void onActionEntrySelected(ProviderPendingIntentResponse
            providerPendingIntentResponse, String entryKey) {
            providerPendingIntentResponse) {
        Slog.i(TAG, "onActionEntrySelected");
        Slog.i(TAG, "onActionEntrySelected");
        onCredentialEntrySelected(providerPendingIntentResponse, entryKey);
        onCredentialEntrySelected(providerPendingIntentResponse);
    }
    }




@@ -632,7 +605,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
            Entry entry = new Entry(CREDENTIAL_ENTRY_KEY,
            Entry entry = new Entry(CREDENTIAL_ENTRY_KEY,
                    id, credentialEntry.getSlice(),
                    id, credentialEntry.getSlice(),
                    setUpFillInIntentWithFinalRequest(credentialEntry
                    setUpFillInIntentWithFinalRequest(credentialEntry
                            .getBeginGetCredentialOptionId(), id));
                            .getBeginGetCredentialOptionId()));
            mUiCredentialEntries.put(id, new Pair<>(credentialEntry, entry));
            mUiCredentialEntries.put(id, new Pair<>(credentialEntry, entry));
            mCredentialEntryTypes.add(credentialEntry.getType());
            mCredentialEntryTypes.add(credentialEntry.getType());
        }
        }