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

Commit 1e9e7bce authored by Reema Bajwa's avatar Reema Bajwa Committed by Android (Google) Code Review
Browse files

Merge "Fix more options crash" into main

parents 12e0eee1 cc93a450
Loading
Loading
Loading
Loading
+11 −21
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ package android.credentials;

import android.annotation.Hide;
import android.annotation.NonNull;
import android.app.PendingIntent;
import android.content.Intent;
import android.credentials.selection.GetCredentialProviderData;
import android.os.Parcel;
import android.os.Parcelable;
@@ -39,32 +39,22 @@ public final class GetCandidateCredentialsResponse implements Parcelable {
    @NonNull
    private final List<GetCredentialProviderData> mCandidateProviderDataList;

    private final PendingIntent mPendingIntent;

    /**
     * @hide
     */
    @Hide
    public GetCandidateCredentialsResponse(
            GetCredentialResponse getCredentialResponse
    ) {
        mCandidateProviderDataList = null;
        mPendingIntent = null;
    }
    @NonNull
    private final Intent mIntent;

    /**
     * @hide
     */
    @Hide
    public GetCandidateCredentialsResponse(
            List<GetCredentialProviderData> candidateProviderDataList,
            PendingIntent pendingIntent
            @NonNull List<GetCredentialProviderData> candidateProviderDataList,
            @NonNull Intent intent
    ) {
        Preconditions.checkCollectionNotEmpty(
                candidateProviderDataList,
                /*valueName=*/ "candidateProviderDataList");
        mCandidateProviderDataList = new ArrayList<>(candidateProviderDataList);
        mPendingIntent = pendingIntent;
        mIntent = intent;
    }

    /**
@@ -81,8 +71,9 @@ public final class GetCandidateCredentialsResponse implements Parcelable {
     *
     * @hide
     */
    public PendingIntent getPendingIntent() {
        return mPendingIntent;
    @NonNull
    public Intent getIntent() {
        return mIntent;
    }

    protected GetCandidateCredentialsResponse(Parcel in) {
@@ -91,14 +82,13 @@ public final class GetCandidateCredentialsResponse implements Parcelable {
        mCandidateProviderDataList = candidateProviderDataList;

        AnnotationValidations.validate(NonNull.class, null, mCandidateProviderDataList);

        mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
        mIntent = in.readTypedObject(Intent.CREATOR);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeTypedList(mCandidateProviderDataList);
        dest.writeTypedObject(mPendingIntent, flags);
        dest.writeTypedObject(mIntent, flags);
    }

    @Override
+26 −19
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ class CredentialAutofillService : AutofillService() {
        autofillIdToProvidersMap.forEach { (autofillId, providers) ->
            validFillResponse = processProvidersForAutofillId(
                    filLRequest, autofillId, providers, entryIconMap, fillResponseBuilder,
                    getCredResponse.pendingIntent)
                    getCredResponse.intent)
                    .or(validFillResponse)
        }
        if (!validFillResponse) {
@@ -229,7 +229,7 @@ class CredentialAutofillService : AutofillService() {
            providerDataList: ArrayList<GetCredentialProviderData>,
            entryIconMap: Map<String, Icon>,
            fillResponseBuilder: FillResponse.Builder,
            bottomSheetPendingIntent: PendingIntent?
            bottomSheetIntent: Intent
    ): Boolean {
        val providerList = GetFlowUtils.toProviderList(
            providerDataList,
@@ -267,6 +267,8 @@ class CredentialAutofillService : AutofillService() {
                }
            }
        }
        bottomSheetIntent.putExtra(
                ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, providerDataList)
        providerDisplayInfo.sortedUserNameToCredentialEntryList.forEach usernameLoop@{
            val primaryEntry = it.sortedCredentialEntryList.first()
            val pendingIntent = primaryEntry.pendingIntent
@@ -330,16 +332,16 @@ class CredentialAutofillService : AutofillService() {
            datasetAdded = true
            i++

            if (i == lastDropdownDatasetIndex && bottomSheetPendingIntent != null) {
                addDropdownMoreOptionsPresentation(bottomSheetPendingIntent, autofillId,
            if (i == lastDropdownDatasetIndex) {
                addDropdownMoreOptionsPresentation(bottomSheetIntent, autofillId,
                        fillResponseBuilder)
            }
        }
        val pinnedSpec = getLastInlinePresentationSpec(inlinePresentationSpecs,
                inlinePresentationSpecsCount)
        if (datasetAdded && bottomSheetPendingIntent != null && pinnedSpec != null) {
            addPinnedInlineSuggestion(bottomSheetPendingIntent, pinnedSpec, autofillId,
                    fillResponseBuilder, providerDataList)
        if (datasetAdded && pinnedSpec != null) {
            addPinnedInlineSuggestion(pinnedSpec, autofillId,
                    fillResponseBuilder, bottomSheetIntent)
        }
        return datasetAdded
    }
@@ -370,13 +372,14 @@ class CredentialAutofillService : AutofillService() {
    }

    private fun addDropdownMoreOptionsPresentation(
            bottomSheetPendingIntent: PendingIntent,
            bottomSheetIntent: Intent,
            autofillId: AutofillId,
            fillResponseBuilder: FillResponse.Builder
    ) {
        val presentationBuilder = Presentations.Builder()
                .setMenuPresentation(
                        RemoteViewsFactory.createMoreSignInOptionsPresentation(this))
        val pendingIntent = setUpBottomSheetPendingIntent(bottomSheetIntent)

        fillResponseBuilder.addDataset(
                Dataset.Builder()
@@ -385,7 +388,7 @@ class CredentialAutofillService : AutofillService() {
                                Field.Builder().setPresentations(
                                        presentationBuilder.build())
                                        .build())
                        .setAuthentication(bottomSheetPendingIntent.intentSender)
                        .setAuthentication(pendingIntent.intentSender)
                        .build()
        )
    }
@@ -401,37 +404,41 @@ class CredentialAutofillService : AutofillService() {
    }

    private fun addPinnedInlineSuggestion(
            bottomSheetPendingIntent: PendingIntent,
            spec: InlinePresentationSpec,
            autofillId: AutofillId,
            fillResponseBuilder: FillResponse.Builder,
            providerDataList: ArrayList<GetCredentialProviderData>
            bottomSheetIntent: Intent
    ) {
        val pendingIntent = setUpBottomSheetPendingIntent(bottomSheetIntent)

        val dataSetBuilder = Dataset.Builder()
        val sliceBuilder = InlineSuggestionUi
                .newContentBuilder(bottomSheetPendingIntent)
                .newContentBuilder(pendingIntent)
                .setStartIcon(Icon.createWithResource(this,
                        com.android.credentialmanager.R.drawable.more_horiz_24px))
        val presentationBuilder = Presentations.Builder()
                .setInlinePresentation(InlinePresentation(
                        sliceBuilder.build().slice, spec, /* pinned= */ true))

        val extrasIntent = Intent()
        extrasIntent.putExtra(ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, providerDataList)

        fillResponseBuilder.addDataset(
                dataSetBuilder
                        .setField(
                                autofillId,
                                Field.Builder().setPresentations(
                                        presentationBuilder.build())
                                        .build())
                        .setAuthentication(bottomSheetPendingIntent.intentSender)
                        .setCredentialFillInIntent(extrasIntent)
                                        presentationBuilder.build()
                                ).build()
                        )
                        .setAuthentication(pendingIntent.intentSender)
                        .build()
        )
    }

    private fun setUpBottomSheetPendingIntent(intent: Intent): PendingIntent {
        intent.setAction(java.util.UUID.randomUUID().toString())
        return PendingIntent.getActivity(this, /*requestCode=*/0, intent,
                PendingIntent.FLAG_MUTABLE, /*options=*/null)
    }

    /**
     *  Maps Autofill Id to provider list. For example, passing in a provider info
     *
+7 −3
Original line number Diff line number Diff line
@@ -193,7 +193,6 @@ 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;
@@ -2821,8 +2820,9 @@ 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 GetCredentialException exception = data.getSerializable(
                CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION,
                GetCredentialException.class);

        final Bundle newClientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE);
        if (sDebug) {
@@ -5126,6 +5126,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                toIpcFriendlyResultReceiver(resultReceiver);

        Intent metadataIntent = dataset.getCredentialFillInIntent();
        if (metadataIntent == null) {
            metadataIntent = new Intent();
        }

        metadataIntent.putExtra(
                android.credentials.selection.Constants.EXTRA_FINAL_RESPONSE_RECEIVER,
                ipcFriendlyResultReceiver);
+20 −30
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.server.credentials;
import static android.credentials.selection.Constants.EXTRA_FINAL_RESPONSE_RECEIVER;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -161,26 +160,6 @@ public class CredentialManagerUi {
     */
    public PendingIntent createPendingIntent(
            RequestInfo requestInfo, ArrayList<ProviderData> providerDataList) {
        return createPendingIntent(requestInfo, providerDataList, /*forAutofill=*/ false);
    }

    /**
     * Creates a {@link PendingIntent} to be used to invoke the credential manager selector UI,
     * by the calling app process. This intent is invoked from the Autofill flow, when the user
     * requests to bring up the 'All Options' page of the credential bottom-sheet. When the user
     * clicks on the pinned entry, the intent will bring up the 'All Options' page of the
     * bottom-sheet. The provider data list is processed by the credential autofill service for
     * each autofill id and passed in as an auth extra.
     *
     * @param requestInfo            the information about the request
     */
    public PendingIntent createPendingIntentForAutofill(RequestInfo requestInfo) {
        return createPendingIntent(requestInfo, /*providerDataList=*/ null, /*forAutofill=*/ true);
    }

    private PendingIntent createPendingIntent(
            RequestInfo requestInfo, @Nullable ArrayList<ProviderData> providerDataList,
            boolean forAutofill) {
        List<CredentialProviderInfo> allProviders =
                CredentialProviderInfoFactory.getCredentialProviderServices(
                        mContext,
@@ -196,15 +175,9 @@ public class CredentialManagerUi {
                        disabledProvider.getComponentName().flattenToString())).toList();

        Intent intent;
        if (forAutofill) {
            intent = IntentFactory.createCredentialSelectorIntentForAutofill(
                    mContext, requestInfo, new ArrayList<>(disabledProviderDataList),
                    mResultReceiver);
        } else {
        intent = IntentFactory.createCredentialSelectorIntent(
                mContext, requestInfo, providerDataList,
                new ArrayList<>(disabledProviderDataList), mResultReceiver);
        }
        intent.setAction(UUID.randomUUID().toString());
        //TODO: Create unique pending intent using request code and cancel any pre-existing pending
        // intents
@@ -213,4 +186,21 @@ public class CredentialManagerUi {
                PendingIntent.FLAG_MUTABLE, /*options=*/null,
                UserHandle.of(mUserId));
    }

    /**
     * Creates an {@link Intent} to be used to invoke the credential manager selector UI,
     * by the calling app process. This intent is invoked from the Autofill flow, when the user
     * requests to bring up the 'All Options' page of the credential bottom-sheet. When the user
     * clicks on the pinned entry, the intent will bring up the 'All Options' page of the
     * bottom-sheet. The provider data list is processed by the credential autofill service for
     * each autofill id and passed in as extras in the pending intent set as authentication
     * of the pinned entry.
     *
     * @param requestInfo            the information about the request
     */
    public Intent createIntentForAutofill(RequestInfo requestInfo) {
        return IntentFactory.createCredentialSelectorIntentForAutofill(
                mContext, requestInfo, new ArrayList<>(),
                mResultReceiver);
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.credentials.Constants;
import android.credentials.CredentialProviderInfo;
import android.credentials.GetCandidateCredentialsException;
@@ -114,8 +115,7 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ
            return;
        }

        cancelExistingPendingIntent();
        mPendingIntent = mCredentialManagerUi.createPendingIntentForAutofill(
        Intent intent = mCredentialManagerUi.createIntentForAutofill(
                RequestInfo.newGetRequestInfo(
                        mRequestId, mClientRequest, mClientAppInfo.getPackageName(),
                        PermissionUtils.hasPermission(mContext, mClientAppInfo.getPackageName(),
@@ -129,7 +129,7 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ

        try {
            invokeClientCallbackSuccess(new GetCandidateCredentialsResponse(
                    candidateProviderDataList, mPendingIntent));
                    candidateProviderDataList, intent));
        } catch (RemoteException e) {
            Slog.e(TAG, "Issue while responding to client with error : " + e);
        }