summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt24
-rw-r--r--api/system-current.txt24
-rw-r--r--core/java/android/app/AssistStructure.java444
-rw-r--r--core/java/android/view/View.java140
-rw-r--r--core/java/android/view/ViewAssistStructure.java43
-rw-r--r--core/java/android/view/ViewGroup.java27
-rw-r--r--core/java/android/widget/Switch.java4
-rw-r--r--core/java/android/widget/TextView.java4
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java10
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java1
10 files changed, 507 insertions, 214 deletions
diff --git a/api/current.txt b/api/current.txt
index ce6bbfa..6890968 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -34511,6 +34511,7 @@ package android.view {
method public boolean dispatchNestedPreScroll(int, int, int[], int[]);
method public boolean dispatchNestedScroll(int, int, int, int, int[]);
method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+ method public void dispatchProvideAssistStructure(android.view.ViewAssistStructure);
method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
method protected void dispatchSetActivated(boolean);
@@ -34767,7 +34768,8 @@ package android.view {
method protected void onMeasure(int, int);
method protected void onOverScrolled(int, int, boolean, boolean);
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
- method public void onProvideAssistStructure(android.view.ViewAssistStructure, android.os.Bundle);
+ method public void onProvideAssistStructure(android.view.ViewAssistStructure);
+ method public void onProvideVirtualAssistStructure(android.view.ViewAssistStructure);
method protected void onRestoreInstanceState(android.os.Parcelable);
method public void onRtlPropertiesChanged(int);
method protected android.os.Parcelable onSaveInstanceState();
@@ -35177,14 +35179,34 @@ package android.view {
public abstract class ViewAssistStructure {
ctor public ViewAssistStructure();
+ method public abstract void clearExtras();
+ method public abstract android.os.Bundle editExtras();
+ method public abstract int getChildCount();
method public abstract java.lang.CharSequence getHint();
method public abstract java.lang.CharSequence getText();
method public abstract int getTextSelectionEnd();
method public abstract int getTextSelectionStart();
+ method public abstract android.view.ViewAssistStructure newChild(int);
+ method public abstract void setAccessibilityFocused(boolean);
+ method public abstract void setActivated(boolean);
+ method public abstract void setCheckable(boolean);
+ method public abstract void setChecked(boolean);
+ method public abstract void setChildCount(int);
+ method public abstract void setClassName(java.lang.String);
+ method public abstract void setClickable(boolean);
+ method public abstract void setContentDescription(java.lang.CharSequence);
+ method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setEnabled(boolean);
+ method public abstract void setFocusable(boolean);
+ method public abstract void setFocused(boolean);
method public abstract void setHint(java.lang.CharSequence);
+ method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
+ method public abstract void setLongClickable(boolean);
+ method public abstract void setSelected(boolean);
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextPaint(android.text.TextPaint);
+ method public abstract void setVisibility(int);
}
public class ViewConfiguration {
diff --git a/api/system-current.txt b/api/system-current.txt
index 6053603..b5b7c05 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -37053,6 +37053,7 @@ package android.view {
method public boolean dispatchNestedPreScroll(int, int, int[], int[]);
method public boolean dispatchNestedScroll(int, int, int, int, int[]);
method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+ method public void dispatchProvideAssistStructure(android.view.ViewAssistStructure);
method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
method protected void dispatchSetActivated(boolean);
@@ -37309,7 +37310,8 @@ package android.view {
method protected void onMeasure(int, int);
method protected void onOverScrolled(int, int, boolean, boolean);
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
- method public void onProvideAssistStructure(android.view.ViewAssistStructure, android.os.Bundle);
+ method public void onProvideAssistStructure(android.view.ViewAssistStructure);
+ method public void onProvideVirtualAssistStructure(android.view.ViewAssistStructure);
method protected void onRestoreInstanceState(android.os.Parcelable);
method public void onRtlPropertiesChanged(int);
method protected android.os.Parcelable onSaveInstanceState();
@@ -37719,14 +37721,34 @@ package android.view {
public abstract class ViewAssistStructure {
ctor public ViewAssistStructure();
+ method public abstract void clearExtras();
+ method public abstract android.os.Bundle editExtras();
+ method public abstract int getChildCount();
method public abstract java.lang.CharSequence getHint();
method public abstract java.lang.CharSequence getText();
method public abstract int getTextSelectionEnd();
method public abstract int getTextSelectionStart();
+ method public abstract android.view.ViewAssistStructure newChild(int);
+ method public abstract void setAccessibilityFocused(boolean);
+ method public abstract void setActivated(boolean);
+ method public abstract void setCheckable(boolean);
+ method public abstract void setChecked(boolean);
+ method public abstract void setChildCount(int);
+ method public abstract void setClassName(java.lang.String);
+ method public abstract void setClickable(boolean);
+ method public abstract void setContentDescription(java.lang.CharSequence);
+ method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setEnabled(boolean);
+ method public abstract void setFocusable(boolean);
+ method public abstract void setFocused(boolean);
method public abstract void setHint(java.lang.CharSequence);
+ method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
+ method public abstract void setLongClickable(boolean);
+ method public abstract void setSelected(boolean);
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextPaint(android.text.TextPaint);
+ method public abstract void setVisibility(int);
}
public class ViewConfiguration {
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
index c435ccb..e31c821 100644
--- a/core/java/android/app/AssistStructure.java
+++ b/core/java/android/app/AssistStructure.java
@@ -17,7 +17,6 @@
package android.app;
import android.content.ComponentName;
-import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
@@ -31,10 +30,8 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewAssistStructure;
-import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
-import android.widget.Checkable;
import java.util.ArrayList;
@@ -56,107 +53,22 @@ final public class AssistStructure implements Parcelable {
final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
- ViewAssistStructureImpl mTmpViewAssistStructureImpl = new ViewAssistStructureImpl();
- Bundle mTmpExtras = new Bundle();
+ Rect mTmpRect = new Rect();
- final static class ViewAssistStructureImpl extends ViewAssistStructure {
+ final static class ViewNodeText {
CharSequence mText;
- int mTextSelectionStart = -1;
- int mTextSelectionEnd = -1;
- int mTextColor = ViewNode.TEXT_COLOR_UNDEFINED;
- int mTextBackgroundColor = ViewNode.TEXT_COLOR_UNDEFINED;
- float mTextSize = 0;
- int mTextStyle = 0;
- CharSequence mHint;
-
- @Override
- public void setText(CharSequence text) {
- mText = text;
- mTextSelectionStart = mTextSelectionEnd = -1;
- }
-
- @Override
- public void setText(CharSequence text, int selectionStart, int selectionEnd) {
- mText = text;
- mTextSelectionStart = selectionStart;
- mTextSelectionEnd = selectionEnd;
- }
-
- @Override
- public void setTextPaint(TextPaint paint) {
- mTextColor = paint.getColor();
- mTextBackgroundColor = paint.bgColor;
- mTextSize = paint.getTextSize();
- mTextStyle = 0;
- Typeface tf = paint.getTypeface();
- if (tf != null) {
- if (tf.isBold()) {
- mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
- }
- if (tf.isItalic()) {
- mTextStyle |= ViewNode.TEXT_STYLE_ITALIC;
- }
- }
- int pflags = paint.getFlags();
- if ((pflags& Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
- mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
- }
- if ((pflags& Paint.UNDERLINE_TEXT_FLAG) != 0) {
- mTextStyle |= ViewNode.TEXT_STYLE_UNDERLINE;
- }
- if ((pflags& Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
- mTextStyle |= ViewNode.TEXT_STYLE_STRIKE_THRU;
- }
- }
-
- @Override
- public void setHint(CharSequence hint) {
- mHint = hint;
- }
-
- @Override
- public CharSequence getText() {
- return mText;
- }
-
- @Override
- public int getTextSelectionStart() {
- return mTextSelectionStart;
- }
-
- @Override
- public int getTextSelectionEnd() {
- return mTextSelectionEnd;
- }
-
- @Override
- public CharSequence getHint() {
- return mHint;
- }
- }
-
- final static class ViewNodeTextImpl {
- final CharSequence mText;
- final int mTextSelectionStart;
- final int mTextSelectionEnd;
+ int mTextSelectionStart;
+ int mTextSelectionEnd;
int mTextColor;
int mTextBackgroundColor;
float mTextSize;
int mTextStyle;
- final String mHint;
+ String mHint;
- ViewNodeTextImpl(ViewAssistStructureImpl data) {
- mText = data.mText;
- mTextSelectionStart = data.mTextSelectionStart;
- mTextSelectionEnd = data.mTextSelectionEnd;
- mTextColor = data.mTextColor;
- mTextBackgroundColor = data.mTextBackgroundColor;
- mTextSize = data.mTextSize;
- mTextStyle = data.mTextStyle;
- mHint = data.mHint != null ? data.mHint.toString() : null;
+ ViewNodeText() {
}
- ViewNodeTextImpl(Parcel in) {
+ ViewNodeText(Parcel in) {
mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mTextSelectionStart = in.readInt();
mTextSelectionEnd = in.readInt();
@@ -199,7 +111,9 @@ final public class AssistStructure implements Parcelable {
mWidth = rect.width();
mHeight = rect.height();
mTitle = root.getTitle();
- mRoot = new ViewNode(assist, view);
+ mRoot = new ViewNode();
+ ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot);
+ view.dispatchProvideAssistStructure(builder);
}
WindowNode(Parcel in, PooledStringReader preader) {
@@ -260,16 +174,16 @@ final public class AssistStructure implements Parcelable {
public static final int TEXT_STYLE_UNDERLINE = 1<<2;
public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
- final int mId;
- final String mIdPackage;
- final String mIdType;
- final String mIdEntry;
- final int mX;
- final int mY;
- final int mScrollX;
- final int mScrollY;
- final int mWidth;
- final int mHeight;
+ int mId;
+ String mIdPackage;
+ String mIdType;
+ String mIdEntry;
+ int mX;
+ int mY;
+ int mScrollX;
+ int mScrollY;
+ int mWidth;
+ int mHeight;
static final int FLAGS_DISABLED = 0x00000001;
static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
@@ -283,104 +197,17 @@ final public class AssistStructure implements Parcelable {
static final int FLAGS_CLICKABLE = 0x00004000;
static final int FLAGS_LONG_CLICKABLE = 0x00200000;
- final int mFlags;
+ int mFlags;
- final String mClassName;
- final CharSequence mContentDescription;
+ String mClassName;
+ CharSequence mContentDescription;
- final ViewNodeTextImpl mText;
- final Bundle mExtras;
+ ViewNodeText mText;
+ Bundle mExtras;
- final ViewNode[] mChildren;
+ ViewNode[] mChildren;
- ViewNode(AssistStructure assistStructure, View view) {
- mId = view.getId();
- if (mId > 0 && (mId&0xff000000) != 0 && (mId&0x00ff0000) != 0
- && (mId&0x0000ffff) != 0) {
- String pkg, type, entry;
- try {
- Resources res = view.getResources();
- entry = res.getResourceEntryName(mId);
- type = res.getResourceTypeName(mId);
- pkg = res.getResourcePackageName(mId);
- } catch (Resources.NotFoundException e) {
- entry = type = pkg = null;
- }
- mIdPackage = pkg;
- mIdType = type;
- mIdEntry = entry;
- } else {
- mIdPackage = mIdType = mIdEntry = null;
- }
- mX = view.getLeft();
- mY = view.getTop();
- mScrollX = view.getScrollX();
- mScrollY = view.getScrollY();
- mWidth = view.getWidth();
- mHeight = view.getHeight();
- int flags = view.getVisibility();
- if (!view.isEnabled()) {
- flags |= FLAGS_DISABLED;
- }
- if (!view.isClickable()) {
- flags |= FLAGS_CLICKABLE;
- }
- if (!view.isFocusable()) {
- flags |= FLAGS_FOCUSABLE;
- }
- if (!view.isFocused()) {
- flags |= FLAGS_FOCUSED;
- }
- if (!view.isAccessibilityFocused()) {
- flags |= FLAGS_ACCESSIBILITY_FOCUSED;
- }
- if (!view.isSelected()) {
- flags |= FLAGS_SELECTED;
- }
- if (!view.isActivated()) {
- flags |= FLAGS_ACTIVATED;
- }
- if (!view.isLongClickable()) {
- flags |= FLAGS_LONG_CLICKABLE;
- }
- if (view instanceof Checkable) {
- flags |= FLAGS_CHECKABLE;
- if (((Checkable)view).isChecked()) {
- flags |= FLAGS_CHECKED;
- }
- }
- mFlags = flags;
- mClassName = view.getAccessibilityClassName().toString();
- mContentDescription = view.getContentDescription();
- final ViewAssistStructureImpl viewData = assistStructure.mTmpViewAssistStructureImpl;
- final Bundle extras = assistStructure.mTmpExtras;
- view.onProvideAssistStructure(viewData, extras);
- if (viewData.mText != null || viewData.mHint != null) {
- mText = new ViewNodeTextImpl(viewData);
- assistStructure.mTmpViewAssistStructureImpl = new ViewAssistStructureImpl();
- } else {
- mText = null;
- }
- if (!extras.isEmpty()) {
- mExtras = extras;
- assistStructure.mTmpExtras = new Bundle();
- } else {
- mExtras = null;
- }
- if (view instanceof ViewGroup) {
- ViewGroup vg = (ViewGroup)view;
- final int NCHILDREN = vg.getChildCount();
- if (NCHILDREN > 0) {
- mChildren = new ViewNode[NCHILDREN];
- for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNode(assistStructure, vg.getChildAt(i));
- }
- } else {
- mChildren = null;
- }
- } else {
- mChildren = null;
- }
+ ViewNode() {
}
ViewNode(Parcel in, PooledStringReader preader) {
@@ -406,7 +233,7 @@ final public class AssistStructure implements Parcelable {
mClassName = preader.readString();
mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
if (in.readInt() != 0) {
- mText = new ViewNodeTextImpl(in);
+ mText = new ViewNodeText(in);
} else {
mText = null;
}
@@ -595,6 +422,221 @@ final public class AssistStructure implements Parcelable {
}
}
+ static class ViewNodeBuilder extends ViewAssistStructure {
+ final AssistStructure mAssist;
+ final ViewNode mNode;
+
+ ViewNodeBuilder(AssistStructure assist, ViewNode node) {
+ mAssist = assist;
+ mNode = node;
+ }
+
+ @Override
+ public void setId(int id, String packageName, String typeName, String entryName) {
+ mNode.mId = id;
+ mNode.mIdPackage = packageName;
+ mNode.mIdType = typeName;
+ mNode.mIdEntry = entryName;
+ }
+
+ @Override
+ public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
+ mNode.mX = left;
+ mNode.mY = top;
+ mNode.mScrollX = scrollX;
+ mNode.mScrollY = scrollY;
+ mNode.mWidth = width;
+ mNode.mHeight = height;
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
+ }
+
+ @Override
+ public void setEnabled(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_DISABLED)
+ | (state ? 0 : ViewNode.FLAGS_DISABLED);
+ }
+
+ @Override
+ public void setClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CLICKABLE)
+ | (state ? ViewNode.FLAGS_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setLongClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_LONG_CLICKABLE)
+ | (state ? ViewNode.FLAGS_LONG_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setFocusable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE)
+ | (state ? ViewNode.FLAGS_FOCUSABLE : 0);
+ }
+
+ @Override
+ public void setFocused(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSED)
+ | (state ? ViewNode.FLAGS_FOCUSED : 0);
+ }
+
+ @Override
+ public void setAccessibilityFocused(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACCESSIBILITY_FOCUSED)
+ | (state ? ViewNode.FLAGS_ACCESSIBILITY_FOCUSED : 0);
+ }
+
+ @Override
+ public void setCheckable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKABLE)
+ | (state ? ViewNode.FLAGS_CHECKABLE : 0);
+ }
+
+ @Override
+ public void setChecked(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKED)
+ | (state ? ViewNode.FLAGS_CHECKED : 0);
+ }
+
+ @Override
+ public void setSelected(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_SELECTED)
+ | (state ? ViewNode.FLAGS_SELECTED : 0);
+ }
+
+ @Override
+ public void setActivated(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACTIVATED)
+ | (state ? ViewNode.FLAGS_ACTIVATED : 0);
+ }
+
+ @Override
+ public void setClassName(String className) {
+ mNode.mClassName = className;
+ }
+
+ @Override
+ public void setContentDescription(CharSequence contentDescription) {
+ mNode.mContentDescription = contentDescription;
+ }
+
+ private final ViewNodeText getNodeText() {
+ if (mNode.mText != null) {
+ return mNode.mText;
+ }
+ mNode.mText = new ViewNodeText();
+ return mNode.mText;
+ }
+
+ @Override
+ public void setText(CharSequence text) {
+ ViewNodeText t = getNodeText();
+ t.mText = text;
+ t.mTextSelectionStart = t.mTextSelectionEnd = -1;
+ }
+
+ @Override
+ public void setText(CharSequence text, int selectionStart, int selectionEnd) {
+ ViewNodeText t = getNodeText();
+ t.mText = text;
+ t.mTextSelectionStart = selectionStart;
+ t.mTextSelectionEnd = selectionEnd;
+ }
+
+ @Override
+ public void setTextPaint(TextPaint paint) {
+ ViewNodeText t = getNodeText();
+ t.mTextColor = paint.getColor();
+ t.mTextBackgroundColor = paint.bgColor;
+ t.mTextSize = paint.getTextSize();
+ t.mTextStyle = 0;
+ Typeface tf = paint.getTypeface();
+ if (tf != null) {
+ if (tf.isBold()) {
+ t.mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
+ }
+ if (tf.isItalic()) {
+ t.mTextStyle |= ViewNode.TEXT_STYLE_ITALIC;
+ }
+ }
+ int pflags = paint.getFlags();
+ if ((pflags& Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
+ t.mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
+ }
+ if ((pflags& Paint.UNDERLINE_TEXT_FLAG) != 0) {
+ t.mTextStyle |= ViewNode.TEXT_STYLE_UNDERLINE;
+ }
+ if ((pflags& Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
+ t.mTextStyle |= ViewNode.TEXT_STYLE_STRIKE_THRU;
+ }
+ }
+
+ @Override
+ public void setHint(CharSequence hint) {
+ getNodeText().mHint = hint != null ? hint.toString() : null;
+ }
+
+ @Override
+ public CharSequence getText() {
+ return mNode.mText != null ? mNode.mText.mText : null;
+ }
+
+ @Override
+ public int getTextSelectionStart() {
+ return mNode.mText != null ? mNode.mText.mTextSelectionStart : -1;
+ }
+
+ @Override
+ public int getTextSelectionEnd() {
+ return mNode.mText != null ? mNode.mText.mTextSelectionEnd : -1;
+ }
+
+ @Override
+ public CharSequence getHint() {
+ return mNode.mText != null ? mNode.mText.mHint : null;
+ }
+
+ @Override
+ public Bundle editExtras() {
+ if (mNode.mExtras != null) {
+ return mNode.mExtras;
+ }
+ mNode.mExtras = new Bundle();
+ return mNode.mExtras;
+ }
+
+ @Override
+ public void clearExtras() {
+ mNode.mExtras = null;
+ }
+
+ @Override
+ public void setChildCount(int num) {
+ mNode.mChildren = new ViewNode[num];
+ }
+
+ @Override
+ public int getChildCount() {
+ return mNode.mChildren != null ? mNode.mChildren.length : 0;
+ }
+
+ @Override
+ public ViewAssistStructure newChild(int index) {
+ ViewNode node = new ViewNode();
+ mNode.mChildren[index] = node;
+ return new ViewNodeBuilder(mAssist, node);
+ }
+
+ @Override
+ public Rect getTempRect() {
+ return mAssist.mTmpRect;
+ }
+ }
+
AssistStructure(Activity activity) {
mActivityComponent = activity.getComponentName();
ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a69384a..c0e253b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -91,6 +91,7 @@ import android.view.animation.Transformation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.widget.Checkable;
import android.widget.ScrollBarDrawable;
import static android.os.Build.VERSION_CODES.*;
@@ -5676,10 +5677,143 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Called when assist structure is being retrieved from a view as part of
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
- * @param structure Additional standard structured view structure to supply.
- * @param extras Non-standard extensions.
+ * @param structure Fill in with structured view data. The default implementation
+ * fills in all data that can be inferred from the view itself.
+ */
+ public void onProvideAssistStructure(ViewAssistStructure structure) {
+ final int id = mID;
+ if (id > 0 && (id&0xff000000) != 0 && (id&0x00ff0000) != 0
+ && (id&0x0000ffff) != 0) {
+ String pkg, type, entry;
+ try {
+ final Resources res = getResources();
+ entry = res.getResourceEntryName(id);
+ type = res.getResourceTypeName(id);
+ pkg = res.getResourcePackageName(id);
+ } catch (Resources.NotFoundException e) {
+ entry = type = pkg = null;
+ }
+ structure.setId(id, pkg, type, entry);
+ } else {
+ structure.setId(id, null, null, null);
+ }
+ structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight-mLeft, mBottom-mTop);
+ structure.setVisibility(getVisibility());
+ structure.setEnabled(isEnabled());
+ if (isClickable()) {
+ structure.setClickable(true);
+ }
+ if (isFocusable()) {
+ structure.setFocusable(true);
+ }
+ if (isFocused()) {
+ structure.setFocused(true);
+ }
+ if (isAccessibilityFocused()) {
+ structure.setAccessibilityFocused(true);
+ }
+ if (isSelected()) {
+ structure.setSelected(true);
+ }
+ if (isActivated()) {
+ structure.setActivated(true);
+ }
+ if (isLongClickable()) {
+ structure.setLongClickable(true);
+ }
+ if (this instanceof Checkable) {
+ structure.setCheckable(true);
+ if (((Checkable)this).isChecked()) {
+ structure.setChecked(true);
+ }
+ }
+ structure.setClassName(getAccessibilityClassName().toString());
+ structure.setContentDescription(getContentDescription());
+ }
+
+ /**
+ * Called when assist structure is being retrieved from a view as part of
+ * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to
+ * generate additional virtual structure under this view. The defaullt implementation
+ * uses {@link #getAccessibilityNodeProvider()} to try to generate this from the
+ * view's virtual accessibility nodes, if any. You can override this for a more
+ * optimal implementation providing this data.
+ */
+ public void onProvideVirtualAssistStructure(ViewAssistStructure structure) {
+ AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+ if (provider != null) {
+ AccessibilityNodeInfo info = createAccessibilityNodeInfo();
+ Log.i("View", "Provider of " + this + ": children=" + info.getChildCount());
+ structure.setChildCount(1);
+ ViewAssistStructure root = structure.newChild(0);
+ populateVirtualAssistStructure(root, provider, info);
+ info.recycle();
+ }
+ }
+
+ private void populateVirtualAssistStructure(ViewAssistStructure structure,
+ AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
+ structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
+ null, null, null);
+ Rect rect = structure.getTempRect();
+ info.getBoundsInParent(rect);
+ structure.setDimens(rect.left, rect.top, 0, 0, rect.width(), rect.height());
+ structure.setVisibility(VISIBLE);
+ structure.setEnabled(info.isEnabled());
+ if (info.isClickable()) {
+ structure.setClickable(true);
+ }
+ if (info.isFocusable()) {
+ structure.setFocusable(true);
+ }
+ if (info.isFocused()) {
+ structure.setFocused(true);
+ }
+ if (info.isAccessibilityFocused()) {
+ structure.setAccessibilityFocused(true);
+ }
+ if (info.isSelected()) {
+ structure.setSelected(true);
+ }
+ if (info.isLongClickable()) {
+ structure.setLongClickable(true);
+ }
+ if (info.isCheckable()) {
+ structure.setCheckable(true);
+ if (info.isChecked()) {
+ structure.setChecked(true);
+ }
+ }
+ CharSequence cname = info.getClassName();
+ structure.setClassName(cname != null ? cname.toString() : null);
+ structure.setContentDescription(info.getContentDescription());
+ Log.i("View", "vassist " + cname + " @ " + rect.toShortString()
+ + " text=" + info.getText() + " cd=" + info.getContentDescription());
+ if (info.getText() != null || info.getError() != null) {
+ structure.setText(info.getText(), info.getTextSelectionStart(),
+ info.getTextSelectionEnd());
+ }
+ final int NCHILDREN = info.getChildCount();
+ if (NCHILDREN > 0) {
+ structure.setChildCount(NCHILDREN);
+ for (int i=0; i<NCHILDREN; i++) {
+ AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo(
+ AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
+ ViewAssistStructure child = structure.newChild(i);
+ populateVirtualAssistStructure(child, provider, cinfo);
+ cinfo.recycle();
+ }
+ }
+ }
+
+ /**
+ * Dispatch creation of {@link ViewAssistStructure} down the hierarchy. The default
+ * implementation calls {@link #onProvideAssistStructure} and
+ * {@link #onProvideVirtualAssistStructure}.
*/
- public void onProvideAssistStructure(ViewAssistStructure structure, Bundle extras) {
+ public void dispatchProvideAssistStructure(ViewAssistStructure structure) {
+ onProvideAssistStructure(structure);
+ onProvideVirtualAssistStructure(structure);
}
/**
diff --git a/core/java/android/view/ViewAssistStructure.java b/core/java/android/view/ViewAssistStructure.java
index 5132bb9..c05ed6f 100644
--- a/core/java/android/view/ViewAssistStructure.java
+++ b/core/java/android/view/ViewAssistStructure.java
@@ -16,6 +16,8 @@
package android.view;
+import android.graphics.Rect;
+import android.os.Bundle;
import android.text.TextPaint;
/**
@@ -23,6 +25,37 @@ import android.text.TextPaint;
* View.onProvideAssistStructure}.
*/
public abstract class ViewAssistStructure {
+ public abstract void setId(int id, String packageName, String typeName, String entryName);
+
+ public abstract void setDimens(int left, int top, int scrollX, int scrollY, int width,
+ int height);
+
+ public abstract void setVisibility(int visibility);
+
+ public abstract void setEnabled(boolean state);
+
+ public abstract void setClickable(boolean state);
+
+ public abstract void setLongClickable(boolean state);
+
+ public abstract void setFocusable(boolean state);
+
+ public abstract void setFocused(boolean state);
+
+ public abstract void setAccessibilityFocused(boolean state);
+
+ public abstract void setCheckable(boolean state);
+
+ public abstract void setChecked(boolean state);
+
+ public abstract void setSelected(boolean state);
+
+ public abstract void setActivated(boolean state);
+
+ public abstract void setClassName(String className);
+
+ public abstract void setContentDescription(CharSequence contentDescription);
+
public abstract void setText(CharSequence text);
public abstract void setText(CharSequence text, int selectionStart, int selectionEnd);
public abstract void setTextPaint(TextPaint paint);
@@ -32,4 +65,14 @@ public abstract class ViewAssistStructure {
public abstract int getTextSelectionStart();
public abstract int getTextSelectionEnd();
public abstract CharSequence getHint();
+
+ public abstract Bundle editExtras();
+ public abstract void clearExtras();
+
+ public abstract void setChildCount(int num);
+ public abstract int getChildCount();
+ public abstract ViewAssistStructure newChild(int index);
+
+ /** @hide */
+ public abstract Rect getTempRect();
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 87f3e94..7a84bb0 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2852,6 +2852,33 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return false;
}
+ /**
+ * Dispatch creation of {@link ViewAssistStructure} down the hierarchy. This implementation
+ * adds in all child views of the view group, in addition to calling the default View
+ * implementation.
+ */
+ public void dispatchProvideAssistStructure(ViewAssistStructure structure) {
+ super.dispatchProvideAssistStructure(structure);
+ if (structure.getChildCount() == 0) {
+ final int childrenCount = getChildCount();
+ if (childrenCount > 0) {
+ structure.setChildCount(childrenCount);
+ final ArrayList<View> preorderedList = buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && isChildrenDrawingOrderEnabled();
+ final View[] children = mChildren;
+ for (int i=0; i<childrenCount; i++) {
+ final int childIndex = customOrder
+ ? getChildDrawingOrder(childrenCount, i) : i;
+ final View child = (preorderedList == null)
+ ? children[childIndex] : preorderedList.get(childIndex);
+ ViewAssistStructure cstructure = structure.newChild(i);
+ child.dispatchProvideAssistStructure(cstructure);
+ }
+ }
+ }
+ }
+
/** @hide */
@Override
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index bb290e7..ae779fe 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -1363,8 +1363,8 @@ public class Switch extends CompoundButton {
}
@Override
- public void onProvideAssistStructure(ViewAssistStructure structure, Bundle extras) {
- super.onProvideAssistStructure(structure, extras);
+ public void onProvideAssistStructure(ViewAssistStructure structure) {
+ super.onProvideAssistStructure(structure);
CharSequence switchText = isChecked() ? mTextOn : mTextOff;
if (!TextUtils.isEmpty(switchText)) {
CharSequence oldText = structure.getText();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 718ef93..877647d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8576,8 +8576,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
- public void onProvideAssistStructure(ViewAssistStructure structure, Bundle extras) {
- super.onProvideAssistStructure(structure, extras);
+ public void onProvideAssistStructure(ViewAssistStructure structure) {
+ super.onProvideAssistStructure(structure);
final boolean isPassword = hasPasswordTransformationMethod();
if (!isPassword) {
structure.setText(getText(), getSelectionStart(), getSelectionEnd());
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
index bdc1276..782d112 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -45,6 +45,7 @@ public class AssistVisualizer extends View {
}
public void setAssistStructure(AssistStructure as) {
+ mAssistStructure.dump();
mAssistStructure = as;
mTextRects.clear();
final int N = as.getWindowNodeCount();
@@ -55,6 +56,7 @@ public class AssistVisualizer extends View {
windowNode.getTop());
}
}
+ Log.d(TAG, "Building text rects in " + this + ": found " + mTextRects.size());
invalidate();
}
@@ -69,10 +71,11 @@ public class AssistVisualizer extends View {
}
int left = parentLeft+root.getLeft();
int top = parentTop+root.getTop();
- Log.d(TAG, "View " + root.getClassName() + ": " + left + ", " + top);
- if (root.getText() != null) {
+ if (root.getText() != null || root.getContentDescription() != null) {
Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight());
- Log.d(TAG, "Text Rect " + r.toShortString() + ": " + root.getText());
+ Log.d(TAG, "View " + root.getClassName() + " " + left + "," + top + " tr "
+ + r.toShortString() + ": "
+ + (root.getText() != null ? root.getText() : root.getContentDescription()));
mTextRects.add(r);
}
final int N = root.getChildCount();
@@ -91,6 +94,7 @@ public class AssistVisualizer extends View {
super.onDraw(canvas);
getLocationOnScreen(mTmpLocation);
final int N = mTextRects.size();
+ Log.d(TAG, "Drawing text rects in " + this + ": found " + mTextRects.size());
for (int i=0; i<N; i++) {
Rect r = mTextRects.get(i);
canvas.drawRect(r.left-mTmpLocation[0], r.top-mTmpLocation[1],
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index bc18ca9..ec727c4 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -142,7 +142,6 @@ public class MainInteractionSession extends VoiceInteractionSession
if (assistContext != null) {
mAssistStructure = AssistStructure.getAssistStructure(assistContext);
if (mAssistStructure != null) {
- mAssistStructure.dump();
if (mAssistVisualizer != null) {
mAssistVisualizer.setAssistStructure(mAssistStructure);
}