Merge "Changes on Assist structure to handle virtual child for autofill:"
diff --git a/api/current.txt b/api/current.txt
index 235a4a6..dc67b7d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -46324,7 +46324,6 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
-    method public abstract android.view.ViewStructure asyncNewChild(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46333,11 +46332,11 @@
     method public abstract int getTextSelectionStart();
     method public abstract boolean hasExtras();
     method public abstract android.view.ViewStructure newChild(int);
-    method public abstract android.view.ViewStructure newChild(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
     method public abstract void setAutofillHint(java.lang.String[]);
+    method public abstract void setAutofillId(android.view.ViewStructure, int);
     method public abstract void setAutofillOptions(java.lang.String[]);
     method public abstract void setAutofillType(int);
     method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
diff --git a/api/system-current.txt b/api/system-current.txt
index abdcaaa..748875a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -49787,7 +49787,6 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
-    method public abstract android.view.ViewStructure asyncNewChild(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -49796,11 +49795,11 @@
     method public abstract int getTextSelectionStart();
     method public abstract boolean hasExtras();
     method public abstract android.view.ViewStructure newChild(int);
-    method public abstract android.view.ViewStructure newChild(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
     method public abstract void setAutofillHint(java.lang.String[]);
+    method public abstract void setAutofillId(android.view.ViewStructure, int);
     method public abstract void setAutofillOptions(java.lang.String[]);
     method public abstract void setAutofillType(int);
     method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
diff --git a/api/test-current.txt b/api/test-current.txt
index 3fb42a4..d511c7a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -46693,7 +46693,6 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
-    method public abstract android.view.ViewStructure asyncNewChild(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46702,11 +46701,11 @@
     method public abstract int getTextSelectionStart();
     method public abstract boolean hasExtras();
     method public abstract android.view.ViewStructure newChild(int);
-    method public abstract android.view.ViewStructure newChild(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
     method public abstract void setAutofillHint(java.lang.String[]);
+    method public abstract void setAutofillId(android.view.ViewStructure, int);
     method public abstract void setAutofillOptions(java.lang.String[]);
     method public abstract void setAutofillType(int);
     method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index e041457..d5436b7 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1,5 +1,6 @@
 package android.app.assist;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.content.ComponentName;
@@ -1601,23 +1602,22 @@
             return mNode.mChildren != null ? mNode.mChildren.length : 0;
         }
 
-        private void setAutofillId(ViewNode child, boolean forAutoFill, int virtualId) {
-            if (forAutoFill) {
-                child.mAutofillId = new AutofillId(mNode.mAutofillId, virtualId);
-            }
+        @Override
+        public void setAutofillId(@NonNull ViewStructure parent, int virtualId) {
+            mNode.mAutofillId = new AutofillId(parent.getAutofillId(), virtualId);
         }
 
-        private ViewStructure newChild(int index, boolean forAutoFill, int virtualId, int flags) {
+        @Override
+        public ViewStructure newChild(int index) {
             ViewNode node = new ViewNode();
-            setAutofillId(node, forAutoFill, virtualId);
             mNode.mChildren[index] = node;
             return new ViewNodeBuilder(mAssist, node, false);
         }
 
-        private ViewStructure asyncNewChild(int index, boolean forAutoFill, int virtualId) {
+        @Override
+        public ViewStructure asyncNewChild(int index) {
             synchronized (mAssist) {
                 ViewNode node = new ViewNode();
-                setAutofillId(node, forAutoFill, virtualId);
                 mNode.mChildren[index] = node;
                 ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true);
                 mAssist.mPendingAsyncChildren.add(builder);
@@ -1626,26 +1626,6 @@
         }
 
         @Override
-        public ViewStructure newChild(int index) {
-            return newChild(index, false, 0, 0);
-        }
-
-        @Override
-        public ViewStructure newChild(int index, int virtualId, int flags) {
-            return newChild(index, true, virtualId, flags);
-        }
-
-        @Override
-        public ViewStructure asyncNewChild(int index) {
-            return asyncNewChild(index, false, 0);
-        }
-
-        @Override
-        public ViewStructure asyncNewChild(int index, int virtualId, int flags) {
-            return asyncNewChild(index, true, virtualId);
-        }
-
-        @Override
         public void asyncCommit() {
             synchronized (mAssist) {
                 if (!mAsync) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e26e609..5269296 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7275,11 +7275,16 @@
      * fills in all data that can be inferred from the view itself.
      * @param flags optional flags (currently {@code 0}).
      */
-    @CallSuper
     public void onProvideAutofillStructure(ViewStructure structure, int flags) {
         onProvideStructureForAssistOrAutofill(structure, true);
     }
 
+    private void setAutofillId(ViewStructure structure) {
+        // The autofill id needs to be unique, but its value doesn't matter,
+        // so it's better to reuse the accessibility id to save space.
+        structure.setAutofillId(getAccessibilityViewId());
+    }
+
     private void onProvideStructureForAssistOrAutofill(ViewStructure structure,
             boolean forAutofill) {
         final int id = mID;
@@ -7299,13 +7304,11 @@
         }
 
         if (forAutofill) {
+            setAutofillId(structure);
             final @AutofillType int autofillType = getAutofillType();
             // Don't need to fill autofill info if view does not support it.
             // For example, only TextViews that are editable support autofill
             if (autofillType != AUTOFILL_TYPE_NONE) {
-                // The autofill id needs to be unique, but its value doesn't matter, so it's better
-                // to reuse the accessibility id to save space.
-                structure.setAutofillId(getAccessibilityViewId());
                 structure.setAutofillType(autofillType);
                 structure.setAutofillHint(getAutofillHint());
                 structure.setAutofillValue(getAutofillValue());
@@ -7404,6 +7407,9 @@
 
     private void onProvideVirtualStructureForAssistOrAutofill(ViewStructure structure,
             boolean forAutofill) {
+        if (forAutofill) {
+            setAutofillId(structure);
+        }
         // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
         // this method should take a boolean with the type of request.
         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
@@ -7671,6 +7677,9 @@
                 AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo(
                         AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
                 ViewStructure child = structure.newChild(i);
+                // TODO(b/33197203): add CTS test to autofill virtual children based on
+                // Accessibility API.
+                child.setAutofillId(structure, i);
                 populateVirtualStructure(child, provider, cinfo, forAutofill);
                 cinfo.recycle();
             }
@@ -7707,9 +7716,7 @@
         boolean blocked = forAutofill ? isAutofillBlocked() : isAssistBlocked();
         if (!blocked) {
             if (forAutofill) {
-                // The autofill id needs to be unique, but its value doesn't matter,
-                // so it's better to reuse the accessibility id to save space.
-                structure.setAutofillId(getAccessibilityViewId());
+                setAutofillId(structure);
                 // NOTE: flags are not currently supported, hence 0
                 onProvideAutofillStructure(structure, 0);
                 onProvideAutofillVirtualStructure(structure, 0);
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 40e0285..b927720 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Matrix;
 import android.graphics.Rect;
@@ -280,20 +281,6 @@
     public abstract ViewStructure newChild(int index);
 
     /**
-     * Create a new child {@link ViewStructure} in this view for autofill purposes.
-     *
-     * @param index the index (in the list of children) to put the new child at (see
-     *            {@link #addChildCount(int)} and {@link #setChildCount(int)}.
-     * @param virtualId an opaque ID to the Android System (although it could be meaningful to the
-     *            {@link View} creating the {@link ViewStructure}), but it's the same id used on
-     *            {@link View#autofill(android.util.SparseArray)}.
-     * @param flags currently {@code 0}.
-     *
-     * @return Returns an fresh {@link ViewStructure} ready to be filled in.
-     */
-    public abstract ViewStructure newChild(int index, int virtualId, int flags);
-
-    /**
      * Like {@link #newChild}, but allows the caller to asynchronously populate the returned
      * child.  It can transfer the returned {@link ViewStructure} to another thread for it
      * to build its content (and children etc).  Once done, some thread must call
@@ -304,25 +291,13 @@
     public abstract ViewStructure asyncNewChild(int index);
 
     /**
-     * Like {@link #newChild(int, int, int)}, but allows the caller to asynchronously
-     * populate the returned child.
+     * Sets the {@link AutofillId} for this virtual node.
      *
-     * <p>It can transfer the returned {@link ViewStructure} to another thread for it to build its
-     * content (and children etc).
-     *
-     * <p>Once done, some thread must call {@link #asyncCommit()} to tell the containing
-     * {@link ViewStructure} that the async population is done.
-     *
-     * @param index the index (in the list of children) to put the new child at (see
-     *            {@link #addChildCount(int)} and {@link #setChildCount(int)}.
-     * @param virtualId an opaque ID to the Android System (although it could be meaningful to the
-     *            {@link View} creating the {@link ViewStructure}), but it's the same id used on
+     * @param parent parent node.
+     * @param virtualId an opaque ID to the Android System; it's the same id used on
      *            {@link View#autofill(android.util.SparseArray)}.
-     * @param flags currently {@code 0}.
-     *
-     * @return Returns an fresh {@link ViewStructure} ready to be filled in.
      */
-    public abstract ViewStructure asyncNewChild(int index, int virtualId, int flags);
+    public abstract void setAutofillId(@NonNull ViewStructure parent, int virtualId);
 
     /**
      * Sets the {@link View#getAutofillType()} that can be used to autofill this node.