Merge "Add API for virtual view is ready to user"
diff --git a/core/api/current.txt b/core/api/current.txt
index 9e4c958..f50d3ca 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -54248,6 +54248,7 @@
method public void notifyViewExited(@NonNull android.view.View, int);
method public void notifyViewVisibilityChanged(@NonNull android.view.View, boolean);
method public void notifyViewVisibilityChanged(@NonNull android.view.View, int, boolean);
+ method public void notifyVirtualViewsReady(@NonNull android.view.View, @NonNull android.util.SparseArray<android.view.autofill.VirtualViewFillInfo>);
method public void registerCallback(@Nullable android.view.autofill.AutofillManager.AutofillCallback);
method public void requestAutofill(@NonNull android.view.View);
method public void requestAutofill(@NonNull android.view.View, int, @NonNull android.graphics.Rect);
@@ -54294,6 +54295,16 @@
field @NonNull public static final android.os.Parcelable.Creator<android.view.autofill.AutofillValue> CREATOR;
}
+ public final class VirtualViewFillInfo {
+ method @Nullable public String[] getAutofillHints();
+ }
+
+ public static final class VirtualViewFillInfo.Builder {
+ ctor public VirtualViewFillInfo.Builder();
+ method @NonNull public android.view.autofill.VirtualViewFillInfo build();
+ method @NonNull public android.view.autofill.VirtualViewFillInfo.Builder setAutofillHints(@NonNull java.lang.String...);
+ }
+
}
package android.view.contentcapture {
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 2ad01ed..b5764c5 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1235,6 +1235,42 @@
}
/**
+ * Called when the virtual views are ready to the user for autofill.
+ *
+ * This method is used to notify autofill system the views are ready to the user. And then
+ * Autofill can do initialization if needed before the user starts to input. For example, do
+ * a pre-fill request for the
+ * <a href="/reference/android/service/autofill/Dataset.html#FillDialogUI">fill dialog</a>.
+ *
+ * @param view the host view that holds a virtual view hierarchy.
+ * @param infos extra information for the virtual views. The key is virtual id which represents
+ * the virtual view in the host view.
+ *
+ * @throws IllegalArgumentException if the {@code infos} was empty
+ */
+ public void notifyVirtualViewsReady(
+ @NonNull View view, @NonNull SparseArray<VirtualViewFillInfo> infos) {
+ Objects.requireNonNull(infos);
+ if (infos.size() == 0) {
+ throw new IllegalArgumentException("No VirtualViewInfo found");
+ }
+ if (AutofillFeatureFlags.isFillDialogDisabledForCredentialManager()
+ && view.isCredential()) {
+ if (sDebug) {
+ Log.d(TAG, "Ignoring Fill Dialog request since important for credMan:"
+ + view.getAutofillId().toString());
+ }
+ return;
+ }
+ for (int i = 0; i < infos.size(); i++) {
+ final VirtualViewFillInfo info = infos.valueAt(i);
+ final int virtualId = infos.indexOfKey(i);
+ notifyViewReadyInner(getAutofillId(view, virtualId),
+ (info == null) ? null : info.getAutofillHints());
+ }
+ }
+
+ /**
* 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.
@@ -1245,9 +1281,6 @@
if (sDebug) {
Log.d(TAG, "notifyViewEnteredForFillDialog:" + v.getAutofillId());
}
- if (!hasAutofillFeature()) {
- return;
- }
if (AutofillFeatureFlags.isFillDialogDisabledForCredentialManager()
&& v.isCredential()) {
if (sDebug) {
@@ -1256,6 +1289,13 @@
}
return;
}
+ notifyViewReadyInner(v.getAutofillId(), v.getAutofillHints());
+ }
+
+ private void notifyViewReadyInner(AutofillId id, String[] autofillHints) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (mTrackedViews != null) {
@@ -1263,7 +1303,7 @@
// different pages but in the same Activity. We need to reset the
// mIsFillRequested flag to allow asking for a new FillRequest when
// user switches to other page
- mTrackedViews.checkViewState(v.getAutofillId());
+ mTrackedViews.checkViewState(id);
}
}
@@ -1273,9 +1313,9 @@
}
if (mIsFillDialogEnabled
- || ArrayUtils.containsAny(v.getAutofillHints(), mFillDialogEnabledHints)) {
+ || ArrayUtils.containsAny(autofillHints, mFillDialogEnabledHints)) {
if (sDebug) {
- Log.d(TAG, "Trigger fill request at view entered");
+ Log.d(TAG, "Trigger fill request when the view is ready.");
}
int flags = FLAG_SUPPORTS_FILL_DIALOG;
diff --git a/core/java/android/view/autofill/VirtualViewFillInfo.java b/core/java/android/view/autofill/VirtualViewFillInfo.java
new file mode 100644
index 0000000..4bec5a4
--- /dev/null
+++ b/core/java/android/view/autofill/VirtualViewFillInfo.java
@@ -0,0 +1,141 @@
+/*
+ * 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.Nullable;
+import android.annotation.SuppressLint;
+import android.view.View;
+
+import com.android.internal.util.DataClass;
+
+
+/**
+ * Information for the virtual view to the autofill framework.
+ */
+@DataClass(genBuilder = true)
+public final class VirtualViewFillInfo {
+
+ /**
+ * Autofill hints of the virtual view.
+ *
+ * @see View#setAutofillHints(String...)
+ */
+ @Nullable
+ @SuppressLint("NullableCollection")
+ private String[] mAutofillHints;
+
+ private static String[] defaultAutofillHints() {
+ return null;
+ }
+
+
+
+ // Code below generated by codegen v1.0.23.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/autofill/VirtualViewFillInfo.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ @DataClass.Generated.Member
+ /* package-private */ VirtualViewFillInfo(
+ @Nullable @SuppressLint("NullableCollection") String[] autofillHints) {
+ this.mAutofillHints = autofillHints;
+ com.android.internal.util.AnnotationValidations.validate(
+ SuppressLint.class, null, mAutofillHints,
+ "value", "NullableCollection");
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ /**
+ * Autofill hints of the virtual view.
+ *
+ * @see View#setAutofillHints(String...)
+ */
+ @DataClass.Generated.Member
+ public @Nullable @SuppressLint("NullableCollection") String[] getAutofillHints() {
+ return mAutofillHints;
+ }
+
+ /**
+ * A builder for {@link VirtualViewFillInfo}
+ */
+ @SuppressWarnings("WeakerAccess")
+ @DataClass.Generated.Member
+ public static final class Builder {
+
+ private @Nullable @SuppressLint("NullableCollection") String[] mAutofillHints;
+
+ private long mBuilderFieldsSet = 0L;
+
+ public Builder() {
+ }
+
+ /**
+ * Autofill hints of the virtual view.
+ *
+ * @see View#setAutofillHints(String...)
+ */
+ @DataClass.Generated.Member
+ public @android.annotation.NonNull Builder setAutofillHints(@SuppressLint("NullableCollection") @android.annotation.NonNull String... value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x1;
+ mAutofillHints = value;
+ return this;
+ }
+
+ /** Builds the instance. This builder should not be touched after calling this! */
+ public @android.annotation.NonNull VirtualViewFillInfo build() {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x2; // Mark builder used
+
+ if ((mBuilderFieldsSet & 0x1) == 0) {
+ mAutofillHints = defaultAutofillHints();
+ }
+ VirtualViewFillInfo o = new VirtualViewFillInfo(
+ mAutofillHints);
+ return o;
+ }
+
+ private void checkNotUsed() {
+ if ((mBuilderFieldsSet & 0x2) != 0) {
+ throw new IllegalStateException(
+ "This Builder should not be reused. Use a new Builder instance instead");
+ }
+ }
+ }
+
+ @DataClass.Generated(
+ time = 1674023010954L,
+ codegenVersion = "1.0.23",
+ sourceFile = "frameworks/base/core/java/android/view/autofill/VirtualViewFillInfo.java",
+ inputSignatures = "private @android.annotation.Nullable @android.annotation.SuppressLint java.lang.String[] mAutofillHints\nprivate static java.lang.String[] defaultAutofillHints()\nclass VirtualViewFillInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
+}