* add: row, column, depth, etc. for UiObject

* add: row, column, depth, etc. conditions for UiGlobalSelector
* add: filter for UiGlobalSelector
This commit is contained in:
hyb1996 2017-11-05 17:42:41 +08:00
parent 99466e2c33
commit 0b884f5747
7 changed files with 205 additions and 45 deletions

View File

@ -33,6 +33,7 @@ public class NodeInfoView extends RecyclerView {
private static final String[] FIELD_NAMES = {
"id",
"bounds",
"depth",
"desc",
"className",
"packageName",
@ -47,6 +48,12 @@ public class NodeInfoView extends RecyclerView {
"enabled",
"focusable",
"longClickable",
"row",
"rowCount",
"rowSpan",
"column",
"columnCount",
"columnSpan",
"selected",
"scrollable",
};
@ -64,17 +71,6 @@ public class NodeInfoView extends RecyclerView {
}
private String[][] mData = new String[FIELDS.length + 1][2];
private OnLongClickListener itemLongClickListener = new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos = getChildAdapterPosition(v);
if (pos < 1 || pos >= mData.length)
return false;
ClipboardUtil.setClip(getContext(), mData[pos][0] + " = " + mData[pos][1]);
Toast.makeText(getContext(), R.string.text_copy_to_clip, Toast.LENGTH_SHORT).show();
return true;
}
};
public NodeInfoView(Context context) {
super(context);

View File

@ -125,7 +125,7 @@ public class UiSelector extends UiGlobalSelector {
@NonNull
public UiObject untilFindOne() {
UiObjectCollection collection = untilFind();
return new UiObject(collection.get(0).getInfo());
return collection.get(0);
}
@ScriptInterface

View File

@ -10,9 +10,12 @@ import com.stardust.automator.filter.ClassNameFilter;
import com.stardust.automator.filter.DescFilter;
import com.stardust.automator.filter.DfsFilter;
import com.stardust.automator.filter.IdFilter;
import com.stardust.automator.filter.IntFilter;
import com.stardust.automator.filter.ListFilter;
import com.stardust.automator.filter.PackageNameFilter;
import com.stardust.automator.filter.TextFilter;
import com.stardust.automator.simple_action.Able;
import com.stardust.util.Supplier;
import java.util.ArrayList;
import java.util.LinkedList;
@ -351,6 +354,54 @@ public class UiGlobalSelector {
return this;
}
//第三类 int
public UiGlobalSelector depth(int d) {
mFilters.add(new IntFilter(IntFilter.DEPTH, d));
return this;
}
public UiGlobalSelector row(int d) {
mFilters.add(new IntFilter(IntFilter.ROW, d));
return this;
}
public UiGlobalSelector rowCount(int d) {
mFilters.add(new IntFilter(IntFilter.ROW_COUNT, d));
return this;
}
public UiGlobalSelector rowSpan(int d) {
mFilters.add(new IntFilter(IntFilter.ROW_SPAN, d));
return this;
}
public UiGlobalSelector column(int d) {
mFilters.add(new IntFilter(IntFilter.COLUMN, d));
return this;
}
public UiGlobalSelector columnCount(int d) {
mFilters.add(new IntFilter(IntFilter.COLUMN_COUNT, d));
return this;
}
public UiGlobalSelector columnSpan(int d) {
mFilters.add(new IntFilter(IntFilter.COLUMN_SPAN, d));
return this;
}
public UiGlobalSelector filter(final BooleanFilter.BooleanSupplier filter) {
mFilters.add(new DfsFilter() {
@Override
protected boolean isIncluded(UiObject nodeInfo) {
return filter.get(nodeInfo);
}
});
return this;
}
public UiObjectCollection findOf(UiObject node) {
List<UiObject> list = new ArrayList<>();
list.add(node);

View File

@ -1,22 +1,16 @@
package com.stardust.automator;
import android.app.UiAutomation;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pools;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
import com.stardust.view.accessibility.AccessibilityNodeInfoHelper;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -40,35 +34,40 @@ public class UiObject extends AccessibilityNodeInfoCompat {
private static final String TAG = "UiObject";
private static final boolean DEBUG = false;
private static int notRecycledCount = 0;
public static UiObject createRoot(AccessibilityNodeInfo root) {
return new UiObject(root, null, true);
return new UiObject(root, null, 0);
}
public static UiObject createRoot(AccessibilityNodeInfo root, AccessibilityNodeInfoAllocator allocator) {
return new UiObject(root, allocator, true);
return new UiObject(root, allocator, 0);
}
private AccessibilityNodeInfoAllocator mAllocator = null;
private String mStackTrace = "";
private boolean mIsRootNode = false;
private int mDepth = 0;
public UiObject(Object info) {
this(info, null);
this(info, 0);
}
public UiObject(Object info, AccessibilityNodeInfoAllocator allocator, boolean isRootNode) {
public UiObject(Object info, AccessibilityNodeInfoAllocator allocator, int depth) {
super(info);
mIsRootNode = isRootNode;
mDepth = depth;
mAllocator = allocator;
if (DEBUG)
mStackTrace = Arrays.toString(Thread.currentThread().getStackTrace());
}
public UiObject(Object info, AccessibilityNodeInfoAllocator allocator) {
this(info, allocator, false);
this(info, allocator, 0);
}
public UiObject(Object info, int depth) {
this(info, null, depth);
}
@Nullable
@ -77,7 +76,7 @@ public class UiObject extends AccessibilityNodeInfoCompat {
AccessibilityNodeInfoCompat parent = super.getParent();
if (parent == null)
return null;
return new UiObject(parent.getInfo());
return new UiObject(parent.getInfo(), mDepth - 1);
} catch (IllegalStateException e) {
// FIXME: 2017/5/5
return null;
@ -90,7 +89,7 @@ public class UiObject extends AccessibilityNodeInfoCompat {
AccessibilityNodeInfoCompat child = super.getChild(i);
if (child == null)
return null;
return new UiObject(child.getInfo());
return new UiObject(child.getInfo(), mDepth + 1);
} catch (IllegalStateException e) {
// FIXME: 2017/5/5
return null;
@ -151,6 +150,10 @@ public class UiObject extends AccessibilityNodeInfoCompat {
return getPackageName().toString();
}
public int depth() {
return mDepth;
}
public boolean performAction(int action, ActionArgument... arguments) {
Bundle bundle = argumentsToBundle(arguments);
return performAction(action, bundle);
@ -370,6 +373,36 @@ public class UiObject extends AccessibilityNodeInfoCompat {
return isScrollable();
}
public int row() {
return getCollectionItemInfo() == null ? -1 : getCollectionItemInfo().getRowIndex();
}
public int column() {
return getCollectionItemInfo() == null ? -1 : getCollectionItemInfo().getColumnIndex();
}
public int rowSpan() {
return getCollectionItemInfo() == null ? -1 : getCollectionItemInfo().getRowSpan();
}
public int columnSpan() {
return getCollectionItemInfo() == null ? -1 : getCollectionItemInfo().getColumnSpan();
}
public int rowCount() {
return getCollectionInfo() == null ? 0 : getCollectionInfo().getRowCount();
}
public int columnCount() {
return getCollectionInfo() == null ? 0 : getCollectionInfo().getColumnCount();
}
public boolean isHierarchically() {
return getCollectionInfo() != null && getCollectionInfo().isHierarchical();
}
@Override
public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) {
if (mAllocator == null)
@ -393,6 +426,7 @@ public class UiObject extends AccessibilityNodeInfoCompat {
}
public static List<UiObject> compatListToUiObjectList(List<AccessibilityNodeInfoCompat> compats, AccessibilityNodeInfoAllocator allocator) {
// FIXME: 2017/11/5 lost depth info
List<UiObject> uiObjects = new ArrayList<>(compats.size());
for (AccessibilityNodeInfoCompat compat : compats) {
if (compat != null)

View File

@ -35,14 +35,6 @@ public class UiObjectCollection {
return new UiObjectCollection(UiObject.compatListToUiObjectList(list));
}
public static UiObjectCollection ofInfo(List<AccessibilityNodeInfo> list) {
List<UiObject> compatList = new ArrayList<>(list.size());
for (AccessibilityNodeInfo nodeInfo : list) {
compatList.add(new UiObject(nodeInfo));
}
return new UiObjectCollection(compatList);
}
public static UiObjectCollection of(List<UiObject> list) {
return new UiObjectCollection(list);
}

View File

@ -0,0 +1,76 @@
package com.stardust.automator.filter;
import com.stardust.automator.UiObject;
/**
* Created by Stardust on 2017/11/5.
*/
public class IntFilter extends DfsFilter {
public interface IntProperty {
int get(UiObject object);
}
public static final IntProperty DEPTH = new IntProperty() {
@Override
public int get(UiObject object) {
return object.depth();
}
};
public static final IntProperty ROW = new IntProperty() {
@Override
public int get(UiObject object) {
return object.row();
}
};
public static final IntProperty ROW_COUNT = new IntProperty() {
@Override
public int get(UiObject object) {
return object.rowCount();
}
};
public static final IntProperty ROW_SPAN = new IntProperty() {
@Override
public int get(UiObject object) {
return object.rowSpan();
}
};
public static final IntProperty COLUMN = new IntProperty() {
@Override
public int get(UiObject object) {
return object.column();
}
};
public static final IntProperty COLUMN_COUNT = new IntProperty() {
@Override
public int get(UiObject object) {
return object.columnCount();
}
};
public static final IntProperty COLUMN_SPAN = new IntProperty() {
@Override
public int get(UiObject object) {
return object.columnSpan();
}
};
private IntProperty mIntProperty;
private int mValue;
public IntFilter(IntProperty intProperty, int value) {
mIntProperty = intProperty;
mValue = value;
}
@Override
protected boolean isIncluded(UiObject nodeInfo) {
return mIntProperty.get(nodeInfo) == mValue;
}
}

View File

@ -25,6 +25,7 @@ public class NodeInfo {
public CharSequence className;
public CharSequence packageName;
public CharSequence text;
public int depth;
public int drawingOrder;
public boolean accessibilityFocused;
public boolean checked;
@ -35,20 +36,34 @@ public class NodeInfo {
public boolean enabled;
public boolean focusable;
public boolean longClickable;
public int row;
public int column;
public int rowCount;
public int columnCount;
public int rowSpan;
public int columnSpan;
public boolean selected;
public boolean scrollable;
public String bounds;
public NodeInfo(AccessibilityNodeInfoCompat node) {
public NodeInfo(UiObject node) {
id = simplifyId(node.getViewIdResourceName());
desc = node.getContentDescription();
className = node.getClassName();
packageName = node.getPackageName();
text = node.getText();
depth = node.depth();
drawingOrder = node.getDrawingOrder();
row = node.row();
column = node.column();
rowCount = node.rowCount();
columnCount = node.columnCount();
rowSpan = node.rowSpan();
columnSpan = node.columnSpan();
accessibilityFocused = node.isAccessibilityFocused();
checked = node.isChecked();
clickable = node.isClickable();
@ -80,16 +95,12 @@ public class NodeInfo {
return rect.toString().replace('-', ',').replace(" ", "").substring(4);
}
public NodeInfo(AccessibilityNodeInfo node) {
this(new AccessibilityNodeInfoCompat(node));
}
public static NodeInfo capture(@NonNull UiObject root) {
NodeInfo nodeInfo = new NodeInfo(root);
int childCount = root.getChildCount();
public static NodeInfo capture(@NonNull UiObject parent) {
NodeInfo nodeInfo = new NodeInfo(parent);
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
UiObject child = root.child(i);
UiObject child = parent.child(i);
if (child != null) {
nodeInfo.children.add(capture(child));
}