* add: row, column, depth, etc. for UiObject
* add: row, column, depth, etc. conditions for UiGlobalSelector * add: filter for UiGlobalSelector
This commit is contained in:
@@ -33,6 +33,7 @@ public class NodeInfoView extends RecyclerView {
|
|||||||
private static final String[] FIELD_NAMES = {
|
private static final String[] FIELD_NAMES = {
|
||||||
"id",
|
"id",
|
||||||
"bounds",
|
"bounds",
|
||||||
|
"depth",
|
||||||
"desc",
|
"desc",
|
||||||
"className",
|
"className",
|
||||||
"packageName",
|
"packageName",
|
||||||
@@ -47,6 +48,12 @@ public class NodeInfoView extends RecyclerView {
|
|||||||
"enabled",
|
"enabled",
|
||||||
"focusable",
|
"focusable",
|
||||||
"longClickable",
|
"longClickable",
|
||||||
|
"row",
|
||||||
|
"rowCount",
|
||||||
|
"rowSpan",
|
||||||
|
"column",
|
||||||
|
"columnCount",
|
||||||
|
"columnSpan",
|
||||||
"selected",
|
"selected",
|
||||||
"scrollable",
|
"scrollable",
|
||||||
};
|
};
|
||||||
@@ -64,17 +71,6 @@ public class NodeInfoView extends RecyclerView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String[][] mData = new String[FIELDS.length + 1][2];
|
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) {
|
public NodeInfoView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class UiSelector extends UiGlobalSelector {
|
|||||||
@NonNull
|
@NonNull
|
||||||
public UiObject untilFindOne() {
|
public UiObject untilFindOne() {
|
||||||
UiObjectCollection collection = untilFind();
|
UiObjectCollection collection = untilFind();
|
||||||
return new UiObject(collection.get(0).getInfo());
|
return collection.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ import com.stardust.automator.filter.ClassNameFilter;
|
|||||||
import com.stardust.automator.filter.DescFilter;
|
import com.stardust.automator.filter.DescFilter;
|
||||||
import com.stardust.automator.filter.DfsFilter;
|
import com.stardust.automator.filter.DfsFilter;
|
||||||
import com.stardust.automator.filter.IdFilter;
|
import com.stardust.automator.filter.IdFilter;
|
||||||
|
import com.stardust.automator.filter.IntFilter;
|
||||||
import com.stardust.automator.filter.ListFilter;
|
import com.stardust.automator.filter.ListFilter;
|
||||||
import com.stardust.automator.filter.PackageNameFilter;
|
import com.stardust.automator.filter.PackageNameFilter;
|
||||||
import com.stardust.automator.filter.TextFilter;
|
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.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -351,6 +354,54 @@ public class UiGlobalSelector {
|
|||||||
return this;
|
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) {
|
public UiObjectCollection findOf(UiObject node) {
|
||||||
List<UiObject> list = new ArrayList<>();
|
List<UiObject> list = new ArrayList<>();
|
||||||
list.add(node);
|
list.add(node);
|
||||||
|
|||||||
@@ -1,22 +1,16 @@
|
|||||||
package com.stardust.automator;
|
package com.stardust.automator;
|
||||||
|
|
||||||
import android.app.UiAutomation;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.Pools;
|
|
||||||
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
|
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
|
|
||||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||||
import com.stardust.view.accessibility.AccessibilityNodeInfoHelper;
|
import com.stardust.view.accessibility.AccessibilityNodeInfoHelper;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -40,35 +34,40 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
|||||||
|
|
||||||
private static final String TAG = "UiObject";
|
private static final String TAG = "UiObject";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static int notRecycledCount = 0;
|
|
||||||
|
|
||||||
public static UiObject createRoot(AccessibilityNodeInfo root) {
|
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) {
|
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 AccessibilityNodeInfoAllocator mAllocator = null;
|
||||||
private String mStackTrace = "";
|
private String mStackTrace = "";
|
||||||
private boolean mIsRootNode = false;
|
private int mDepth = 0;
|
||||||
|
|
||||||
public UiObject(Object info) {
|
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);
|
super(info);
|
||||||
mIsRootNode = isRootNode;
|
mDepth = depth;
|
||||||
mAllocator = allocator;
|
mAllocator = allocator;
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
mStackTrace = Arrays.toString(Thread.currentThread().getStackTrace());
|
mStackTrace = Arrays.toString(Thread.currentThread().getStackTrace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public UiObject(Object info, AccessibilityNodeInfoAllocator allocator) {
|
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
|
@Nullable
|
||||||
@@ -77,7 +76,7 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
|||||||
AccessibilityNodeInfoCompat parent = super.getParent();
|
AccessibilityNodeInfoCompat parent = super.getParent();
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
return null;
|
return null;
|
||||||
return new UiObject(parent.getInfo());
|
return new UiObject(parent.getInfo(), mDepth - 1);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// FIXME: 2017/5/5
|
// FIXME: 2017/5/5
|
||||||
return null;
|
return null;
|
||||||
@@ -90,7 +89,7 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
|||||||
AccessibilityNodeInfoCompat child = super.getChild(i);
|
AccessibilityNodeInfoCompat child = super.getChild(i);
|
||||||
if (child == null)
|
if (child == null)
|
||||||
return null;
|
return null;
|
||||||
return new UiObject(child.getInfo());
|
return new UiObject(child.getInfo(), mDepth + 1);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// FIXME: 2017/5/5
|
// FIXME: 2017/5/5
|
||||||
return null;
|
return null;
|
||||||
@@ -151,6 +150,10 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
|||||||
return getPackageName().toString();
|
return getPackageName().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int depth() {
|
||||||
|
return mDepth;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean performAction(int action, ActionArgument... arguments) {
|
public boolean performAction(int action, ActionArgument... arguments) {
|
||||||
Bundle bundle = argumentsToBundle(arguments);
|
Bundle bundle = argumentsToBundle(arguments);
|
||||||
return performAction(action, bundle);
|
return performAction(action, bundle);
|
||||||
@@ -370,6 +373,36 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
|||||||
return isScrollable();
|
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
|
@Override
|
||||||
public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) {
|
public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) {
|
||||||
if (mAllocator == null)
|
if (mAllocator == null)
|
||||||
@@ -393,6 +426,7 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<UiObject> compatListToUiObjectList(List<AccessibilityNodeInfoCompat> compats, AccessibilityNodeInfoAllocator allocator) {
|
public static List<UiObject> compatListToUiObjectList(List<AccessibilityNodeInfoCompat> compats, AccessibilityNodeInfoAllocator allocator) {
|
||||||
|
// FIXME: 2017/11/5 lost depth info
|
||||||
List<UiObject> uiObjects = new ArrayList<>(compats.size());
|
List<UiObject> uiObjects = new ArrayList<>(compats.size());
|
||||||
for (AccessibilityNodeInfoCompat compat : compats) {
|
for (AccessibilityNodeInfoCompat compat : compats) {
|
||||||
if (compat != null)
|
if (compat != null)
|
||||||
|
|||||||
@@ -35,14 +35,6 @@ public class UiObjectCollection {
|
|||||||
return new UiObjectCollection(UiObject.compatListToUiObjectList(list));
|
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) {
|
public static UiObjectCollection of(List<UiObject> list) {
|
||||||
return new UiObjectCollection(list);
|
return new UiObjectCollection(list);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ public class NodeInfo {
|
|||||||
public CharSequence className;
|
public CharSequence className;
|
||||||
public CharSequence packageName;
|
public CharSequence packageName;
|
||||||
public CharSequence text;
|
public CharSequence text;
|
||||||
|
public int depth;
|
||||||
public int drawingOrder;
|
public int drawingOrder;
|
||||||
public boolean accessibilityFocused;
|
public boolean accessibilityFocused;
|
||||||
public boolean checked;
|
public boolean checked;
|
||||||
@@ -35,20 +36,34 @@ public class NodeInfo {
|
|||||||
public boolean enabled;
|
public boolean enabled;
|
||||||
public boolean focusable;
|
public boolean focusable;
|
||||||
public boolean longClickable;
|
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 selected;
|
||||||
public boolean scrollable;
|
public boolean scrollable;
|
||||||
public String bounds;
|
public String bounds;
|
||||||
|
|
||||||
|
|
||||||
public NodeInfo(AccessibilityNodeInfoCompat node) {
|
public NodeInfo(UiObject node) {
|
||||||
id = simplifyId(node.getViewIdResourceName());
|
id = simplifyId(node.getViewIdResourceName());
|
||||||
desc = node.getContentDescription();
|
desc = node.getContentDescription();
|
||||||
className = node.getClassName();
|
className = node.getClassName();
|
||||||
packageName = node.getPackageName();
|
packageName = node.getPackageName();
|
||||||
text = node.getText();
|
text = node.getText();
|
||||||
|
|
||||||
|
depth = node.depth();
|
||||||
drawingOrder = node.getDrawingOrder();
|
drawingOrder = node.getDrawingOrder();
|
||||||
|
|
||||||
|
row = node.row();
|
||||||
|
column = node.column();
|
||||||
|
rowCount = node.rowCount();
|
||||||
|
columnCount = node.columnCount();
|
||||||
|
rowSpan = node.rowSpan();
|
||||||
|
columnSpan = node.columnSpan();
|
||||||
|
|
||||||
accessibilityFocused = node.isAccessibilityFocused();
|
accessibilityFocused = node.isAccessibilityFocused();
|
||||||
checked = node.isChecked();
|
checked = node.isChecked();
|
||||||
clickable = node.isClickable();
|
clickable = node.isClickable();
|
||||||
@@ -80,16 +95,12 @@ public class NodeInfo {
|
|||||||
return rect.toString().replace('-', ',').replace(" ", "").substring(4);
|
return rect.toString().replace('-', ',').replace(" ", "").substring(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeInfo(AccessibilityNodeInfo node) {
|
|
||||||
this(new AccessibilityNodeInfoCompat(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public static NodeInfo capture(@NonNull UiObject parent) {
|
||||||
public static NodeInfo capture(@NonNull UiObject root) {
|
NodeInfo nodeInfo = new NodeInfo(parent);
|
||||||
NodeInfo nodeInfo = new NodeInfo(root);
|
int childCount = parent.getChildCount();
|
||||||
int childCount = root.getChildCount();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
for (int i = 0; i < childCount; i++) {
|
||||||
UiObject child = root.child(i);
|
UiObject child = parent.child(i);
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
nodeInfo.children.add(capture(child));
|
nodeInfo.children.add(capture(child));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user