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

Commit 6de452ae authored by Tim Yu's avatar Tim Yu Committed by Android (Google) Code Review
Browse files

Merge "Allow better customization of Autofill dialogs."

parents d3234fd8 715aec89
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -39235,9 +39235,13 @@ package android.service.autofill {
    method @NonNull public android.service.autofill.FillResponse.Builder setFlags(int);
    method @NonNull public android.service.autofill.FillResponse.Builder setFooter(@NonNull android.widget.RemoteViews);
    method @NonNull public android.service.autofill.FillResponse.Builder setHeader(@NonNull android.widget.RemoteViews);
    method @NonNull public android.service.autofill.FillResponse.Builder setIconResourceId(@DrawableRes int);
    method @NonNull public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
    method @NonNull public android.service.autofill.FillResponse.Builder setPresentationCancelIds(@Nullable int[]);
    method @NonNull public android.service.autofill.FillResponse.Builder setSaveInfo(@NonNull android.service.autofill.SaveInfo);
    method @NonNull public android.service.autofill.FillResponse.Builder setServiceDisplayNameResourceId(@StringRes int);
    method @NonNull public android.service.autofill.FillResponse.Builder setShowFillDialogIcon(boolean);
    method @NonNull public android.service.autofill.FillResponse.Builder setShowSaveDialogIcon(boolean);
    method @NonNull public android.service.autofill.FillResponse.Builder setUserData(@NonNull android.service.autofill.UserData);
  }
+107 −0
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@ import static android.service.autofill.AutofillServiceHelper.assertValid;
import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
import static android.view.autofill.Helper.sDebug;

import android.annotation.DrawableRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.app.Activity;
@@ -107,6 +109,10 @@ public final class FillResponse implements Parcelable {
    private final @Nullable UserData mUserData;
    private final @Nullable int[] mCancelIds;
    private final boolean mSupportsInlineSuggestions;
    private final @DrawableRes int mIconResourceId;
    private final @StringRes int mServiceDisplayNameResourceId;
    private final boolean mShowFillDialogIcon;
    private final boolean mShowSaveDialogIcon;

    private FillResponse(@NonNull Builder builder) {
        mDatasets = (builder.mDatasets != null) ? new ParceledListSlice<>(builder.mDatasets) : null;
@@ -130,6 +136,10 @@ public final class FillResponse implements Parcelable {
        mUserData = builder.mUserData;
        mCancelIds = builder.mCancelIds;
        mSupportsInlineSuggestions = builder.mSupportsInlineSuggestions;
        mIconResourceId = builder.mIconResourceId;
        mServiceDisplayNameResourceId = builder.mServiceDisplayNameResourceId;
        mShowFillDialogIcon = builder.mShowFillDialogIcon;
        mShowSaveDialogIcon = builder.mShowSaveDialogIcon;
    }

    /** @hide */
@@ -217,6 +227,26 @@ public final class FillResponse implements Parcelable {
        return mUserData;
    }

    /** @hide */
    public @DrawableRes int getIconResourceId() {
        return mIconResourceId;
    }

    /** @hide */
    public @StringRes int getServiceDisplayNameResourceId() {
        return mServiceDisplayNameResourceId;
    }

    /** @hide */
    public boolean getShowFillDialogIcon() {
        return mShowFillDialogIcon;
    }

    /** @hide */
    public boolean getShowSaveDialogIcon() {
        return mShowSaveDialogIcon;
    }

    /** @hide */
    @TestApi
    public int getFlags() {
@@ -278,6 +308,10 @@ public final class FillResponse implements Parcelable {
        private UserData mUserData;
        private int[] mCancelIds;
        private boolean mSupportsInlineSuggestions;
        private int mIconResourceId;
        private int mServiceDisplayNameResourceId;
        private boolean mShowFillDialogIcon = true;
        private boolean mShowSaveDialogIcon = true;

        /**
         * Triggers a custom UI before autofilling the screen with any data set in this
@@ -728,6 +762,70 @@ public final class FillResponse implements Parcelable {
            return this;
        }

        /**
         * Overwrites Save/Fill dialog header icon with a specific one specified by resource id.
         * The image is pulled from the package, so id should be defined in the manifest.
         *
         * @param id {@link android.graphics.drawable.Drawable} resource id of the icon to be used.
         * A value of 0 indicates to use the default header icon.
         *
         * @return this builder
         */
        @NonNull
        public Builder setIconResourceId(@DrawableRes int id) {
            throwIfDestroyed();

            mIconResourceId = id;
            return this;
        }

        /**
         * Overrides the service name in the Save Dialog header with a specific string defined
         * in the service provider's manifest.xml
         *
         * @param id Resoure Id of the custom string defined in the provider's manifest. If set
         * to 0, the default name will be used.
         *
         * @return this builder
         */
        @NonNull
        public Builder setServiceDisplayNameResourceId(@StringRes int id) {
            throwIfDestroyed();

            mServiceDisplayNameResourceId = id;
            return this;
        }

        /**
         * Whether or not to show the Autofill provider icon inside of the Fill Dialog
         *
         * @param show True to show, false to hide. Defaults to true.
         *
         * @return this builder
         */
        @NonNull
        public Builder setShowFillDialogIcon(boolean show) {
            throwIfDestroyed();

            mShowFillDialogIcon = show;
            return this;
        }

        /**
         * Whether or not to show the Autofill provider icon inside of the Save Dialog
         *
         * @param show True to show, false to hide. Defaults to true.
         *
         * @return this builder
         */
        @NonNull
        public Builder setShowSaveDialogIcon(boolean show) {
            throwIfDestroyed();

            mShowSaveDialogIcon = show;
            return this;
        }

        /**
         * Sets a header to be shown as the first element in the list of datasets.
         *
@@ -1024,6 +1122,10 @@ public final class FillResponse implements Parcelable {
        parcel.writeParcelableArray(mIgnoredIds, flags);
        parcel.writeLong(mDisableDuration);
        parcel.writeParcelableArray(mFieldClassificationIds, flags);
        parcel.writeInt(mIconResourceId);
        parcel.writeInt(mServiceDisplayNameResourceId);
        parcel.writeBoolean(mShowFillDialogIcon);
        parcel.writeBoolean(mShowSaveDialogIcon);
        parcel.writeInt(mFlags);
        parcel.writeIntArray(mCancelIds);
        parcel.writeInt(mRequestId);
@@ -1089,6 +1191,11 @@ public final class FillResponse implements Parcelable {
            if (fieldClassifactionIds != null) {
                builder.setFieldClassificationIds(fieldClassifactionIds);
            }

            builder.setIconResourceId(parcel.readInt());
            builder.setServiceDisplayNameResourceId(parcel.readInt());
            builder.setShowFillDialogIcon(parcel.readBoolean());
            builder.setShowSaveDialogIcon(parcel.readBoolean());
            builder.setFlags(parcel.readInt());
            final int[] cancelIds = parcel.createIntArray();
            builder.setPresentationCancelIds(cancelIds);
+63 −7
Original line number Diff line number Diff line
@@ -2651,8 +2651,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                final CharSequence serviceLabel;
                final Drawable serviceIcon;
                synchronized (mLock) {
                    serviceLabel = mService.getServiceLabelLocked();
                    serviceIcon = mService.getServiceIconLocked();
                    serviceIcon = getServiceIcon(response);
                    serviceLabel = getServiceLabel(response);
                }
                if (serviceLabel == null || serviceIcon == null) {
                    wtf(null, "showSaveLocked(): no service label or icon");
@@ -2662,7 +2662,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState

                getUiForShowing().showSaveUi(serviceLabel, serviceIcon,
                        mService.getServicePackageName(), saveInfo, this,
                        mComponentName, this, mPendingSaveUi, isUpdate, mCompatMode);
                        mComponentName, this, mPendingSaveUi, isUpdate, mCompatMode,
                        response.getShowSaveDialogIcon());
                if (client != null) {
                    try {
                        client.setSaveUiState(id, true);
@@ -3600,9 +3601,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                if (sDebug) Log.w(TAG, "Last fill dialog triggered ids are changed.");
                return false;
            }

        }

        final Drawable serviceIcon = getServiceIcon();
        Drawable serviceIcon = null;
        synchronized (mLock) {
            serviceIcon = getServiceIcon(response);
        }

        getUiForShowing().showFillDialog(filledId, response, filterText,
                mService.getServicePackageName(), mComponentName, serviceIcon, this,
@@ -3610,13 +3615,64 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        return true;
    }

    /**
     * Get the custom icon that was passed through FillResponse. If the custom icon wasn't able
     * to be fetched, use the default provider icon instead
     *
     * @return Drawable of the provider icon, if it was able to be fetched. Null otherwise
     */
    @SuppressWarnings("GuardedBy") // ErrorProne says we need to use mService.mLock, but it's
                                   // actually the same object as mLock.
                                   // TODO: Expose mService.mLock or redesign instead.
    private Drawable getServiceIcon() {
        synchronized (mLock) {
            return mService.getServiceIconLocked();
    @GuardedBy("mLock")
    private Drawable getServiceIcon(FillResponse response) {
        Drawable serviceIcon = null;
        // Try to get the custom Icon, if one was passed through FillResponse
        int iconResourceId = response.getIconResourceId();
        if (iconResourceId != 0) {
            serviceIcon = mService.getMaster().getContext().getPackageManager()
                .getDrawable(
                    mService.getServicePackageName(),
                    iconResourceId,
                    null);
        }

        // Custom icon wasn't fetched, use the default package icon instead
        if (serviceIcon == null) {
            serviceIcon = mService.getServiceIconLocked();
        }

        return serviceIcon;
    }

    /**
     * Get the custom label that was passed through FillResponse. If the custom label
     * wasn't able to be fetched, use the default provider icon instead
     *
     * @return Drawable of the provider icon, if it was able to be fetched. Null otherwise
     */
    @SuppressWarnings("GuardedBy") // ErrorProne says we need to use mService.mLock, but it's
                                   // actually the same object as mLock.
                                   // TODO: Expose mService.mLock or redesign instead.
    @GuardedBy("mLock")
    private CharSequence getServiceLabel(FillResponse response) {
        CharSequence serviceLabel = null;
        // Try to get the custom Service name, if one was passed through FillResponse
        int customServiceNameId = response.getServiceDisplayNameResourceId();
        if (customServiceNameId != 0) {
            serviceLabel = mService.getMaster().getContext().getPackageManager()
                .getText(
                    mService.getServicePackageName(),
                    customServiceNameId,
                    null);
        }

        // Custom label wasn't fetched, use the default package name instead
        if (serviceLabel == null) {
            serviceLabel = mService.getServiceLabelLocked();
        }

        return serviceLabel;
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -315,7 +315,7 @@ public final class AutoFillUI {
            @Nullable String servicePackageName, @NonNull SaveInfo info,
            @NonNull ValueFinder valueFinder, @NonNull ComponentName componentName,
            @NonNull AutoFillUiCallback callback, @NonNull PendingUi pendingSaveUi,
            boolean isUpdate, boolean compatMode) {
            boolean isUpdate, boolean compatMode, boolean showServiceIcon) {
        if (sVerbose) {
            Slog.v(TAG, "showSaveUi(update=" + isUpdate + ") for " + componentName.toShortString()
                    + ": " + info);
@@ -379,7 +379,7 @@ public final class AutoFillUI {
                public void startIntentSender(IntentSender intentSender, Intent intent) {
                    callback.startIntentSender(intentSender, intent);
                }
            }, mUiModeMgr.isNightMode(), isUpdate, compatMode);
            }, mUiModeMgr.isNightMode(), isUpdate, compatMode, showServiceIcon);
        });
    }

+3 −1
Original line number Diff line number Diff line
@@ -117,7 +117,9 @@ final class DialogFillUi {
        final LayoutInflater inflater = LayoutInflater.from(mContext);
        final View decor = inflater.inflate(R.layout.autofill_fill_dialog, null);

        if (response.getShowFillDialogIcon()) {
            setServiceIcon(decor, serviceIcon);
        }
        setHeader(decor, response);

        mVisibleDatasetsMaxCount = getVisibleDatasetsMaxCount();
Loading