Loading api/test-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -619,10 +619,13 @@ package android.content { method public int describeContents(); method public static android.content.AutofillOptions forWhitelistingItself(); method public boolean isAugmentedAutofillEnabled(@NonNull android.content.Context); method public boolean isAutofillDisabledLocked(@NonNull android.content.ComponentName); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.content.AutofillOptions> CREATOR; field public long appDisabledExpiration; field public boolean augmentedAutofillEnabled; field public final boolean compatModeEnabled; field @Nullable public android.util.ArrayMap<java.lang.String,java.lang.Long> disabledActivities; field public final int loggingLevel; field @Nullable public android.util.ArraySet<android.content.ComponentName> whitelistedActivitiesForAugmentedAutofill; } Loading core/java/android/content/AutofillOptions.java +60 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.annotation.TestApi; import android.app.ActivityThread; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.view.autofill.AutofillManager; Loading Loading @@ -62,6 +64,18 @@ public final class AutofillOptions implements Parcelable { @Nullable public ArraySet<ComponentName> whitelistedActivitiesForAugmentedAutofill; /** * The package disable expiration by autofill service. */ public long appDisabledExpiration; /** * The disabled Activities of the package. key is component name string, value is when they * will be enabled. */ @Nullable public ArrayMap<String, Long> disabledActivities; public AutofillOptions(int loggingLevel, boolean compatModeEnabled) { this.loggingLevel = loggingLevel; this.compatModeEnabled = compatModeEnabled; Loading @@ -81,6 +95,27 @@ public final class AutofillOptions implements Parcelable { || whitelistedActivitiesForAugmentedAutofill.contains(component); } /** * Returns if autofill is disabled by service to the given activity. */ public boolean isAutofillDisabledLocked(@NonNull ComponentName componentName) { final long elapsedTime = SystemClock.elapsedRealtime(); final String component = componentName.flattenToString(); // Check app first. if (appDisabledExpiration >= elapsedTime) return true; // Then check activities. if (disabledActivities != null) { final Long expiration = disabledActivities.get(component); if (expiration != null) { if (expiration >= elapsedTime) return true; disabledActivities.remove(component); } } appDisabledExpiration = 0; return false; } /** * @hide */ Loading Loading @@ -110,7 +145,8 @@ public final class AutofillOptions implements Parcelable { @Override public String toString() { return "AutofillOptions [loggingLevel=" + loggingLevel + ", compatMode=" + compatModeEnabled + ", augmentedAutofillEnabled=" + augmentedAutofillEnabled + "]"; + ", augmentedAutofillEnabled=" + augmentedAutofillEnabled + ", appDisabledExpiration=" + appDisabledExpiration + "]"; } /** @hide */ Loading @@ -122,6 +158,11 @@ public final class AutofillOptions implements Parcelable { pw.print(", whitelistedActivitiesForAugmentedAutofill="); pw.print(whitelistedActivitiesForAugmentedAutofill); } pw.print(", appDisabledExpiration="); pw.print(appDisabledExpiration); if (disabledActivities != null) { pw.print(", disabledActivities="); pw.print(disabledActivities); } } @Override Loading @@ -135,6 +176,16 @@ public final class AutofillOptions implements Parcelable { parcel.writeBoolean(compatModeEnabled); parcel.writeBoolean(augmentedAutofillEnabled); parcel.writeArraySet(whitelistedActivitiesForAugmentedAutofill); parcel.writeLong(appDisabledExpiration); final int size = disabledActivities != null ? disabledActivities.size() : 0; parcel.writeInt(size); if (size > 0) { for (int i = 0; i < size; i++) { final String key = disabledActivities.keyAt(i); parcel.writeString(key); parcel.writeLong(disabledActivities.get(key)); } } } public static final @android.annotation.NonNull Parcelable.Creator<AutofillOptions> CREATOR = Loading @@ -148,6 +199,14 @@ public final class AutofillOptions implements Parcelable { options.augmentedAutofillEnabled = parcel.readBoolean(); options.whitelistedActivitiesForAugmentedAutofill = (ArraySet<ComponentName>) parcel.readArraySet(null); options.appDisabledExpiration = parcel.readLong(); final int size = parcel.readInt(); if (size > 0) { options.disabledActivities = new ArrayMap<>(); for (int i = 0; i < size; i++) { options.disabledActivities.put(parcel.readString(), parcel.readLong()); } } return options; } Loading core/java/android/view/autofill/AutofillManager.java +62 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.service.autofill.AutofillService; import android.service.autofill.FillEventHistory; import android.service.autofill.UserData; Loading Loading @@ -1737,6 +1738,26 @@ public final class AutofillManager { final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); final ComponentName componentName = client.autofillClientGetComponentName(); if (!mEnabledForAugmentedAutofillOnly && mOptions != null && mOptions.isAutofillDisabledLocked(componentName)) { if (mOptions.isAugmentedAutofillEnabled(mContext)) { if (sDebug) { Log.d(TAG, "startSession(" + componentName + "): disabled by service but " + "whitelisted for augmented autofill"); flags |= FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY; } } else { if (sDebug) { Log.d(TAG, "startSession(" + componentName + "): ignored because " + "disabled by service and not whitelisted for augmented autofill"); } setSessionFinished(AutofillManager.STATE_DISABLED_BY_SERVICE, null); client.autofillClientResetableStateAvailable(); return; } } mService.startSession(client.autofillClientGetActivityToken(), mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(), mCallback != null, flags, componentName, Loading Loading @@ -2067,6 +2088,7 @@ public final class AutofillManager { mServiceClientCleaner.clean(); mServiceClientCleaner = null; } notifyReenableAutofill(); } } sDebug = (flags & SET_STATE_FLAG_DEBUG) != 0; Loading Loading @@ -2403,6 +2425,37 @@ public final class AutofillManager { } } private void notifyDisableAutofill(long disableDuration, ComponentName componentName) { synchronized (mLock) { if (mOptions == null) { return; } long expiration = SystemClock.elapsedRealtime() + disableDuration; // Protect it against overflow if (expiration < 0) { expiration = Long.MAX_VALUE; } if (componentName != null) { if (mOptions.disabledActivities == null) { mOptions.disabledActivities = new ArrayMap<>(); } mOptions.disabledActivities.put(componentName.flattenToString(), expiration); } else { mOptions.appDisabledExpiration = expiration; } } } void notifyReenableAutofill() { synchronized (mLock) { if (mOptions == null) { return; } mOptions.appDisabledExpiration = 0; mOptions.disabledActivities = null; } } private void notifyNoFillUi(int sessionId, AutofillId id, int sessionFinishedState) { if (sVerbose) { Log.v(TAG, "notifyNoFillUi(): sessionId=" + sessionId + ", autofillId=" + id Loading Loading @@ -3180,6 +3233,15 @@ public final class AutofillManager { } } @Override public void notifyDisableAutofill(long disableDuration, ComponentName componentName) throws RemoteException { final AutofillManager afm = mAfm.get(); if (afm != null) { afm.post(() -> afm.notifyDisableAutofill(disableDuration, componentName)); } } @Override public void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent fullScreen) { final AutofillManager afm = mAfm.get(); Loading core/java/android/view/autofill/IAutoFillManagerClient.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view.autofill; import java.util.List; import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; import android.graphics.Rect; Loading Loading @@ -111,4 +112,8 @@ oneway interface IAutoFillManagerClient { */ void getAugmentedAutofillClient(in IResultReceiver result); /** * Notifies disables autofill for the app or activity. */ void notifyDisableAutofill(long disableDuration, in ComponentName componentName); } services/autofill/java/com/android/server/autofill/AutofillManagerService.java +14 −0 Original line number Diff line number Diff line Loading @@ -807,6 +807,7 @@ public final class AutofillManagerService packageName, versionCode, userId); final AutofillOptions options = new AutofillOptions(loggingLevel, compatModeEnabled); mAugmentedAutofillState.injectAugmentedAutofillInfo(options, userId, packageName); injectDisableAppInfo(options, userId, packageName); return options; } Loading @@ -820,6 +821,19 @@ public final class AutofillManagerService } return false; } private void injectDisableAppInfo(@NonNull AutofillOptions options, int userId, String packageName) { synchronized (mLock) { final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); if (service != null) { options.appDisabledExpiration = service.getAppDisabledExpirationLocked( packageName); options.disabledActivities = service.getAppDisabledActivitiesLocked( packageName); } } } } /** Loading Loading
api/test-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -619,10 +619,13 @@ package android.content { method public int describeContents(); method public static android.content.AutofillOptions forWhitelistingItself(); method public boolean isAugmentedAutofillEnabled(@NonNull android.content.Context); method public boolean isAutofillDisabledLocked(@NonNull android.content.ComponentName); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.content.AutofillOptions> CREATOR; field public long appDisabledExpiration; field public boolean augmentedAutofillEnabled; field public final boolean compatModeEnabled; field @Nullable public android.util.ArrayMap<java.lang.String,java.lang.Long> disabledActivities; field public final int loggingLevel; field @Nullable public android.util.ArraySet<android.content.ComponentName> whitelistedActivitiesForAugmentedAutofill; } Loading
core/java/android/content/AutofillOptions.java +60 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.annotation.TestApi; import android.app.ActivityThread; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.view.autofill.AutofillManager; Loading Loading @@ -62,6 +64,18 @@ public final class AutofillOptions implements Parcelable { @Nullable public ArraySet<ComponentName> whitelistedActivitiesForAugmentedAutofill; /** * The package disable expiration by autofill service. */ public long appDisabledExpiration; /** * The disabled Activities of the package. key is component name string, value is when they * will be enabled. */ @Nullable public ArrayMap<String, Long> disabledActivities; public AutofillOptions(int loggingLevel, boolean compatModeEnabled) { this.loggingLevel = loggingLevel; this.compatModeEnabled = compatModeEnabled; Loading @@ -81,6 +95,27 @@ public final class AutofillOptions implements Parcelable { || whitelistedActivitiesForAugmentedAutofill.contains(component); } /** * Returns if autofill is disabled by service to the given activity. */ public boolean isAutofillDisabledLocked(@NonNull ComponentName componentName) { final long elapsedTime = SystemClock.elapsedRealtime(); final String component = componentName.flattenToString(); // Check app first. if (appDisabledExpiration >= elapsedTime) return true; // Then check activities. if (disabledActivities != null) { final Long expiration = disabledActivities.get(component); if (expiration != null) { if (expiration >= elapsedTime) return true; disabledActivities.remove(component); } } appDisabledExpiration = 0; return false; } /** * @hide */ Loading Loading @@ -110,7 +145,8 @@ public final class AutofillOptions implements Parcelable { @Override public String toString() { return "AutofillOptions [loggingLevel=" + loggingLevel + ", compatMode=" + compatModeEnabled + ", augmentedAutofillEnabled=" + augmentedAutofillEnabled + "]"; + ", augmentedAutofillEnabled=" + augmentedAutofillEnabled + ", appDisabledExpiration=" + appDisabledExpiration + "]"; } /** @hide */ Loading @@ -122,6 +158,11 @@ public final class AutofillOptions implements Parcelable { pw.print(", whitelistedActivitiesForAugmentedAutofill="); pw.print(whitelistedActivitiesForAugmentedAutofill); } pw.print(", appDisabledExpiration="); pw.print(appDisabledExpiration); if (disabledActivities != null) { pw.print(", disabledActivities="); pw.print(disabledActivities); } } @Override Loading @@ -135,6 +176,16 @@ public final class AutofillOptions implements Parcelable { parcel.writeBoolean(compatModeEnabled); parcel.writeBoolean(augmentedAutofillEnabled); parcel.writeArraySet(whitelistedActivitiesForAugmentedAutofill); parcel.writeLong(appDisabledExpiration); final int size = disabledActivities != null ? disabledActivities.size() : 0; parcel.writeInt(size); if (size > 0) { for (int i = 0; i < size; i++) { final String key = disabledActivities.keyAt(i); parcel.writeString(key); parcel.writeLong(disabledActivities.get(key)); } } } public static final @android.annotation.NonNull Parcelable.Creator<AutofillOptions> CREATOR = Loading @@ -148,6 +199,14 @@ public final class AutofillOptions implements Parcelable { options.augmentedAutofillEnabled = parcel.readBoolean(); options.whitelistedActivitiesForAugmentedAutofill = (ArraySet<ComponentName>) parcel.readArraySet(null); options.appDisabledExpiration = parcel.readLong(); final int size = parcel.readInt(); if (size > 0) { options.disabledActivities = new ArrayMap<>(); for (int i = 0; i < size; i++) { options.disabledActivities.put(parcel.readString(), parcel.readLong()); } } return options; } Loading
core/java/android/view/autofill/AutofillManager.java +62 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.service.autofill.AutofillService; import android.service.autofill.FillEventHistory; import android.service.autofill.UserData; Loading Loading @@ -1737,6 +1738,26 @@ public final class AutofillManager { final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); final ComponentName componentName = client.autofillClientGetComponentName(); if (!mEnabledForAugmentedAutofillOnly && mOptions != null && mOptions.isAutofillDisabledLocked(componentName)) { if (mOptions.isAugmentedAutofillEnabled(mContext)) { if (sDebug) { Log.d(TAG, "startSession(" + componentName + "): disabled by service but " + "whitelisted for augmented autofill"); flags |= FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY; } } else { if (sDebug) { Log.d(TAG, "startSession(" + componentName + "): ignored because " + "disabled by service and not whitelisted for augmented autofill"); } setSessionFinished(AutofillManager.STATE_DISABLED_BY_SERVICE, null); client.autofillClientResetableStateAvailable(); return; } } mService.startSession(client.autofillClientGetActivityToken(), mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(), mCallback != null, flags, componentName, Loading Loading @@ -2067,6 +2088,7 @@ public final class AutofillManager { mServiceClientCleaner.clean(); mServiceClientCleaner = null; } notifyReenableAutofill(); } } sDebug = (flags & SET_STATE_FLAG_DEBUG) != 0; Loading Loading @@ -2403,6 +2425,37 @@ public final class AutofillManager { } } private void notifyDisableAutofill(long disableDuration, ComponentName componentName) { synchronized (mLock) { if (mOptions == null) { return; } long expiration = SystemClock.elapsedRealtime() + disableDuration; // Protect it against overflow if (expiration < 0) { expiration = Long.MAX_VALUE; } if (componentName != null) { if (mOptions.disabledActivities == null) { mOptions.disabledActivities = new ArrayMap<>(); } mOptions.disabledActivities.put(componentName.flattenToString(), expiration); } else { mOptions.appDisabledExpiration = expiration; } } } void notifyReenableAutofill() { synchronized (mLock) { if (mOptions == null) { return; } mOptions.appDisabledExpiration = 0; mOptions.disabledActivities = null; } } private void notifyNoFillUi(int sessionId, AutofillId id, int sessionFinishedState) { if (sVerbose) { Log.v(TAG, "notifyNoFillUi(): sessionId=" + sessionId + ", autofillId=" + id Loading Loading @@ -3180,6 +3233,15 @@ public final class AutofillManager { } } @Override public void notifyDisableAutofill(long disableDuration, ComponentName componentName) throws RemoteException { final AutofillManager afm = mAfm.get(); if (afm != null) { afm.post(() -> afm.notifyDisableAutofill(disableDuration, componentName)); } } @Override public void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent fullScreen) { final AutofillManager afm = mAfm.get(); Loading
core/java/android/view/autofill/IAutoFillManagerClient.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view.autofill; import java.util.List; import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; import android.graphics.Rect; Loading Loading @@ -111,4 +112,8 @@ oneway interface IAutoFillManagerClient { */ void getAugmentedAutofillClient(in IResultReceiver result); /** * Notifies disables autofill for the app or activity. */ void notifyDisableAutofill(long disableDuration, in ComponentName componentName); }
services/autofill/java/com/android/server/autofill/AutofillManagerService.java +14 −0 Original line number Diff line number Diff line Loading @@ -807,6 +807,7 @@ public final class AutofillManagerService packageName, versionCode, userId); final AutofillOptions options = new AutofillOptions(loggingLevel, compatModeEnabled); mAugmentedAutofillState.injectAugmentedAutofillInfo(options, userId, packageName); injectDisableAppInfo(options, userId, packageName); return options; } Loading @@ -820,6 +821,19 @@ public final class AutofillManagerService } return false; } private void injectDisableAppInfo(@NonNull AutofillOptions options, int userId, String packageName) { synchronized (mLock) { final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); if (service != null) { options.appDisabledExpiration = service.getAppDisabledExpirationLocked( packageName); options.disabledActivities = service.getAppDisabledActivitiesLocked( packageName); } } } } /** Loading