summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt6
-rw-r--r--api/system-current.txt6
-rw-r--r--core/java/android/app/assist/AssistStructure.java286
-rw-r--r--core/java/android/view/View.java21
-rw-r--r--core/java/android/view/ViewStructure.java23
-rw-r--r--tests/VoiceInteraction/res/layout/voice_interaction_session.xml41
-rw-r--r--tests/VoiceInteraction/res/values/strings.xml2
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java103
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java29
9 files changed, 404 insertions, 113 deletions
diff --git a/api/current.txt b/api/current.txt
index cd5c0a8..3f425a2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5846,10 +5846,12 @@ package android.app.assist {
}
public static class AssistStructure.ViewNode {
+ method public float getAlpha();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount();
method public java.lang.String getClassName();
method public java.lang.CharSequence getContentDescription();
+ method public float getElevation();
method public android.os.Bundle getExtras();
method public int getHeight();
method public java.lang.String getHint();
@@ -5868,6 +5870,7 @@ package android.app.assist {
method public float getTextSize();
method public int getTextStyle();
method public int getTop();
+ method public android.graphics.Matrix getTransformation();
method public int getVisibility();
method public int getWidth();
method public boolean isAccessibilityFocused();
@@ -36962,6 +36965,7 @@ package android.view {
method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
+ method public abstract void setAlpha(float);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -36970,6 +36974,7 @@ package android.view {
method public abstract void setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setElevation(float);
method public abstract void setEnabled(boolean);
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
@@ -36980,6 +36985,7 @@ package android.view {
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, int, int);
+ method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 574f0c8..33c7a1b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5964,10 +5964,12 @@ package android.app.assist {
}
public static class AssistStructure.ViewNode {
+ method public float getAlpha();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount();
method public java.lang.String getClassName();
method public java.lang.CharSequence getContentDescription();
+ method public float getElevation();
method public android.os.Bundle getExtras();
method public int getHeight();
method public java.lang.String getHint();
@@ -5986,6 +5988,7 @@ package android.app.assist {
method public float getTextSize();
method public int getTextStyle();
method public int getTop();
+ method public android.graphics.Matrix getTransformation();
method public int getVisibility();
method public int getWidth();
method public boolean isAccessibilityFocused();
@@ -39243,6 +39246,7 @@ package android.view {
method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
+ method public abstract void setAlpha(float);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -39251,6 +39255,7 @@ package android.view {
method public abstract void setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setElevation(float);
method public abstract void setEnabled(boolean);
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
@@ -39261,6 +39266,7 @@ package android.view {
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, int, int);
+ method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
}
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 284dfd6..3429b6e 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2,6 +2,7 @@ package android.app.assist;
import android.app.Activity;
import android.content.ComponentName;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Bundle;
@@ -128,24 +129,24 @@ public class AssistStructure implements Parcelable {
view.dispatchProvideStructure(builder);
}
- WindowNode(Parcel in, PooledStringReader preader) {
+ WindowNode(Parcel in, PooledStringReader preader, float[] tmpMatrix) {
mX = in.readInt();
mY = in.readInt();
mWidth = in.readInt();
mHeight = in.readInt();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mDisplayId = in.readInt();
- mRoot = new ViewNode(in, preader);
+ mRoot = new ViewNode(in, preader, tmpMatrix);
}
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+ int writeToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
out.writeInt(mX);
out.writeInt(mY);
out.writeInt(mWidth);
out.writeInt(mHeight);
TextUtils.writeToParcel(mTitle, out, 0);
out.writeInt(mDisplayId);
- mRoot.writeToParcel(out, pwriter);
+ return mRoot.writeToParcel(out, pwriter, tmpMatrix);
}
/**
@@ -216,7 +217,7 @@ public class AssistStructure implements Parcelable {
public static final int TEXT_STYLE_UNDERLINE = 1<<2;
public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
- int mId;
+ int mId = View.NO_ID;
String mIdPackage;
String mIdType;
String mIdEntry;
@@ -226,20 +227,35 @@ public class AssistStructure implements Parcelable {
int mScrollY;
int mWidth;
int mHeight;
+ Matrix mMatrix;
+ float mElevation;
+ float mAlpha = 1.0f;
static final int FLAGS_DISABLED = 0x00000001;
static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
static final int FLAGS_FOCUSABLE = 0x00000010;
static final int FLAGS_FOCUSED = 0x00000020;
- static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
static final int FLAGS_SELECTED = 0x00000040;
static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
- static final int FLAGS_ACTIVATED = 0x40000000;
static final int FLAGS_CHECKABLE = 0x00000100;
static final int FLAGS_CHECKED = 0x00000200;
- static final int FLAGS_CLICKABLE = 0x00004000;
- static final int FLAGS_LONG_CLICKABLE = 0x00200000;
- static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000;
+ static final int FLAGS_CLICKABLE = 0x00000400;
+ static final int FLAGS_LONG_CLICKABLE = 0x00000800;
+ static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x00001000;
+ static final int FLAGS_ACTIVATED = 0x00002000;
+ static final int FLAGS_CONTEXT_CLICKABLE = 0x00004000;
+
+ static final int FLAGS_HAS_MATRIX = 0x40000000;
+ static final int FLAGS_HAS_ALPHA = 0x20000000;
+ static final int FLAGS_HAS_ELEVATION = 0x10000000;
+ static final int FLAGS_HAS_SCROLL = 0x08000000;
+ static final int FLAGS_HAS_LARGE_COORDS = 0x04000000;
+ static final int FLAGS_HAS_CONTENT_DESCRIPTION = 0x02000000;
+ static final int FLAGS_HAS_TEXT = 0x01000000;
+ static final int FLAGS_HAS_EXTRAS = 0x00800000;
+ static final int FLAGS_HAS_ID = 0x00400000;
+ static final int FLAGS_HAS_CHILDREN = 0x00200000;
+ static final int FLAGS_ALL_CONTROL = 0xfff00000;
int mFlags;
@@ -254,79 +270,153 @@ public class AssistStructure implements Parcelable {
ViewNode() {
}
- ViewNode(Parcel in, PooledStringReader preader) {
- mId = in.readInt();
- if (mId != 0) {
- mIdEntry = preader.readString();
- if (mIdEntry != null) {
- mIdType = preader.readString();
- mIdPackage = preader.readString();
- } else {
- mIdPackage = mIdType = null;
+ ViewNode(Parcel in, PooledStringReader preader, float[] tmpMatrix) {
+ mClassName = preader.readString();
+ mFlags = in.readInt();
+ final int flags = mFlags;
+ if ((flags&FLAGS_HAS_ID) != 0) {
+ mId = in.readInt();
+ if (mId != 0) {
+ mIdEntry = preader.readString();
+ if (mIdEntry != null) {
+ mIdType = preader.readString();
+ mIdPackage = preader.readString();
+ }
}
+ }
+ if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
+ mX = in.readInt();
+ mY = in.readInt();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
} else {
- mIdPackage = mIdType = mIdEntry = null;
+ int val = in.readInt();
+ mX = val&0x7fff;
+ mY = (val>>16)&0x7fff;
+ val = in.readInt();
+ mWidth = val&0x7fff;
+ mHeight = (val>>16)&0x7fff;
}
- mX = in.readInt();
- mY = in.readInt();
- mScrollX = in.readInt();
- mScrollY = in.readInt();
- mWidth = in.readInt();
- mHeight = in.readInt();
- mFlags = in.readInt();
- mClassName = preader.readString();
- mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- if (in.readInt() != 0) {
+ if ((flags&FLAGS_HAS_SCROLL) != 0) {
+ mScrollX = in.readInt();
+ mScrollY = in.readInt();
+ }
+ if ((flags&FLAGS_HAS_MATRIX) != 0) {
+ mMatrix = new Matrix();
+ in.readFloatArray(tmpMatrix);
+ mMatrix.setValues(tmpMatrix);
+ }
+ if ((flags&FLAGS_HAS_ELEVATION) != 0) {
+ mElevation = in.readFloat();
+ }
+ if ((flags&FLAGS_HAS_ALPHA) != 0) {
+ mAlpha = in.readFloat();
+ }
+ if ((flags&FLAGS_HAS_CONTENT_DESCRIPTION) != 0) {
+ mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ }
+ if ((flags&FLAGS_HAS_TEXT) != 0) {
mText = new ViewNodeText(in);
- } else {
- mText = null;
}
- mExtras = in.readBundle();
- final int NCHILDREN = in.readInt();
- if (NCHILDREN > 0) {
+ if ((flags&FLAGS_HAS_EXTRAS) != 0) {
+ mExtras = in.readBundle();
+ }
+ if ((flags&FLAGS_HAS_CHILDREN) != 0) {
+ final int NCHILDREN = in.readInt();
mChildren = new ViewNode[NCHILDREN];
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNode(in, preader);
+ mChildren[i] = new ViewNode(in, preader, tmpMatrix);
}
- } else {
- mChildren = null;
}
}
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
- out.writeInt(mId);
- if (mId != 0) {
- pwriter.writeString(mIdEntry);
- if (mIdEntry != null) {
- pwriter.writeString(mIdType);
- pwriter.writeString(mIdPackage);
- }
+ int writeToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
+ int flags = mFlags & ~FLAGS_ALL_CONTROL;
+ if (mId != View.NO_ID) {
+ flags |= FLAGS_HAS_ID;
+ }
+ if ((mX&~0x7fff) != 0 || (mY&~0x7fff) != 0
+ || (mWidth&~0x7fff) != 0 | (mHeight&~0x7fff) != 0) {
+ flags |= FLAGS_HAS_LARGE_COORDS;
+ }
+ if (mScrollX != 0 || mScrollY != 0) {
+ flags |= FLAGS_HAS_SCROLL;
+ }
+ if (mMatrix != null) {
+ flags |= FLAGS_HAS_MATRIX;
+ }
+ if (mElevation != 0) {
+ flags |= FLAGS_HAS_ELEVATION;
+ }
+ if (mAlpha != 1.0f) {
+ flags |= FLAGS_HAS_ALPHA;
+ }
+ if (mContentDescription != null) {
+ flags |= FLAGS_HAS_CONTENT_DESCRIPTION;
}
- out.writeInt(mX);
- out.writeInt(mY);
- out.writeInt(mScrollX);
- out.writeInt(mScrollY);
- out.writeInt(mWidth);
- out.writeInt(mHeight);
- out.writeInt(mFlags);
- pwriter.writeString(mClassName);
- TextUtils.writeToParcel(mContentDescription, out, 0);
if (mText != null) {
- out.writeInt(1);
- mText.writeToParcel(out);
- } else {
- out.writeInt(0);
+ flags |= FLAGS_HAS_TEXT;
+ }
+ if (mExtras != null) {
+ flags |= FLAGS_HAS_EXTRAS;
}
- out.writeBundle(mExtras);
if (mChildren != null) {
+ flags |= FLAGS_HAS_CHILDREN;
+ }
+
+ pwriter.writeString(mClassName);
+ out.writeInt(flags);
+ if ((flags&FLAGS_HAS_ID) != 0) {
+ out.writeInt(mId);
+ if (mId != 0) {
+ pwriter.writeString(mIdEntry);
+ if (mIdEntry != null) {
+ pwriter.writeString(mIdType);
+ pwriter.writeString(mIdPackage);
+ }
+ }
+ }
+ if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ } else {
+ out.writeInt((mY<<16) | mX);
+ out.writeInt((mHeight<<16) | mWidth);
+ }
+ if ((flags&FLAGS_HAS_SCROLL) != 0) {
+ out.writeInt(mScrollX);
+ out.writeInt(mScrollY);
+ }
+ if ((flags&FLAGS_HAS_MATRIX) != 0) {
+ mMatrix.getValues(tmpMatrix);
+ out.writeFloatArray(tmpMatrix);
+ }
+ if ((flags&FLAGS_HAS_ELEVATION) != 0) {
+ out.writeFloat(mElevation);
+ }
+ if ((flags&FLAGS_HAS_ALPHA) != 0) {
+ out.writeFloat(mAlpha);
+ }
+ if ((flags&FLAGS_HAS_CONTENT_DESCRIPTION) != 0) {
+ TextUtils.writeToParcel(mContentDescription, out, 0);
+ }
+ if ((flags&FLAGS_HAS_TEXT) != 0) {
+ mText.writeToParcel(out);
+ }
+ if ((flags&FLAGS_HAS_EXTRAS) != 0) {
+ out.writeBundle(mExtras);
+ }
+ int N = 1;
+ if ((flags&FLAGS_HAS_CHILDREN) != 0) {
final int NCHILDREN = mChildren.length;
out.writeInt(NCHILDREN);
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i].writeToParcel(out, pwriter);
+ N += mChildren[i].writeToParcel(out, pwriter, tmpMatrix);
}
- } else {
- out.writeInt(0);
}
+ return N;
}
/**
@@ -408,6 +498,33 @@ public class AssistStructure implements Parcelable {
}
/**
+ * Returns the transformation that has been applied to this view, such as a translation
+ * or scaling. The returned Matrix object is owned by ViewNode; do not modify it.
+ * Returns null if there is no transformation applied to the view.
+ */
+ public Matrix getTransformation() {
+ return mMatrix;
+ }
+
+ /**
+ * Returns the visual elevation of the view, used for shadowing and other visual
+ * characterstics, as set by {@link ViewStructure#setElevation
+ * ViewStructure.setElevation(float)}.
+ */
+ public float getElevation() {
+ return mElevation;
+ }
+
+ /**
+ * Returns the alpha transformation of the view, used to reduce the overall opacity
+ * of the view's contents, as set by {@link ViewStructure#setAlpha
+ * ViewStructure.setAlpha(float)}.
+ */
+ public float getAlpha() {
+ return mAlpha;
+ }
+
+ /**
* Returns the visibility mode of this view, as per
* {@link android.view.View#getVisibility() View.getVisibility()}.
*/
@@ -646,6 +763,25 @@ public class AssistStructure implements Parcelable {
}
@Override
+ public void setTransformation(Matrix matrix) {
+ if (matrix == null) {
+ mNode.mMatrix = null;
+ } else {
+ mNode.mMatrix = new Matrix(matrix);
+ }
+ }
+
+ @Override
+ public void setElevation(float elevation) {
+ mNode.mElevation = elevation;
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ mNode.mAlpha = alpha;
+ }
+
+ @Override
public void setVisibility(int visibility) {
mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
}
@@ -919,6 +1055,18 @@ public class AssistStructure implements Parcelable {
if (scrollX != 0 || scrollY != 0) {
Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY);
}
+ Matrix matrix = node.getTransformation();
+ if (matrix != null) {
+ Log.i(TAG, prefix + " Transformation: " + matrix);
+ }
+ float elevation = node.getElevation();
+ if (elevation != 0) {
+ Log.i(TAG, prefix + " Elevation: " + elevation);
+ }
+ float alpha = node.getAlpha();
+ if (alpha != 0) {
+ Log.i(TAG, prefix + " Alpha: " + elevation);
+ }
CharSequence contentDescription = node.getContentDescription();
if (contentDescription != null) {
Log.i(TAG, prefix + " Content description: " + contentDescription);
@@ -1010,27 +1158,33 @@ public class AssistStructure implements Parcelable {
}
if (mPendingAsyncChildren.size() > 0) {
// We waited too long, assume none of the assist structure is valid.
+ Log.w(TAG, "Skipping assist structure, waiting too long for async children (have "
+ + mPendingAsyncChildren.size() + " remaining");
skipStructure = true;
}
}
int start = out.dataPosition();
PooledStringWriter pwriter = new PooledStringWriter(out);
+ float[] tmpMatrix = new float[9];
ComponentName.writeToParcel(mActivityComponent, out);
final int N = skipStructure ? 0 : mWindowNodes.size();
out.writeInt(N);
+ int NV = 0;
for (int i=0; i<N; i++) {
- mWindowNodes.get(i).writeToParcel(out, pwriter);
+ NV += mWindowNodes.get(i).writeToParcel(out, pwriter, tmpMatrix);
}
pwriter.finish();
- Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
+ Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes, containing "
+ + N + " windows, " + NV + " views");
}
void readContentFromParcel(Parcel in) {
PooledStringReader preader = new PooledStringReader(in);
+ float[] tmpMatrix = new float[9];
mActivityComponent = ComponentName.readFromParcel(in);
final int N = in.readInt();
for (int i=0; i<N; i++) {
- mWindowNodes.add(new WindowNode(in, preader));
+ mWindowNodes.add(new WindowNode(in, preader, tmpMatrix));
}
//dump();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 92dae2e..b3def33 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6179,6 +6179,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setId(id, null, null, null);
}
structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
+ if (!hasIdentityMatrix()) {
+ structure.setTransformation(getMatrix());
+ }
+ structure.setElevation(getZ());
structure.setVisibility(getVisibility());
structure.setEnabled(isEnabled());
if (isClickable()) {
@@ -6215,11 +6219,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setContentDescription(getContentDescription());
}
- /** @hide */
- public void onProvideAssistStructure(ViewStructure structure) {
- onProvideStructure(structure);
- }
-
/**
* Called when assist structure is being retrieved from a view as part of
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to
@@ -6232,7 +6231,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
if (provider != null) {
AccessibilityNodeInfo info = createAccessibilityNodeInfo();
- Log.i("View", "Provider of " + this + ": children=" + info.getChildCount());
structure.setChildCount(1);
ViewStructure root = structure.newChild(0);
populateVirtualStructure(root, provider, info);
@@ -6240,11 +6238,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
- /** @hide */
- public void onProvideVirtualAssistStructure(ViewStructure structure) {
- onProvideVirtualStructure(structure);
- }
-
private void populateVirtualStructure(ViewStructure structure,
AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
@@ -6284,8 +6277,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
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());
@@ -6310,8 +6301,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void dispatchProvideStructure(ViewStructure structure) {
if (!isAssistBlocked()) {
- onProvideAssistStructure(structure);
- onProvideVirtualAssistStructure(structure);
+ onProvideStructure(structure);
+ onProvideVirtualStructure(structure);
} else {
structure.setClassName(getAccessibilityClassName().toString());
structure.setAssistBlocked(true);
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 9ab0ace..794622a 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -16,6 +16,7 @@
package android.view;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Bundle;
@@ -50,6 +51,28 @@ public abstract class ViewStructure {
int height);
/**
+ * Set the transformation matrix associated with this view, as per
+ * {@link View#getMatrix View.getMatrix()}, or null if there is none.
+ */
+ public abstract void setTransformation(Matrix matrix);
+
+ /**
+ * Set the visual elevation (shadow) of the view, as per
+ * {@link View#getZ View.getZ()}. Note this is <em>not</em> related
+ * to the physical Z-ordering of this view relative to its other siblings (that is how
+ * they overlap when drawing), it is only the visual representation for shadowing.
+ */
+ public abstract void setElevation(float elevation);
+
+ /**
+ * Set an alpha transformation that is applied to this view, as per
+ * {@link View#getAlpha View.getAlpha()}. Value ranges from 0
+ * (completely transparent) to 1 (completely opaque); the default is 1, which means
+ * no transformation.
+ */
+ public abstract void setAlpha(float alpha);
+
+ /**
* Set the visibility state of this view, as per
* {@link View#getVisibility View.getVisibility()}.
*/
diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
index d44afb0..610f30b 100644
--- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
+++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
@@ -18,6 +18,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <ImageView android:id="@+id/full_screenshot"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"/>
+
<com.android.test.voiceinteraction.AssistVisualizer android:id="@+id/assist_visualizer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@@ -30,19 +35,29 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
- android:orientation="vertical"
+ android:orientation="horizontal"
android:background="#ffffffff"
android:elevation="8dp"
>
- <Button android:id="@+id/start"
+ <ImageView android:id="@+id/screenshot"
+ android:layout_width="wrap_content"
+ android:layout_height="46dp"
+ android:adjustViewBounds="true" />
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+ <Button android:id="@+id/do_tree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="top|right"
- android:text="@string/start"
- />
- <ImageView android:id="@+id/screenshot"
+ android:text="@string/tree" />
+ <Button android:id="@+id/do_text"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:text="@string/text" />
+ <Button android:id="@+id/start"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/start" />
</LinearLayout>
<LinearLayout android:id="@+id/bottom_content"
@@ -58,26 +73,22 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- />
+ android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/confirm"
- />
+ android:text="@string/confirm" />
<Button android:id="@+id/complete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/complete"
- />
+ android:text="@string/complete" />
<Button android:id="@+id/abort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/abort"
- />
+ android:text="@string/abort" />
</LinearLayout>
</LinearLayout>
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index 6289929..4cf4104 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -17,6 +17,8 @@
<resources>
<string name="start">Start</string>
+ <string name="tree">Tree</string>
+ <string name="text">Text</string>
<string name="asyncStructure">(Async structure goes here)</string>
<string name="confirm">Confirm</string>
<string name="abort">Abort</string>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
index 439ace8..339755f 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.app.assist.AssistStructure;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -31,10 +32,32 @@ import java.util.ArrayList;
public class AssistVisualizer extends View {
static final String TAG = "AssistVisualizer";
+ static class TextEntry {
+ final Rect bounds;
+ final int parentLeft, parentTop;
+ final Matrix matrix;
+ final String className;
+ final CharSequence text;
+
+ TextEntry(AssistStructure.ViewNode node, int parentLeft, int parentTop, Matrix matrix) {
+ int left = parentLeft+node.getLeft();
+ int top = parentTop+node.getTop();
+ bounds = new Rect(left, top, left+node.getWidth(), top+node.getHeight());
+ this.parentLeft = parentLeft;
+ this.parentTop = parentTop;
+ this.matrix = new Matrix(matrix);
+ this.className = node.getClassName();
+ this.text = node.getText() != null ? node.getText() : node.getContentDescription();
+ }
+ }
+
AssistStructure mAssistStructure;
final Paint mFramePaint = new Paint();
- final ArrayList<Rect> mTextRects = new ArrayList<>();
+ final Paint mFrameNoTransformPaint = new Paint();
+ final ArrayList<Matrix> mMatrixStack = new ArrayList<>();
+ final ArrayList<TextEntry> mTextRects = new ArrayList<>();
final int[] mTmpLocation = new int[2];
+ final float[] mTmpMatrixPoint = new float[2];
public AssistVisualizer(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -42,17 +65,26 @@ public class AssistVisualizer extends View {
mFramePaint.setColor(0xffff0000);
mFramePaint.setStyle(Paint.Style.STROKE);
mFramePaint.setStrokeWidth(0);
+ float density = getResources().getDisplayMetrics().density;
+ mFramePaint.setShadowLayer(density, density, density, 0xff000000);
+ mFrameNoTransformPaint.setColor(0xff0000ff);
+ mFrameNoTransformPaint.setStyle(Paint.Style.STROKE);
+ mFrameNoTransformPaint.setStrokeWidth(0);
+ mFrameNoTransformPaint.setShadowLayer(density, density, density, 0xff000000);
}
public void setAssistStructure(AssistStructure as) {
mAssistStructure = as;
- mAssistStructure.dump();
mTextRects.clear();
final int N = as.getWindowNodeCount();
if (N > 0) {
for (int i=0; i<N; i++) {
AssistStructure.WindowNode windowNode = as.getWindowNodeAt(i);
- buildTextRects(windowNode.getRootViewNode(), windowNode.getLeft(),
+ mMatrixStack.clear();
+ Matrix matrix = new Matrix();
+ matrix.setTranslate(windowNode.getLeft(), windowNode.getTop());
+ mMatrixStack.add(matrix);
+ buildTextRects(windowNode.getRootViewNode(), 0, windowNode.getLeft(),
windowNode.getTop());
}
}
@@ -60,31 +92,62 @@ public class AssistVisualizer extends View {
invalidate();
}
+ public void logTree() {
+ if (mAssistStructure != null) {
+ mAssistStructure.dump();
+ }
+ }
+
+ public void logText() {
+ final int N = mTextRects.size();
+ for (int i=0; i<N; i++) {
+ TextEntry te = mTextRects.get(i);
+ Log.d(TAG, "View " + te.className + " " + te.bounds.toShortString()
+ + " in " + te.parentLeft + "," + te.parentTop
+ + " matrix=" + te.matrix.toShortString() + ": "
+ + te.text);
+ }
+ }
+
public void clearAssistData() {
mAssistStructure = null;
mTextRects.clear();
}
- void buildTextRects(AssistStructure.ViewNode root, int parentLeft, int parentTop) {
+ void buildTextRects(AssistStructure.ViewNode root, int matrixStackIndex,
+ int parentLeft, int parentTop) {
if (root.getVisibility() != View.VISIBLE) {
return;
}
- int left = parentLeft+root.getLeft();
- int top = parentTop+root.getTop();
+ Matrix parentMatrix = mMatrixStack.get(matrixStackIndex);
+ matrixStackIndex++;
+ Matrix matrix;
+ if (mMatrixStack.size() > matrixStackIndex) {
+ matrix = mMatrixStack.get(matrixStackIndex);
+ matrix.set(parentMatrix);
+ } else {
+ matrix = new Matrix(parentMatrix);
+ mMatrixStack.add(matrix);
+ }
+ matrix.preTranslate(root.getLeft(), root.getTop());
+ int left = parentLeft + root.getLeft();
+ int top = parentTop + root.getTop();
+ Matrix transform = root.getTransformation();
+ if (transform != null) {
+ matrix.preConcat(transform);
+ }
if (root.getText() != null || root.getContentDescription() != null) {
- Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight());
- Log.d(TAG, "View " + root.getClassName() + " " + left + "," + top + " tr "
- + r.toShortString() + ": "
- + (root.getText() != null ? root.getText() : root.getContentDescription()));
- mTextRects.add(r);
+ TextEntry te = new TextEntry(root, parentLeft, parentTop, matrix);
+ mTextRects.add(te);
}
final int N = root.getChildCount();
if (N > 0) {
left -= root.getScrollX();
top -= root.getScrollY();
+ matrix.preTranslate(-root.getScrollX(), -root.getScrollY());
for (int i=0; i<N; i++) {
AssistStructure.ViewNode child = root.getChildAt(i);
- buildTextRects(child, left, top);
+ buildTextRects(child, matrixStackIndex, left, top);
}
}
}
@@ -96,9 +159,19 @@ public class AssistVisualizer extends View {
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],
- r.right-mTmpLocation[0], r.bottom-mTmpLocation[1], mFramePaint);
+ TextEntry te = mTextRects.get(i);
+ canvas.drawRect(te.bounds.left - mTmpLocation[0], te.bounds.top - mTmpLocation[1],
+ te.bounds.right - mTmpLocation[0], te.bounds.bottom - mTmpLocation[1],
+ mFrameNoTransformPaint);
+ }
+ for (int i=0; i<N; i++) {
+ TextEntry te = mTextRects.get(i);
+ canvas.save();
+ canvas.translate(-mTmpLocation[0], -mTmpLocation[1]);
+ canvas.concat(te.matrix);
+ canvas.drawRect(0, 0, te.bounds.right - te.bounds.left, te.bounds.bottom - te.bounds.top,
+ mFramePaint);
+ canvas.restore();
}
}
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 90a781c..97c1e85 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -42,8 +42,11 @@ public class MainInteractionSession extends VoiceInteractionSession
View mTopContent;
View mBottomContent;
TextView mText;
+ Button mTreeButton;
+ Button mTextButton;
Button mStartButton;
ImageView mScreenshot;
+ ImageView mFullScreenshot;
Button mConfirmButton;
Button mCompleteButton;
Button mAbortButton;
@@ -110,9 +113,15 @@ public class MainInteractionSession extends VoiceInteractionSession
mTopContent = mContentView.findViewById(R.id.top_content);
mBottomContent = mContentView.findViewById(R.id.bottom_content);
mText = (TextView)mContentView.findViewById(R.id.text);
+ mTreeButton = (Button)mContentView.findViewById(R.id.do_tree);
+ mTreeButton.setOnClickListener(this);
+ mTextButton = (Button)mContentView.findViewById(R.id.do_text);
+ mTextButton.setOnClickListener(this);
mStartButton = (Button)mContentView.findViewById(R.id.start);
mStartButton.setOnClickListener(this);
mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot);
+ mScreenshot.setOnClickListener(this);
+ mFullScreenshot = (ImageView)mContentView.findViewById(R.id.full_screenshot);
mConfirmButton = (Button)mContentView.findViewById(R.id.confirm);
mConfirmButton.setOnClickListener(this);
mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
@@ -156,8 +165,10 @@ public class MainInteractionSession extends VoiceInteractionSession
mScreenshot.setAdjustViewBounds(true);
mScreenshot.setMaxWidth(screenshot.getWidth()/3);
mScreenshot.setMaxHeight(screenshot.getHeight()/3);
+ mFullScreenshot.setImageBitmap(screenshot);
} else {
mScreenshot.setImageDrawable(null);
+ mFullScreenshot.setImageDrawable(null);
}
}
@@ -183,7 +194,15 @@ public class MainInteractionSession extends VoiceInteractionSession
}
public void onClick(View v) {
- if (v == mStartButton) {
+ if (v == mTreeButton) {
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.logTree();
+ }
+ } else if (v == mTextButton) {
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.logText();
+ }
+ } else if (v == mStartButton) {
mState = STATE_LAUNCHING;
updateState();
startVoiceActivity(mStartIntent);
@@ -219,9 +238,15 @@ public class MainInteractionSession extends VoiceInteractionSession
} else if (v == mAbortButton) {
mPendingRequest.sendAbortVoiceResult(null);
mPendingRequest = null;
- } else if (v== mCompleteButton) {
+ } else if (v == mCompleteButton) {
mPendingRequest.sendCompleteVoiceResult(null);
mPendingRequest = null;
+ } else if (v == mScreenshot) {
+ if (mFullScreenshot.getVisibility() != View.VISIBLE) {
+ mFullScreenshot.setVisibility(View.VISIBLE);
+ } else {
+ mFullScreenshot.setVisibility(View.INVISIBLE);
+ }
}
updateState();
}