summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--api/test-current.txt2
-rw-r--r--core/java/android/app/assist/AssistStructure.java21
-rw-r--r--core/java/android/view/View.java8
-rw-r--r--core/java/android/view/ViewStructure.java9
-rw-r--r--core/java/android/view/autofill/AutoFillType.java2
-rw-r--r--core/java/android/widget/AdapterView.java6
-rw-r--r--core/java/android/widget/RadioGroup.java11
-rw-r--r--core/java/android/widget/Spinner.java40
10 files changed, 98 insertions, 5 deletions
diff --git a/api/current.txt b/api/current.txt
index 61ddd76f5282..04cdf0523d26 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6547,6 +6547,7 @@ package android.app.assist {
public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
+ method public java.lang.String[] getAutoFillOptions();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
@@ -45644,6 +45645,7 @@ package android.view {
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
+ method public abstract void setAutoFillOptions(java.lang.String[]);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index e170345faa4f..0aa629670ad7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6787,6 +6787,7 @@ package android.app.assist {
public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
+ method public java.lang.String[] getAutoFillOptions();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
@@ -49189,6 +49190,7 @@ package android.view {
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
+ method public abstract void setAutoFillOptions(java.lang.String[]);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
diff --git a/api/test-current.txt b/api/test-current.txt
index af51baafc1b3..22dcb7026bfe 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6573,6 +6573,7 @@ package android.app.assist {
public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
+ method public java.lang.String[] getAutoFillOptions();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
@@ -46006,6 +46007,7 @@ package android.view {
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
+ method public abstract void setAutoFillOptions(java.lang.String[]);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 678c017febe0..716bbe9458c0 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -538,6 +538,7 @@ public class AssistStructure implements Parcelable {
AutoFillId mAutoFillId;
AutoFillType mAutoFillType;
AutoFillValue mAutoFillValue;
+ String[] mAutoFillOptions;
boolean mSanitized;
int mX;
int mY;
@@ -618,6 +619,7 @@ public class AssistStructure implements Parcelable {
mAutoFillId = in.readParcelable(null);
mAutoFillType = in.readParcelable(null);
mAutoFillValue = in.readParcelable(null);
+ mAutoFillOptions = in.readStringArray();
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
mX = in.readInt();
@@ -738,6 +740,7 @@ public class AssistStructure implements Parcelable {
out.writeParcelable(mAutoFillType, 0);
final AutoFillValue sanitizedValue = writeSensitive ? mAutoFillValue : null;
out.writeParcelable(sanitizedValue, 0);
+ out.writeStringArray(mAutoFillOptions);
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
out.writeInt(mX);
@@ -844,6 +847,19 @@ public class AssistStructure implements Parcelable {
return mAutoFillValue;
}
+ /**
+ * Gets the options that can be used to auto-fill this structure.
+ *
+ * <p>Typically used by nodes whose {@link AutoFillType} is a list to indicate the meaning
+ * of each possible value in the list.
+ *
+ * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+ * for assist.
+ */
+ public String[] getAutoFillOptions() {
+ return mAutoFillOptions;
+ }
+
/** @hide */
public boolean isSanitized() {
return mSanitized;
@@ -1506,6 +1522,11 @@ public class AssistStructure implements Parcelable {
mNode.mAutoFillValue = value;
}
+ @Override
+ public void setAutoFillOptions(String[] options) {
+ mNode.mAutoFillOptions = options;
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e7838a7521e0..86669308539a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6993,8 +6993,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Called when assist structure is being retrieved from a view as part of an auto-fill request.
*
* <p>This method already provides most of what's needed for auto-fill, but should be overridden
- * when the view contents does not include PII (Personally Identifiable Information) (so it
- * can call {@link ViewStructure#setSanitized(boolean) ViewStructure#setSanitized(true)}).
+ * <ol>
+ * <li>The view contents does not include PII (Personally Identifiable Information), so it
+ * can call {@link ViewStructure#setSanitized(boolean)} passing {@code true}.
+ * <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
+ * {@link ViewStructure#setAutoFillOptions(String[])}, or {@link ViewStructure#setUrl(String)}.
+ * </ol>
*
* @param structure Fill in with structured view data. The default implementation
* fills in all data that can be inferred from the view itself.
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index bc2725f56bf6..84c2c8452e98 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -307,6 +307,15 @@ public abstract class ViewStructure {
public abstract void setAutoFillValue(AutoFillValue value);
/**
+ * Sets the options that can be used to auto-fill this node.
+ *
+ * <p>Typically used by nodes whose {@link AutoFillType} is a list to indicate the meaning of
+ * each possible value in the list.
+ */
+ // TODO(b/33197203, b/33802548): add CTS/unit test
+ public abstract void setAutoFillOptions(String[] options);
+
+ /**
* Marks this node as sanitized so its content are sent on {@link
* android.service.autofill.AutoFillService#onFillRequest(android.app.assist.AssistStructure,
* Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)}.
diff --git a/core/java/android/view/autofill/AutoFillType.java b/core/java/android/view/autofill/AutoFillType.java
index 017f7f8ca3e8..5d85bfdac095 100644
--- a/core/java/android/view/autofill/AutoFillType.java
+++ b/core/java/android/view/autofill/AutoFillType.java
@@ -44,8 +44,6 @@ public final class AutoFillType implements Parcelable {
private static final int TYPE_TEXT = 1;
private static final int TYPE_TOGGLE = 2;
- // TODO(b/33197203): make sure it works with Spinners and/or add a new type for them
- // (since they're often used for credit card selection)
private static final int TYPE_LIST = 3;
// TODO(b/33197203): add others, like date picker? That would be trick, because they're set as:
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 2cfefba10c57..0b3cff10d17e 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -34,6 +34,7 @@ import android.view.ViewHierarchyEncoder;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.autofill.AutoFillManager;
/**
* An AdapterView is a view whose children are determined by an {@link Adapter}.
@@ -914,6 +915,11 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
dispatchOnItemSelected();
}
}
+ // Always notify AutoFillManager - it will return right away if auto-fill is disabled.
+ final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+ if (afm != null) {
+ afm.valueChanged(this);
+ }
}
private void dispatchOnItemSelected() {
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index 76b38131477d..49253eb609cf 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -430,6 +430,15 @@ public class RadioGroup extends LinearLayout {
@Override
public AutoFillValue getAutoFillValue() {
- return isEnabled() ? AutoFillValue.forList(getCheckedRadioButtonId()) : null;
+ if (!isEnabled()) return null;
+
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getId() == mCheckedId) {
+ return AutoFillValue.forList(i);
+ }
+ }
+ return null;
}
}
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 28cc693f3b31..50c016bb4c3a 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -41,9 +41,12 @@ import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStructure;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.autofill.AutoFillType;
+import android.view.autofill.AutoFillValue;
import android.widget.PopupWindow.OnDismissListener;
import com.android.internal.R;
@@ -784,6 +787,7 @@ public class Spinner extends AbsSpinner implements OnClickListener {
return handled;
}
+ @Override
public void onClick(DialogInterface dialog, int which) {
setSelection(which);
dialog.dismiss();
@@ -912,6 +916,42 @@ public class Spinner extends AbsSpinner implements OnClickListener {
return super.onResolvePointerIcon(event, pointerIndex);
}
+ // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+
+ @Override
+ public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
+ super.onProvideAutoFillStructure(structure, flags);
+ // TODO(b/33197203): implement sanitization so initial value is only sanitized when coming
+ // from resources.
+
+ final int count = getAdapter().getCount();
+ if (count > 0) {
+ final String[] options = new String[count];
+ for (int i = 0; i < count; i++) {
+ options[i] = getAdapter().getItem(i).toString();
+ }
+ structure.setAutoFillOptions(options);
+ }
+ }
+
+ @Override
+ public void autoFill(AutoFillValue value) {
+ if (!isEnabled()) return;
+
+ final int position = value.getListValue();
+ setSelection(position);
+ }
+
+ @Override
+ public AutoFillType getAutoFillType() {
+ return AutoFillType.forList();
+ }
+
+ @Override
+ public AutoFillValue getAutoFillValue() {
+ return isEnabled() ? AutoFillValue.forList(getSelectedItemPosition()) : null;
+ }
+
static class SavedState extends AbsSpinner.SavedState {
boolean showDropdown;