diff options
author | Dianne Hackborn <hackbod@google.com> | 2015-06-26 17:20:10 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-06-26 17:20:12 +0000 |
commit | ff81025a9def3e56908339ad846bff515d5ecbfb (patch) | |
tree | d528a599870aa9e4a842170eda473a2b6eb63020 | |
parent | d2c414573242fc59a2d34f66f1dfb610ec7d59a3 (diff) | |
parent | 70d8be7616a450e9b7ef09c8bda5a8b25936a29a (diff) | |
download | frameworks_base-ff81025a9def3e56908339ad846bff515d5ecbfb.zip frameworks_base-ff81025a9def3e56908339ad846bff515d5ecbfb.tar.gz frameworks_base-ff81025a9def3e56908339ad846bff515d5ecbfb.tar.bz2 |
Merge "Fix issue #22013372: Assist should take translationX and friends..." into mnc-dev
-rw-r--r-- | api/current.txt | 6 | ||||
-rw-r--r-- | api/system-current.txt | 6 | ||||
-rw-r--r-- | core/java/android/app/assist/AssistStructure.java | 286 | ||||
-rw-r--r-- | core/java/android/view/View.java | 21 | ||||
-rw-r--r-- | core/java/android/view/ViewStructure.java | 23 | ||||
-rw-r--r-- | tests/VoiceInteraction/res/layout/voice_interaction_session.xml | 41 | ||||
-rw-r--r-- | tests/VoiceInteraction/res/values/strings.xml | 2 | ||||
-rw-r--r-- | tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java | 103 | ||||
-rw-r--r-- | tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java | 29 |
9 files changed, 404 insertions, 113 deletions
diff --git a/api/current.txt b/api/current.txt index 3cd3ee2..2d51b97 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5832,10 +5832,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(); @@ -5854,6 +5856,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(); @@ -36948,6 +36951,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); @@ -36956,6 +36960,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); @@ -36966,6 +36971,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(); } |