Merge "Allow better customization of Autofill dialogs."
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,9 @@ final class DialogFillUi {
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final View decor = inflater.inflate(R.layout.autofill_fill_dialog, null);
|
||||
|
||||
setServiceIcon(decor, serviceIcon);
|
||||
if (response.getShowFillDialogIcon()) {
|
||||
setServiceIcon(decor, serviceIcon);
|
||||
}
|
||||
setHeader(decor, response);
|
||||
|
||||
mVisibleDatasetsMaxCount = getVisibleDatasetsMaxCount();
|
||||
|
||||
@@ -177,7 +177,7 @@ final class SaveUi {
|
||||
@Nullable String servicePackageName, @NonNull ComponentName componentName,
|
||||
@NonNull SaveInfo info, @NonNull ValueFinder valueFinder,
|
||||
@NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener,
|
||||
boolean nightMode, boolean isUpdate, boolean compatMode) {
|
||||
boolean nightMode, boolean isUpdate, boolean compatMode, boolean showServiceIcon) {
|
||||
if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
|
||||
mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
|
||||
mPendingUi = pendingUi;
|
||||
@@ -288,7 +288,9 @@ final class SaveUi {
|
||||
}
|
||||
titleView.setText(mTitle);
|
||||
|
||||
setServiceIcon(context, view, serviceIcon);
|
||||
if (showServiceIcon) {
|
||||
setServiceIcon(context, view, serviceIcon);
|
||||
}
|
||||
|
||||
final boolean hasCustomDescription =
|
||||
applyCustomDescription(context, view, valueFinder, info);
|
||||
|
||||
Reference in New Issue
Block a user