Merge "Fix issue #22013372: Assist should take translationX and friends..." into mnc-dev

This commit is contained in:
Dianne Hackborn
2015-06-26 17:20:10 +00:00
committed by Android (Google) Code Review
9 changed files with 407 additions and 116 deletions

View File

@@ -5832,10 +5832,12 @@ package android.app.assist {
} }
public static class AssistStructure.ViewNode { public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int); method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount(); method public int getChildCount();
method public java.lang.String getClassName(); method public java.lang.String getClassName();
method public java.lang.CharSequence getContentDescription(); method public java.lang.CharSequence getContentDescription();
method public float getElevation();
method public android.os.Bundle getExtras(); method public android.os.Bundle getExtras();
method public int getHeight(); method public int getHeight();
method public java.lang.String getHint(); method public java.lang.String getHint();
@@ -5854,6 +5856,7 @@ package android.app.assist {
method public float getTextSize(); method public float getTextSize();
method public int getTextStyle(); method public int getTextStyle();
method public int getTop(); method public int getTop();
method public android.graphics.Matrix getTransformation();
method public int getVisibility(); method public int getVisibility();
method public int getWidth(); method public int getWidth();
method public boolean isAccessibilityFocused(); method public boolean isAccessibilityFocused();
@@ -36948,6 +36951,7 @@ package android.view {
method public abstract android.view.ViewStructure newChild(int); method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean); method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean); method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
method public abstract void setCheckable(boolean); method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean); method public abstract void setChecked(boolean);
method public abstract void setChildCount(int); 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 setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean); method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int); 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 setEnabled(boolean);
method public abstract void setFocusable(boolean); method public abstract void setFocusable(boolean);
method public abstract void setFocused(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);
method public abstract void setText(java.lang.CharSequence, int, int); method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, 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); method public abstract void setVisibility(int);
} }

View File

@@ -5964,10 +5964,12 @@ package android.app.assist {
} }
public static class AssistStructure.ViewNode { public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int); method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount(); method public int getChildCount();
method public java.lang.String getClassName(); method public java.lang.String getClassName();
method public java.lang.CharSequence getContentDescription(); method public java.lang.CharSequence getContentDescription();
method public float getElevation();
method public android.os.Bundle getExtras(); method public android.os.Bundle getExtras();
method public int getHeight(); method public int getHeight();
method public java.lang.String getHint(); method public java.lang.String getHint();
@@ -5986,6 +5988,7 @@ package android.app.assist {
method public float getTextSize(); method public float getTextSize();
method public int getTextStyle(); method public int getTextStyle();
method public int getTop(); method public int getTop();
method public android.graphics.Matrix getTransformation();
method public int getVisibility(); method public int getVisibility();
method public int getWidth(); method public int getWidth();
method public boolean isAccessibilityFocused(); method public boolean isAccessibilityFocused();
@@ -39243,6 +39246,7 @@ package android.view {
method public abstract android.view.ViewStructure newChild(int); method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean); method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean); method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
method public abstract void setCheckable(boolean); method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean); method public abstract void setChecked(boolean);
method public abstract void setChildCount(int); 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 setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean); method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int); 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 setEnabled(boolean);
method public abstract void setFocusable(boolean); method public abstract void setFocusable(boolean);
method public abstract void setFocused(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);
method public abstract void setText(java.lang.CharSequence, int, int); method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, 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); method public abstract void setVisibility(int);
} }

View File

@@ -2,6 +2,7 @@ package android.app.assist;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName; import android.content.ComponentName;
import android.graphics.Matrix;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
@@ -128,24 +129,24 @@ public class AssistStructure implements Parcelable {
view.dispatchProvideStructure(builder); view.dispatchProvideStructure(builder);
} }
WindowNode(Parcel in, PooledStringReader preader) { WindowNode(Parcel in, PooledStringReader preader, float[] tmpMatrix) {
mX = in.readInt(); mX = in.readInt();
mY = in.readInt(); mY = in.readInt();
mWidth = in.readInt(); mWidth = in.readInt();
mHeight = in.readInt(); mHeight = in.readInt();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mDisplayId = in.readInt(); 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(mX);
out.writeInt(mY); out.writeInt(mY);
out.writeInt(mWidth); out.writeInt(mWidth);
out.writeInt(mHeight); out.writeInt(mHeight);
TextUtils.writeToParcel(mTitle, out, 0); TextUtils.writeToParcel(mTitle, out, 0);
out.writeInt(mDisplayId); 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_UNDERLINE = 1<<2;
public static final int TEXT_STYLE_STRIKE_THRU = 1<<3; public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
int mId; int mId = View.NO_ID;
String mIdPackage; String mIdPackage;
String mIdType; String mIdType;
String mIdEntry; String mIdEntry;
@@ -226,20 +227,35 @@ public class AssistStructure implements Parcelable {
int mScrollY; int mScrollY;
int mWidth; int mWidth;
int mHeight; int mHeight;
Matrix mMatrix;
float mElevation;
float mAlpha = 1.0f;
static final int FLAGS_DISABLED = 0x00000001; static final int FLAGS_DISABLED = 0x00000001;
static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE; static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
static final int FLAGS_FOCUSABLE = 0x00000010; static final int FLAGS_FOCUSABLE = 0x00000010;
static final int FLAGS_FOCUSED = 0x00000020; static final int FLAGS_FOCUSED = 0x00000020;
static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
static final int FLAGS_SELECTED = 0x00000040; static final int FLAGS_SELECTED = 0x00000040;
static final int FLAGS_ASSIST_BLOCKED = 0x00000080; static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
static final int FLAGS_ACTIVATED = 0x40000000;
static final int FLAGS_CHECKABLE = 0x00000100; static final int FLAGS_CHECKABLE = 0x00000100;
static final int FLAGS_CHECKED = 0x00000200; static final int FLAGS_CHECKED = 0x00000200;
static final int FLAGS_CLICKABLE = 0x00004000; static final int FLAGS_CLICKABLE = 0x00000400;
static final int FLAGS_LONG_CLICKABLE = 0x00200000; static final int FLAGS_LONG_CLICKABLE = 0x00000800;
static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000; 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; int mFlags;
@@ -254,79 +270,153 @@ public class AssistStructure implements Parcelable {
ViewNode() { ViewNode() {
} }
ViewNode(Parcel in, PooledStringReader preader) { ViewNode(Parcel in, PooledStringReader preader, float[] tmpMatrix) {
mId = in.readInt();
if (mId != 0) {
mIdEntry = preader.readString();
if (mIdEntry != null) {
mIdType = preader.readString();
mIdPackage = preader.readString();
} else {
mIdPackage = mIdType = null;
}
} else {
mIdPackage = mIdType = mIdEntry = null;
}
mX = in.readInt();
mY = in.readInt();
mScrollX = in.readInt();
mScrollY = in.readInt();
mWidth = in.readInt();
mHeight = in.readInt();
mFlags = in.readInt();
mClassName = preader.readString(); mClassName = preader.readString();
mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mFlags = in.readInt();
if (in.readInt() != 0) { final int flags = mFlags;
mText = new ViewNodeText(in); if ((flags&FLAGS_HAS_ID) != 0) {
} else { mId = in.readInt();
mText = null; if (mId != 0) {
mIdEntry = preader.readString();
if (mIdEntry != null) {
mIdType = preader.readString();
mIdPackage = preader.readString();
}
}
} }
mExtras = in.readBundle(); if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
final int NCHILDREN = in.readInt(); mX = in.readInt();
if (NCHILDREN > 0) { mY = in.readInt();
mWidth = in.readInt();
mHeight = in.readInt();
} else {
int val = in.readInt();
mX = val&0x7fff;
mY = (val>>16)&0x7fff;
val = in.readInt();
mWidth = val&0x7fff;
mHeight = (val>>16)&0x7fff;
}
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);
}
if ((flags&FLAGS_HAS_EXTRAS) != 0) {
mExtras = in.readBundle();
}
if ((flags&FLAGS_HAS_CHILDREN) != 0) {
final int NCHILDREN = in.readInt();
mChildren = new ViewNode[NCHILDREN]; mChildren = new ViewNode[NCHILDREN];
for (int i=0; i<NCHILDREN; i++) { 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) { int writeToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
out.writeInt(mId); int flags = mFlags & ~FLAGS_ALL_CONTROL;
if (mId != 0) { if (mId != View.NO_ID) {
pwriter.writeString(mIdEntry); flags |= FLAGS_HAS_ID;
if (mIdEntry != null) { }
pwriter.writeString(mIdType); if ((mX&~0x7fff) != 0 || (mY&~0x7fff) != 0
pwriter.writeString(mIdPackage); || (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;
}
if (mText != null) {
flags |= FLAGS_HAS_TEXT;
}
if (mExtras != null) {
flags |= FLAGS_HAS_EXTRAS;
}
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);
}
} }
} }
out.writeInt(mX); if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
out.writeInt(mY); out.writeInt(mX);
out.writeInt(mScrollX); out.writeInt(mY);
out.writeInt(mScrollY); out.writeInt(mWidth);
out.writeInt(mWidth); out.writeInt(mHeight);
out.writeInt(mHeight);
out.writeInt(mFlags);
pwriter.writeString(mClassName);
TextUtils.writeToParcel(mContentDescription, out, 0);
if (mText != null) {
out.writeInt(1);
mText.writeToParcel(out);
} else { } else {
out.writeInt(0); out.writeInt((mY<<16) | mX);
out.writeInt((mHeight<<16) | mWidth);
} }
out.writeBundle(mExtras); if ((flags&FLAGS_HAS_SCROLL) != 0) {
if (mChildren != null) { 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; final int NCHILDREN = mChildren.length;
out.writeInt(NCHILDREN); out.writeInt(NCHILDREN);
for (int i=0; i<NCHILDREN; i++) { 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;
} }
/** /**
@@ -407,6 +497,33 @@ public class AssistStructure implements Parcelable {
return mHeight; return mHeight;
} }
/**
* 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 * Returns the visibility mode of this view, as per
* {@link android.view.View#getVisibility() View.getVisibility()}. * {@link android.view.View#getVisibility() View.getVisibility()}.
@@ -645,6 +762,25 @@ public class AssistStructure implements Parcelable {
mNode.mHeight = height; mNode.mHeight = height;
} }
@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 @Override
public void setVisibility(int visibility) { public void setVisibility(int visibility) {
mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility; mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
@@ -919,6 +1055,18 @@ public class AssistStructure implements Parcelable {
if (scrollX != 0 || scrollY != 0) { if (scrollX != 0 || scrollY != 0) {
Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY); 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(); CharSequence contentDescription = node.getContentDescription();
if (contentDescription != null) { if (contentDescription != null) {
Log.i(TAG, prefix + " Content description: " + contentDescription); Log.i(TAG, prefix + " Content description: " + contentDescription);
@@ -1010,27 +1158,33 @@ public class AssistStructure implements Parcelable {
} }
if (mPendingAsyncChildren.size() > 0) { if (mPendingAsyncChildren.size() > 0) {
// We waited too long, assume none of the assist structure is valid. // 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; skipStructure = true;
} }
} }
int start = out.dataPosition(); int start = out.dataPosition();
PooledStringWriter pwriter = new PooledStringWriter(out); PooledStringWriter pwriter = new PooledStringWriter(out);
float[] tmpMatrix = new float[9];
ComponentName.writeToParcel(mActivityComponent, out); ComponentName.writeToParcel(mActivityComponent, out);
final int N = skipStructure ? 0 : mWindowNodes.size(); final int N = skipStructure ? 0 : mWindowNodes.size();
out.writeInt(N); out.writeInt(N);
int NV = 0;
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
mWindowNodes.get(i).writeToParcel(out, pwriter); NV += mWindowNodes.get(i).writeToParcel(out, pwriter, tmpMatrix);
} }
pwriter.finish(); 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) { void readContentFromParcel(Parcel in) {
PooledStringReader preader = new PooledStringReader(in); PooledStringReader preader = new PooledStringReader(in);
float[] tmpMatrix = new float[9];
mActivityComponent = ComponentName.readFromParcel(in); mActivityComponent = ComponentName.readFromParcel(in);
final int N = in.readInt(); final int N = in.readInt();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
mWindowNodes.add(new WindowNode(in, preader)); mWindowNodes.add(new WindowNode(in, preader, tmpMatrix));
} }
//dump(); //dump();
} }

View File

@@ -6179,6 +6179,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setId(id, null, null, null); structure.setId(id, null, null, null);
} }
structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop); structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
if (!hasIdentityMatrix()) {
structure.setTransformation(getMatrix());
}
structure.setElevation(getZ());
structure.setVisibility(getVisibility()); structure.setVisibility(getVisibility());
structure.setEnabled(isEnabled()); structure.setEnabled(isEnabled());
if (isClickable()) { if (isClickable()) {
@@ -6215,11 +6219,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setContentDescription(getContentDescription()); structure.setContentDescription(getContentDescription());
} }
/** @hide */
public void onProvideAssistStructure(ViewStructure structure) {
onProvideStructure(structure);
}
/** /**
* Called when assist structure is being retrieved from a view as part of * Called when assist structure is being retrieved from a view as part of
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to
@@ -6232,7 +6231,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityNodeProvider provider = getAccessibilityNodeProvider(); AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
if (provider != null) { if (provider != null) {
AccessibilityNodeInfo info = createAccessibilityNodeInfo(); AccessibilityNodeInfo info = createAccessibilityNodeInfo();
Log.i("View", "Provider of " + this + ": children=" + info.getChildCount());
structure.setChildCount(1); structure.setChildCount(1);
ViewStructure root = structure.newChild(0); ViewStructure root = structure.newChild(0);
populateVirtualStructure(root, provider, info); 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, private void populateVirtualStructure(ViewStructure structure,
AccessibilityNodeProvider provider, AccessibilityNodeInfo info) { AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()), structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
@@ -6284,8 +6277,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
CharSequence cname = info.getClassName(); CharSequence cname = info.getClassName();
structure.setClassName(cname != null ? cname.toString() : null); structure.setClassName(cname != null ? cname.toString() : null);
structure.setContentDescription(info.getContentDescription()); structure.setContentDescription(info.getContentDescription());
Log.i("View", "vassist " + cname + " @ " + rect.toShortString()
+ " text=" + info.getText() + " cd=" + info.getContentDescription());
if (info.getText() != null || info.getError() != null) { if (info.getText() != null || info.getError() != null) {
structure.setText(info.getText(), info.getTextSelectionStart(), structure.setText(info.getText(), info.getTextSelectionStart(),
info.getTextSelectionEnd()); info.getTextSelectionEnd());
@@ -6310,8 +6301,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/ */
public void dispatchProvideStructure(ViewStructure structure) { public void dispatchProvideStructure(ViewStructure structure) {
if (!isAssistBlocked()) { if (!isAssistBlocked()) {
onProvideAssistStructure(structure); onProvideStructure(structure);
onProvideVirtualAssistStructure(structure); onProvideVirtualStructure(structure);
} else { } else {
structure.setClassName(getAccessibilityClassName().toString()); structure.setClassName(getAccessibilityClassName().toString());
structure.setAssistBlocked(true); structure.setAssistBlocked(true);

View File

@@ -16,6 +16,7 @@
package android.view; package android.view;
import android.graphics.Matrix;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
@@ -49,6 +50,28 @@ public abstract class ViewStructure {
public abstract void setDimens(int left, int top, int scrollX, int scrollY, int width, public abstract void setDimens(int left, int top, int scrollX, int scrollY, int width,
int height); 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 * Set the visibility state of this view, as per
* {@link View#getVisibility View.getVisibility()}. * {@link View#getVisibility View.getVisibility()}.

View File

@@ -18,6 +18,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="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" <com.android.test.voiceinteraction.AssistVisualizer android:id="@+id/assist_visualizer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
@@ -30,19 +35,29 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="top" android:layout_gravity="top"
android:orientation="vertical" android:orientation="horizontal"
android:background="#ffffffff" android:background="#ffffffff"
android:elevation="8dp" android:elevation="8dp"
> >
<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:text="@string/tree" />
<Button android:id="@+id/do_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text" />
<Button android:id="@+id/start" <Button android:id="@+id/start"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="top|right" android:text="@string/start" />
android:text="@string/start"
/>
<ImageView android:id="@+id/screenshot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout> </LinearLayout>
<LinearLayout android:id="@+id/bottom_content" <LinearLayout android:id="@+id/bottom_content"
@@ -58,26 +73,22 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" 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" <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<Button android:id="@+id/confirm" <Button android:id="@+id/confirm"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/confirm" android:text="@string/confirm" />
/>
<Button android:id="@+id/complete" <Button android:id="@+id/complete"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/complete" android:text="@string/complete" />
/>
<Button android:id="@+id/abort" <Button android:id="@+id/abort"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/abort" android:text="@string/abort" />
/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@@ -17,6 +17,8 @@
<resources> <resources>
<string name="start">Start</string> <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="asyncStructure">(Async structure goes here)</string>
<string name="confirm">Confirm</string> <string name="confirm">Confirm</string>
<string name="abort">Abort</string> <string name="abort">Abort</string>

View File

@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.app.assist.AssistStructure; import android.app.assist.AssistStructure;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
@@ -31,10 +32,32 @@ import java.util.ArrayList;
public class AssistVisualizer extends View { public class AssistVisualizer extends View {
static final String TAG = "AssistVisualizer"; 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; AssistStructure mAssistStructure;
final Paint mFramePaint = new Paint(); 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 int[] mTmpLocation = new int[2];
final float[] mTmpMatrixPoint = new float[2];
public AssistVisualizer(Context context, @Nullable AttributeSet attrs) { public AssistVisualizer(Context context, @Nullable AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@@ -42,17 +65,26 @@ public class AssistVisualizer extends View {
mFramePaint.setColor(0xffff0000); mFramePaint.setColor(0xffff0000);
mFramePaint.setStyle(Paint.Style.STROKE); mFramePaint.setStyle(Paint.Style.STROKE);
mFramePaint.setStrokeWidth(0); 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) { public void setAssistStructure(AssistStructure as) {
mAssistStructure = as; mAssistStructure = as;
mAssistStructure.dump();
mTextRects.clear(); mTextRects.clear();
final int N = as.getWindowNodeCount(); final int N = as.getWindowNodeCount();
if (N > 0) { if (N > 0) {
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
AssistStructure.WindowNode windowNode = as.getWindowNodeAt(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()); windowNode.getTop());
} }
} }
@@ -60,31 +92,62 @@ public class AssistVisualizer extends View {
invalidate(); 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() { public void clearAssistData() {
mAssistStructure = null; mAssistStructure = null;
mTextRects.clear(); 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) { if (root.getVisibility() != View.VISIBLE) {
return; return;
} }
int left = parentLeft+root.getLeft(); Matrix parentMatrix = mMatrixStack.get(matrixStackIndex);
int top = parentTop+root.getTop(); 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) { if (root.getText() != null || root.getContentDescription() != null) {
Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight()); TextEntry te = new TextEntry(root, parentLeft, parentTop, matrix);
Log.d(TAG, "View " + root.getClassName() + " " + left + "," + top + " tr " mTextRects.add(te);
+ r.toShortString() + ": "
+ (root.getText() != null ? root.getText() : root.getContentDescription()));
mTextRects.add(r);
} }
final int N = root.getChildCount(); final int N = root.getChildCount();
if (N > 0) { if (N > 0) {
left -= root.getScrollX(); left -= root.getScrollX();
top -= root.getScrollY(); top -= root.getScrollY();
matrix.preTranslate(-root.getScrollX(), -root.getScrollY());
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
AssistStructure.ViewNode child = root.getChildAt(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(); final int N = mTextRects.size();
Log.d(TAG, "Drawing text rects in " + this + ": found " + mTextRects.size()); Log.d(TAG, "Drawing text rects in " + this + ": found " + mTextRects.size());
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
Rect r = mTextRects.get(i); TextEntry te = mTextRects.get(i);
canvas.drawRect(r.left-mTmpLocation[0], r.top-mTmpLocation[1], canvas.drawRect(te.bounds.left - mTmpLocation[0], te.bounds.top - mTmpLocation[1],
r.right-mTmpLocation[0], r.bottom-mTmpLocation[1], mFramePaint); 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();
} }
} }
} }

View File

@@ -42,8 +42,11 @@ public class MainInteractionSession extends VoiceInteractionSession
View mTopContent; View mTopContent;
View mBottomContent; View mBottomContent;
TextView mText; TextView mText;
Button mTreeButton;
Button mTextButton;
Button mStartButton; Button mStartButton;
ImageView mScreenshot; ImageView mScreenshot;
ImageView mFullScreenshot;
Button mConfirmButton; Button mConfirmButton;
Button mCompleteButton; Button mCompleteButton;
Button mAbortButton; Button mAbortButton;
@@ -110,9 +113,15 @@ public class MainInteractionSession extends VoiceInteractionSession
mTopContent = mContentView.findViewById(R.id.top_content); mTopContent = mContentView.findViewById(R.id.top_content);
mBottomContent = mContentView.findViewById(R.id.bottom_content); mBottomContent = mContentView.findViewById(R.id.bottom_content);
mText = (TextView)mContentView.findViewById(R.id.text); 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 = (Button)mContentView.findViewById(R.id.start);
mStartButton.setOnClickListener(this); mStartButton.setOnClickListener(this);
mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot); 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 = (Button)mContentView.findViewById(R.id.confirm);
mConfirmButton.setOnClickListener(this); mConfirmButton.setOnClickListener(this);
mCompleteButton = (Button)mContentView.findViewById(R.id.complete); mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
@@ -156,8 +165,10 @@ public class MainInteractionSession extends VoiceInteractionSession
mScreenshot.setAdjustViewBounds(true); mScreenshot.setAdjustViewBounds(true);
mScreenshot.setMaxWidth(screenshot.getWidth()/3); mScreenshot.setMaxWidth(screenshot.getWidth()/3);
mScreenshot.setMaxHeight(screenshot.getHeight()/3); mScreenshot.setMaxHeight(screenshot.getHeight()/3);
mFullScreenshot.setImageBitmap(screenshot);
} else { } else {
mScreenshot.setImageDrawable(null); mScreenshot.setImageDrawable(null);
mFullScreenshot.setImageDrawable(null);
} }
} }
@@ -183,7 +194,15 @@ public class MainInteractionSession extends VoiceInteractionSession
} }
public void onClick(View v) { 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; mState = STATE_LAUNCHING;
updateState(); updateState();
startVoiceActivity(mStartIntent); startVoiceActivity(mStartIntent);
@@ -219,9 +238,15 @@ public class MainInteractionSession extends VoiceInteractionSession
} else if (v == mAbortButton) { } else if (v == mAbortButton) {
mPendingRequest.sendAbortVoiceResult(null); mPendingRequest.sendAbortVoiceResult(null);
mPendingRequest = null; mPendingRequest = null;
} else if (v== mCompleteButton) { } else if (v == mCompleteButton) {
mPendingRequest.sendCompleteVoiceResult(null); mPendingRequest.sendCompleteVoiceResult(null);
mPendingRequest = null; mPendingRequest = null;
} else if (v == mScreenshot) {
if (mFullScreenshot.getVisibility() != View.VISIBLE) {
mFullScreenshot.setVisibility(View.VISIBLE);
} else {
mFullScreenshot.setVisibility(View.INVISIBLE);
}
} }
updateState(); updateState();
} }