[Autofill CredMan]: Autofill changes for CredMan integration
For views labelled with for isCredential, disable autofill. Manual request should still continue to work. This CL also refactors feature flags to a common class. BUG: 261045584 Test: atest android.autofillservice.cts.dialog.LoginActivityTest#testCredentialManagerIntegration --iterations=10. Also tested manually with the formgen app with custom changes. Change-Id: Ic2b71b2c027d5fc34006b1660d8ee13ce69aac4c
This commit is contained in:
@@ -51415,6 +51415,7 @@ package android.view {
|
||||
method public boolean isAutoHandwritingEnabled();
|
||||
method public boolean isClickable();
|
||||
method public boolean isContextClickable();
|
||||
method public boolean isCredential();
|
||||
method public boolean isDirty();
|
||||
method @Deprecated public boolean isDrawingCacheEnabled();
|
||||
method public boolean isDuplicateParentStateEnabled();
|
||||
@@ -51648,6 +51649,7 @@ package android.view {
|
||||
method public void setImportantForAccessibility(int);
|
||||
method public void setImportantForAutofill(int);
|
||||
method public void setImportantForContentCapture(int);
|
||||
method public void setIsCredential(boolean);
|
||||
method public void setKeepScreenOn(boolean);
|
||||
method public void setKeyboardNavigationCluster(boolean);
|
||||
method public void setLabelFor(@IdRes int);
|
||||
|
||||
@@ -3206,6 +3206,14 @@ package android.view.animation {
|
||||
|
||||
package android.view.autofill {
|
||||
|
||||
public class AutofillFeatureFlags {
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "compat_mode_allowed_packages";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED = "autofill_credential_manager_enabled";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_IGNORE_VIEWS = "autofill_credential_manager_ignore_views";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED = "autofill_dialog_enabled";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
|
||||
}
|
||||
|
||||
public final class AutofillId implements android.os.Parcelable {
|
||||
ctor public AutofillId(int);
|
||||
ctor public AutofillId(@NonNull android.view.autofill.AutofillId, int);
|
||||
@@ -3217,9 +3225,6 @@ package android.view.autofill {
|
||||
}
|
||||
|
||||
public final class AutofillManager {
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "compat_mode_allowed_packages";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED = "autofill_dialog_enabled";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
|
||||
field public static final int FLAG_SMART_SUGGESTION_OFF = 0; // 0x0
|
||||
field public static final int FLAG_SMART_SUGGESTION_SYSTEM = 1; // 0x1
|
||||
field public static final int MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS = 120000; // 0x1d4c0
|
||||
|
||||
@@ -141,6 +141,7 @@ import android.view.accessibility.AccessibilityWindowInfo;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Transformation;
|
||||
import android.view.autofill.AutofillFeatureFlags;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillManager;
|
||||
import android.view.autofill.AutofillValue;
|
||||
@@ -3662,6 +3663,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
* Indicates that the view enables auto handwriting initiation.
|
||||
*/
|
||||
private static final int PFLAG4_AUTO_HANDWRITING_ENABLED = 0x000010000;
|
||||
|
||||
/**
|
||||
* Indicates that the view is important for Credential Manager.
|
||||
*/
|
||||
private static final int PFLAG4_IMPORTANT_FOR_CREDENTIAL_MANAGER = 0x000020000;
|
||||
|
||||
/* End of masks for mPrivateFlags4 */
|
||||
|
||||
/** @hide */
|
||||
@@ -6130,6 +6137,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
setImportantForContentCapture(a.getInt(attr,
|
||||
IMPORTANT_FOR_CONTENT_CAPTURE_AUTO));
|
||||
}
|
||||
break;
|
||||
case R.styleable.View_isCredential:
|
||||
if (a.peekValue(attr) != null) {
|
||||
setIsCredential(a.getBoolean(attr, false));
|
||||
}
|
||||
break;
|
||||
case R.styleable.View_defaultFocusHighlightEnabled:
|
||||
if (a.peekValue(attr) != null) {
|
||||
setDefaultFocusHighlightEnabled(a.getBoolean(attr, true));
|
||||
@@ -10234,6 +10247,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
private boolean isAutofillable() {
|
||||
if (getAutofillType() == AUTOFILL_TYPE_NONE) return false;
|
||||
|
||||
// Disable triggering autofill if the view is integrated with CredentialManager.
|
||||
if (AutofillFeatureFlags.shouldIgnoreCredentialViews()
|
||||
&& isCredential()) return false;
|
||||
|
||||
if (!isImportantForAutofill()) {
|
||||
// View is not important for "regular" autofill, so we must check if Augmented Autofill
|
||||
// is enabled for the activity
|
||||
@@ -31860,6 +31877,37 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mode for determining whether this view is a credential.
|
||||
*
|
||||
* <p>See {@link #isCredential()}.
|
||||
*
|
||||
* @param isCredential Whether the view is a credential.
|
||||
*
|
||||
* @attr ref android.R.styleable#View_isCredential
|
||||
*/
|
||||
public void setIsCredential(boolean isCredential) {
|
||||
if (isCredential) {
|
||||
mPrivateFlags4 |= PFLAG4_IMPORTANT_FOR_CREDENTIAL_MANAGER;
|
||||
} else {
|
||||
mPrivateFlags4 &= ~PFLAG4_IMPORTANT_FOR_CREDENTIAL_MANAGER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mode for determining whether this view is a credential.
|
||||
*
|
||||
* <p>See {@link #setIsCredential(boolean)}.
|
||||
*
|
||||
* @return false by default, or value passed to {@link #setIsCredential(boolean)}.
|
||||
*
|
||||
* @attr ref android.R.styleable#View_isCredential
|
||||
*/
|
||||
public boolean isCredential() {
|
||||
return ((mPrivateFlags4 & PFLAG4_IMPORTANT_FOR_CREDENTIAL_MANAGER)
|
||||
== PFLAG4_IMPORTANT_FOR_CREDENTIAL_MANAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this view enables automatic handwriting initiation.
|
||||
*
|
||||
|
||||
224
core/java/android/view/autofill/AutofillFeatureFlags.java
Normal file
224
core/java/android/view/autofill/AutofillFeatureFlags.java
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view.autofill;
|
||||
|
||||
import android.annotation.TestApi;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
/**
|
||||
* Feature flags associated with autofill.
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public class AutofillFeatureFlags {
|
||||
|
||||
/**
|
||||
* {@code DeviceConfig} property used to set which Smart Suggestion modes for Augmented Autofill
|
||||
* are available.
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES =
|
||||
"smart_suggestion_supported_modes";
|
||||
|
||||
/**
|
||||
* Sets how long (in ms) the augmented autofill service is bound while idle.
|
||||
*
|
||||
* <p>Use {@code 0} to keep it permanently bound.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT =
|
||||
"augmented_service_idle_unbind_timeout";
|
||||
|
||||
/**
|
||||
* Sets how long (in ms) the augmented autofill service request is killed if not replied.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT =
|
||||
"augmented_service_request_timeout";
|
||||
|
||||
/**
|
||||
* Sets allowed list for the autofill compatibility mode.
|
||||
*
|
||||
* The list of packages is {@code ":"} colon delimited, and each entry has the name of the
|
||||
* package and an optional list of url bar resource ids (the list is delimited by
|
||||
* brackets&mdash{@code [} and {@code ]}&mdash and is also comma delimited).
|
||||
*
|
||||
* <p>For example, a list with 3 packages {@code p1}, {@code p2}, and {@code p3}, where
|
||||
* package {@code p1} have one id ({@code url_bar}, {@code p2} has none, and {@code p3 }
|
||||
* have 2 ids {@code url_foo} and {@code url_bas}) would be
|
||||
* {@code p1[url_bar]:p2:p3[url_foo,url_bas]}
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES =
|
||||
"compat_mode_allowed_packages";
|
||||
|
||||
/**
|
||||
* Indicates Fill dialog feature enabled or not.
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED =
|
||||
"autofill_dialog_enabled";
|
||||
|
||||
/**
|
||||
* Sets the autofill hints allowed list for the fields that can trigger the fill dialog
|
||||
* feature at Activity starting.
|
||||
*
|
||||
* The list of autofill hints is {@code ":"} colon delimited.
|
||||
*
|
||||
* <p>For example, a list with 3 hints {@code password}, {@code phone}, and
|
||||
* { @code emailAddress}, would be {@code password:phone:emailAddress}
|
||||
*
|
||||
* Note: By default the password field is enabled even there is no password hint in the list
|
||||
*
|
||||
* @see View#setAutofillHints(String...)
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_HINTS =
|
||||
"autofill_dialog_hints";
|
||||
|
||||
// START CREDENTIAL MANAGER FLAGS //
|
||||
|
||||
/**
|
||||
* Indicates whether credential manager tagged views should be ignored from autofill structures.
|
||||
* This flag is further gated by {@link #DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED}
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_IGNORE_VIEWS =
|
||||
"autofill_credential_manager_ignore_views";
|
||||
|
||||
/**
|
||||
* Indicates CredentialManager feature enabled or not.
|
||||
* This is the overall feature flag. Individual behavior of credential manager may be controlled
|
||||
* via a different flag, but gated by this flag.
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED =
|
||||
"autofill_credential_manager_enabled";
|
||||
|
||||
/**
|
||||
* Indicates whether credential manager tagged views should suppress fill dialog.
|
||||
* This flag is further gated by {@link #DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_SUPPRESS_FILL_DIALOG =
|
||||
"autofill_credential_manager_suppress_fill_dialog";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether credential manager tagged views should suppress save dialog.
|
||||
* This flag is further gated by {@link #DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_SUPPRESS_SAVE_DIALOG =
|
||||
"autofill_credential_manager_suppress_save_dialog";
|
||||
// END CREDENTIAL MANAGER FLAGS //
|
||||
|
||||
/**
|
||||
* Sets a value of delay time to show up the inline tooltip view.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_TOOLTIP_SHOW_UP_DELAY =
|
||||
"autofill_inline_tooltip_first_show_delay";
|
||||
|
||||
private static final String DIALOG_HINTS_DELIMITER = ":";
|
||||
|
||||
private static final boolean DEFAULT_HAS_FILL_DIALOG_UI_FEATURE = false;
|
||||
private static final String DEFAULT_FILL_DIALOG_ENABLED_HINTS = "";
|
||||
|
||||
// CREDENTIAL MANAGER DEFAULTS
|
||||
// Credential manager is enabled by default so as to allow testing by app developers
|
||||
private static final boolean DEFAULT_CREDENTIAL_MANAGER_ENABLED = true;
|
||||
private static final boolean DEFAULT_CREDENTIAL_MANAGER_IGNORE_VIEWS = true;
|
||||
private static final boolean DEFAULT_CREDENTIAL_MANAGER_SUPPRESS_FILL_DIALOG = false;
|
||||
private static final boolean DEFAULT_CREDENTIAL_MANAGER_SUPPRESS_SAVE_DIALOG = false;
|
||||
// END CREDENTIAL MANAGER DEFAULTS
|
||||
|
||||
private AutofillFeatureFlags() {};
|
||||
|
||||
/**
|
||||
* Whether the fill dialog feature is enabled or not
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isFillDialogEnabled() {
|
||||
return DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED,
|
||||
DEFAULT_HAS_FILL_DIALOG_UI_FEATURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets fill dialog enabled hints.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static String[] getFillDialogEnabledHints() {
|
||||
final String dialogHints = DeviceConfig.getString(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_DIALOG_HINTS,
|
||||
DEFAULT_FILL_DIALOG_ENABLED_HINTS);
|
||||
if (TextUtils.isEmpty(dialogHints)) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
return ArrayUtils.filter(dialogHints.split(DIALOG_HINTS_DELIMITER), String[]::new,
|
||||
(str) -> !TextUtils.isEmpty(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the Credential Manager feature is enabled or not
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isCredentialManagerEnabled() {
|
||||
return DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED,
|
||||
DEFAULT_CREDENTIAL_MANAGER_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether credential manager tagged views should be ignored for autofill structure.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static boolean shouldIgnoreCredentialViews() {
|
||||
return isCredentialManagerEnabled()
|
||||
&& DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_IGNORE_VIEWS,
|
||||
DEFAULT_CREDENTIAL_MANAGER_IGNORE_VIEWS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether credential manager tagged views should not trigger fill dialog requests.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isFillDialogDisabledForCredentialManager() {
|
||||
return isCredentialManagerEnabled()
|
||||
&& DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_SUPPRESS_FILL_DIALOG,
|
||||
DEFAULT_CREDENTIAL_MANAGER_SUPPRESS_FILL_DIALOG);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,6 @@ import android.os.Looper;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.service.autofill.AutofillService;
|
||||
import android.service.autofill.FillCallback;
|
||||
import android.service.autofill.FillEventHistory;
|
||||
@@ -450,88 +449,6 @@ public final class AutofillManager {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface SmartSuggestionMode {}
|
||||
|
||||
/**
|
||||
* {@code DeviceConfig} property used to set which Smart Suggestion modes for Augmented Autofill
|
||||
* are available.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES =
|
||||
"smart_suggestion_supported_modes";
|
||||
|
||||
/**
|
||||
* Sets how long (in ms) the augmented autofill service is bound while idle.
|
||||
*
|
||||
* <p>Use {@code 0} to keep it permanently bound.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT =
|
||||
"augmented_service_idle_unbind_timeout";
|
||||
|
||||
/**
|
||||
* Sets how long (in ms) the augmented autofill service request is killed if not replied.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT =
|
||||
"augmented_service_request_timeout";
|
||||
|
||||
/**
|
||||
* Sets allowed list for the autofill compatibility mode.
|
||||
*
|
||||
* The list of packages is {@code ":"} colon delimited, and each entry has the name of the
|
||||
* package and an optional list of url bar resource ids (the list is delimited by
|
||||
* brackets&mdash{@code [} and {@code ]}&mdash and is also comma delimited).
|
||||
*
|
||||
* <p>For example, a list with 3 packages {@code p1}, {@code p2}, and {@code p3}, where
|
||||
* package {@code p1} have one id ({@code url_bar}, {@code p2} has none, and {@code p3 }
|
||||
* have 2 ids {@code url_foo} and {@code url_bas}) would be
|
||||
* {@code p1[url_bar]:p2:p3[url_foo,url_bas]}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES =
|
||||
"compat_mode_allowed_packages";
|
||||
|
||||
/**
|
||||
* Sets the fill dialog feature enabled or not.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED =
|
||||
"autofill_dialog_enabled";
|
||||
|
||||
/**
|
||||
* Sets the autofill hints allowed list for the fields that can trigger the fill dialog
|
||||
* feature at Activity starting.
|
||||
*
|
||||
* The list of autofill hints is {@code ":"} colon delimited.
|
||||
*
|
||||
* <p>For example, a list with 3 hints {@code password}, {@code phone}, and
|
||||
* {@code emailAddress}, would be {@code password:phone:emailAddress}
|
||||
*
|
||||
* Note: By default the password field is enabled even there is no password hint in the list
|
||||
*
|
||||
* @see View#setAutofillHints(String...)
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_HINTS =
|
||||
"autofill_dialog_hints";
|
||||
|
||||
/**
|
||||
* Sets a value of delay time to show up the inline tooltip view.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_TOOLTIP_SHOW_UP_DELAY =
|
||||
"autofill_inline_tooltip_first_show_delay";
|
||||
|
||||
private static final String DIALOG_HINTS_DELIMITER = ":";
|
||||
|
||||
/** @hide */
|
||||
public static final int RESULT_OK = 0;
|
||||
/** @hide */
|
||||
@@ -634,9 +551,6 @@ public final class AutofillManager {
|
||||
*/
|
||||
public static final int NO_SESSION = Integer.MAX_VALUE;
|
||||
|
||||
private static final boolean HAS_FILL_DIALOG_UI_FEATURE_DEFAULT = false;
|
||||
private static final String FILL_DIALOG_ENABLED_DEFAULT_HINTS = "";
|
||||
|
||||
private final IAutoFillManager mService;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
@@ -891,11 +805,8 @@ public final class AutofillManager {
|
||||
mOptions = context.getAutofillOptions();
|
||||
mIsFillRequested = new AtomicBoolean(false);
|
||||
|
||||
mIsFillDialogEnabled = DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED,
|
||||
HAS_FILL_DIALOG_UI_FEATURE_DEFAULT);
|
||||
mFillDialogEnabledHints = getFillDialogEnabledHints();
|
||||
mIsFillDialogEnabled = AutofillFeatureFlags.isFillDialogEnabled();
|
||||
mFillDialogEnabledHints = AutofillFeatureFlags.getFillDialogEnabledHints();
|
||||
if (sDebug) {
|
||||
Log.d(TAG, "Fill dialog is enabled:" + mIsFillDialogEnabled
|
||||
+ ", hints=" + Arrays.toString(mFillDialogEnabledHints));
|
||||
@@ -907,19 +818,6 @@ public final class AutofillManager {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getFillDialogEnabledHints() {
|
||||
final String dialogHints = DeviceConfig.getString(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_DIALOG_HINTS,
|
||||
FILL_DIALOG_ENABLED_DEFAULT_HINTS);
|
||||
if (TextUtils.isEmpty(dialogHints)) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
return ArrayUtils.filter(dialogHints.split(DIALOG_HINTS_DELIMITER), String[]::new,
|
||||
(str) -> !TextUtils.isEmpty(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -1190,16 +1088,28 @@ public final class AutofillManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link #DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED} is {@code true} or the view have
|
||||
* the allowed autofill hints, performs a fill request to know there is any field supported
|
||||
* fill dialog.
|
||||
* The {@link AutofillFeatureFlags#DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED} is {@code true} or
|
||||
* the view have the allowed autofill hints, performs a fill request to know there is any field
|
||||
* supported fill dialog.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void notifyViewEnteredForFillDialog(View v) {
|
||||
if (sDebug) {
|
||||
Log.d(TAG, "notifyViewEnteredForFillDialog:" + v.getAutofillId());
|
||||
}
|
||||
if (!hasAutofillFeature()) {
|
||||
return;
|
||||
}
|
||||
if (AutofillFeatureFlags.isFillDialogDisabledForCredentialManager()
|
||||
&& v.isCredential()) {
|
||||
if (sDebug) {
|
||||
Log.d(TAG, "Ignoring Fill Dialog request since important for credMan:"
|
||||
+ v.getAutofillId().toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mTrackedViews != null) {
|
||||
// To support the fill dialog can show for the autofillable Views in
|
||||
@@ -1227,8 +1137,8 @@ public final class AutofillManager {
|
||||
synchronized (mLock) {
|
||||
// To match the id of the IME served view, used AutofillId.NO_AUTOFILL_ID on prefill
|
||||
// request, because IME will reset the id of IME served view to 0 when activity
|
||||
// start and does not focus on any view. If the id of the prefill request is
|
||||
// not match to the IME served view's, Autofill will be blocking to wait inline
|
||||
// start and does not focus on any view. If the id of the prefill request does
|
||||
// not match the IME served view's, Autofill will be blocking to wait inline
|
||||
// request from the IME.
|
||||
notifyViewEnteredLocked(/* view= */ null, AutofillId.NO_AUTOFILL_ID,
|
||||
/* bounds= */ null, /* value= */ null, flags);
|
||||
@@ -4075,6 +3985,7 @@ public final class AutofillManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyFillDialogTriggerIds(List<AutofillId> ids) {
|
||||
final AutofillManager afm = mAfm.get();
|
||||
if (afm != null) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.android.internal.view.inline;
|
||||
|
||||
import static android.view.autofill.AutofillManager.DEVICE_CONFIG_AUTOFILL_TOOLTIP_SHOW_UP_DELAY;
|
||||
import static android.view.autofill.AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_TOOLTIP_SHOW_UP_DELAY;
|
||||
import static android.view.autofill.Helper.sVerbose;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view.autofill;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutofillFeatureFlags}
|
||||
*
|
||||
* run: atest FrameworksCoreTests:android.view.autofill.AutofillFeatureFlagsTest
|
||||
*/
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AutofillFeatureFlagsTest {
|
||||
|
||||
@Test
|
||||
public void testGetFillDialogEnabledHintsEmpty() {
|
||||
setFillDialogHints("");
|
||||
String[] fillDialogHints = AutofillFeatureFlags.getFillDialogEnabledHints();
|
||||
assertThat(fillDialogHints).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFillDialogEnabledHintsTwoValues() {
|
||||
setFillDialogHints("password:creditCardNumber");
|
||||
String[] fillDialogHints = AutofillFeatureFlags.getFillDialogEnabledHints();
|
||||
assertThat(fillDialogHints.length).isEqualTo(2);
|
||||
assertThat(fillDialogHints[0]).isEqualTo("password");
|
||||
assertThat(fillDialogHints[1]).isEqualTo("creditCardNumber");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsCredentialManagerEnabled() {
|
||||
setCredentialManagerEnabled(false);
|
||||
assertThat(AutofillFeatureFlags.isCredentialManagerEnabled()).isFalse();
|
||||
setCredentialManagerEnabled(true);
|
||||
assertThat(AutofillFeatureFlags.isCredentialManagerEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldIgnoreCredentialManagerViews() {
|
||||
setCredentialManagerEnabled(false);
|
||||
setIgnoreCredentialManagerViews(true);
|
||||
// Overall feature is disabled, so we shouldn't ignore views.
|
||||
assertThat(AutofillFeatureFlags.shouldIgnoreCredentialViews()).isFalse();
|
||||
setCredentialManagerEnabled(true);
|
||||
assertThat(AutofillFeatureFlags.shouldIgnoreCredentialViews()).isTrue();
|
||||
}
|
||||
|
||||
private static void setFillDialogHints(String value) {
|
||||
setDeviceConfig(
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_DIALOG_HINTS,
|
||||
value);
|
||||
}
|
||||
|
||||
private static void setCredentialManagerEnabled(boolean value) {
|
||||
setDeviceConfig(
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED,
|
||||
String.valueOf(value));
|
||||
}
|
||||
|
||||
private static void setIgnoreCredentialManagerViews(boolean value) {
|
||||
setDeviceConfig(
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_IGNORE_VIEWS,
|
||||
String.valueOf(value));
|
||||
}
|
||||
|
||||
private static void setDeviceConfig(String key, String value) {
|
||||
DeviceConfig.setProperty(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL, key, value, /* makeDefault */ false);
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@ import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.TimeUtils;
|
||||
import android.view.autofill.AutofillFeatureFlags;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillManager;
|
||||
import android.view.autofill.AutofillManager.AutofillCommitReason;
|
||||
@@ -298,12 +299,12 @@ public final class AutofillManagerService
|
||||
private void onDeviceConfigChange(@NonNull Set<String> keys) {
|
||||
for (String key : keys) {
|
||||
switch (key) {
|
||||
case AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
|
||||
case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
|
||||
case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT:
|
||||
setDeviceConfigProperties();
|
||||
break;
|
||||
case AutofillManager.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
|
||||
updateCachedServices();
|
||||
break;
|
||||
default:
|
||||
@@ -567,15 +568,15 @@ public final class AutofillManagerService
|
||||
synchronized (mLock) {
|
||||
mAugmentedServiceIdleUnbindTimeoutMs = DeviceConfig.getInt(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT,
|
||||
(int) AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS);
|
||||
mAugmentedServiceRequestTimeoutMs = DeviceConfig.getInt(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT,
|
||||
DEFAULT_AUGMENTED_AUTOFILL_REQUEST_TIMEOUT_MILLIS);
|
||||
mSupportedSmartSuggestionModes = DeviceConfig.getInt(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES,
|
||||
AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM);
|
||||
if (verbose) {
|
||||
Slog.v(mTag, "setDeviceConfigProperties(): "
|
||||
@@ -729,7 +730,7 @@ public final class AutofillManagerService
|
||||
private String getAllowedCompatModePackagesFromDeviceConfig() {
|
||||
String config = DeviceConfig.getString(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillManager.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
|
||||
/* defaultValue */ null);
|
||||
if (!TextUtils.isEmpty(config)) {
|
||||
return config;
|
||||
|
||||
Reference in New Issue
Block a user