Dying...
This commit is contained in:
@@ -9,6 +9,7 @@ import com.stardust.view.accessibility.AccessibilityDelegate;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -69,6 +70,11 @@ public class AccessibilityEventCommandHost implements AccessibilityDelegate {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getEventTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void executeCommand(final Command command, final AccessibilityService service, final AccessibilityEvent event) {
|
||||
final Runnable r = new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -2,18 +2,16 @@ package com.stardust.automator;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.automator.filter.BooleanFilter;
|
||||
import com.stardust.automator.filter.BoundsFilter;
|
||||
import com.stardust.automator.filter.DfsFilter;
|
||||
import com.stardust.automator.filter.IdFilter;
|
||||
import com.stardust.automator.filter.PackageNameFilter;
|
||||
import com.stardust.automator.filter.TextFilter;
|
||||
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.ListFilter;
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.filter.PackageNameFilter;
|
||||
import com.stardust.automator.filter.TextFilter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
@@ -173,7 +171,7 @@ public class UiGlobalSelector {
|
||||
public UiGlobalSelector drawingOrder(final int order) {
|
||||
mFilters.add(new DfsFilter() {
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && nodeInfo.getDrawingOrder() == order;
|
||||
}
|
||||
});
|
||||
@@ -352,26 +350,18 @@ public class UiGlobalSelector {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UiObjectCollection findOf(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo node) {
|
||||
List<AccessibilityNodeInfo> list = new ArrayList<>();
|
||||
public UiObjectCollection findOf(UiObject node) {
|
||||
List<UiObject> list = new ArrayList<>();
|
||||
list.add(node);
|
||||
for (ListFilter filter : mFilters) {
|
||||
list = filter.filter(allocator, list);
|
||||
list = filter.filter(list);
|
||||
}
|
||||
return UiObjectCollection.of(list);
|
||||
}
|
||||
|
||||
public UiObjectCollection findOf(AccessibilityNodeInfo node) {
|
||||
return findOf(AccessibilityNodeInfoAllocator.NONE, node);
|
||||
}
|
||||
|
||||
public UiObject findOneOf(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo node) {
|
||||
public UiObject findOneOf(UiObject node) {
|
||||
// TODO: 2017/3/9 优化
|
||||
return new UiObject(findOf(allocator, node).get(0).getInfo());
|
||||
}
|
||||
|
||||
public UiObject findOneOf(AccessibilityNodeInfo node) {
|
||||
return findOneOf(AccessibilityNodeInfoAllocator.NONE, node);
|
||||
return findOf(node).get(0);
|
||||
}
|
||||
|
||||
public UiGlobalSelector addFilter(ListFilter filter) {
|
||||
|
||||
@@ -3,12 +3,14 @@ package com.stardust.automator;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CONTEXT_CLICK;
|
||||
@@ -26,15 +28,21 @@ import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.
|
||||
|
||||
public class UiObject extends AccessibilityNodeInfoCompat {
|
||||
|
||||
private static final String TAG = "UiObject";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private AccessibilityNodeInfoAllocator mAllocator = null;
|
||||
private String mStackTrace = "";
|
||||
|
||||
public UiObject(Object info) {
|
||||
super(info);
|
||||
this(info, null);
|
||||
}
|
||||
|
||||
public UiObject(Object info, AccessibilityNodeInfoAllocator allocator) {
|
||||
super(info);
|
||||
mAllocator = allocator;
|
||||
if (DEBUG)
|
||||
mStackTrace = Arrays.toString(Thread.currentThread().getStackTrace());
|
||||
}
|
||||
|
||||
public UiObject parent() {
|
||||
@@ -46,11 +54,11 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
||||
}
|
||||
|
||||
public UiObjectCollection find(UiGlobalSelector selector) {
|
||||
return selector.findOf((AccessibilityNodeInfo) getInfo());
|
||||
return selector.findOf(this);
|
||||
}
|
||||
|
||||
public UiObject findOne(UiGlobalSelector selector) {
|
||||
return selector.findOneOf((AccessibilityNodeInfo) getInfo());
|
||||
return selector.findOneOf(this);
|
||||
}
|
||||
|
||||
public UiObjectCollection children() {
|
||||
@@ -237,6 +245,10 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
||||
return mAllocator.findAccessibilityNodeInfosByText(this, text);
|
||||
}
|
||||
|
||||
public List<UiObject> findByText(String text) {
|
||||
return compatListToUiObjectList(findAccessibilityNodeInfosByText(text), mAllocator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(String viewId) {
|
||||
if (mAllocator == null)
|
||||
@@ -244,5 +256,37 @@ public class UiObject extends AccessibilityNodeInfoCompat {
|
||||
return mAllocator.findAccessibilityNodeInfosByViewId(this, viewId);
|
||||
}
|
||||
|
||||
public List<UiObject> findByViewId(String viewId) {
|
||||
return compatListToUiObjectList(findAccessibilityNodeInfosByViewId(viewId), mAllocator);
|
||||
}
|
||||
|
||||
public static List<UiObject> compatListToUiObjectList(List<AccessibilityNodeInfoCompat> compats, AccessibilityNodeInfoAllocator allocator) {
|
||||
List<UiObject> uiObjects = new ArrayList<>(compats.size());
|
||||
for (AccessibilityNodeInfoCompat compat : compats) {
|
||||
uiObjects.add(new UiObject(compat.getInfo(), allocator));
|
||||
}
|
||||
return uiObjects;
|
||||
}
|
||||
|
||||
public static List<UiObject> compatListToUiObjectList(List<AccessibilityNodeInfoCompat> compats) {
|
||||
return compatListToUiObjectList(compats, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
try {
|
||||
super.recycle();
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, mStackTrace, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
super.recycle();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,28 +26,30 @@ import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.
|
||||
public class UiObjectCollection {
|
||||
|
||||
public static UiObjectCollection ofCompat(List<AccessibilityNodeInfoCompat> list) {
|
||||
return new UiObjectCollection(list);
|
||||
return new UiObjectCollection(UiObject.compatListToUiObjectList(list));
|
||||
}
|
||||
|
||||
public static UiObjectCollection of(List<AccessibilityNodeInfo> list) {
|
||||
List<AccessibilityNodeInfoCompat> compatList = new ArrayList<>(list.size());
|
||||
public static UiObjectCollection ofInfo(List<AccessibilityNodeInfo> list) {
|
||||
List<UiObject> compatList = new ArrayList<>(list.size());
|
||||
for (AccessibilityNodeInfo nodeInfo : list) {
|
||||
compatList.add(new AccessibilityNodeInfoCompat(nodeInfo));
|
||||
compatList.add(new UiObject(nodeInfo));
|
||||
}
|
||||
return new UiObjectCollection(compatList);
|
||||
}
|
||||
|
||||
private List<AccessibilityNodeInfoCompat> mNodes;
|
||||
private UiObject[] mUiObjects;
|
||||
public static UiObjectCollection of(List<UiObject> list) {
|
||||
return new UiObjectCollection(list);
|
||||
}
|
||||
|
||||
private List<UiObject> mNodes;
|
||||
|
||||
private UiObjectCollection(List<AccessibilityNodeInfoCompat> list) {
|
||||
private UiObjectCollection(List<UiObject> list) {
|
||||
mNodes = list;
|
||||
}
|
||||
|
||||
public boolean performAction(int action) {
|
||||
boolean fail = false;
|
||||
for (AccessibilityNodeInfoCompat node : mNodes) {
|
||||
for (UiObject node : mNodes) {
|
||||
if (!node.performAction(action)) {
|
||||
fail = true;
|
||||
}
|
||||
@@ -58,7 +60,7 @@ public class UiObjectCollection {
|
||||
public boolean performAction(int action, ActionArgument... arguments) {
|
||||
boolean fail = false;
|
||||
Bundle bundle = argumentsToBundle(arguments);
|
||||
for (AccessibilityNodeInfoCompat node : mNodes) {
|
||||
for (UiObject node : mNodes) {
|
||||
if (!node.performAction(action, bundle)) {
|
||||
fail = true;
|
||||
}
|
||||
@@ -182,18 +184,7 @@ public class UiObjectCollection {
|
||||
}
|
||||
|
||||
public UiObject get(int i) {
|
||||
ensureUiObjectAt(i);
|
||||
return mUiObjects[i];
|
||||
}
|
||||
|
||||
|
||||
private void ensureUiObjectAt(int i) {
|
||||
if (mUiObjects == null) {
|
||||
mUiObjects = new UiObject[mNodes.size()];
|
||||
}
|
||||
if (mUiObjects[i] == null) {
|
||||
mUiObjects[i] = new UiObject(mNodes.get(i).getInfo());
|
||||
}
|
||||
return mNodes.get(i);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
@@ -201,9 +192,8 @@ public class UiObjectCollection {
|
||||
}
|
||||
|
||||
public UiObjectCollection each(Consumer<UiObject> consumer) {
|
||||
for (int i = 0; i < mNodes.size(); i++) {
|
||||
ensureUiObjectAt(i);
|
||||
consumer.accept(mUiObjects[i]);
|
||||
for (UiObject uiObject : mNodes) {
|
||||
consumer.accept(uiObject);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ package com.stardust.automator.filter;
|
||||
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -31,14 +32,14 @@ public class BooleanFilter extends DfsFilter {
|
||||
|
||||
public interface BooleanSupplier {
|
||||
|
||||
boolean get(AccessibilityNodeInfo node);
|
||||
boolean get(UiObject node);
|
||||
|
||||
}
|
||||
|
||||
public static final BooleanSupplier CHECKABLE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isCheckable();
|
||||
}
|
||||
};
|
||||
@@ -46,7 +47,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier CHECKED = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isChecked();
|
||||
}
|
||||
};
|
||||
@@ -54,7 +55,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier FOCUSABLE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isFocusable();
|
||||
}
|
||||
};
|
||||
@@ -62,7 +63,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier FOCUSED = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isFocused();
|
||||
}
|
||||
};
|
||||
@@ -70,7 +71,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier VISIBLE_TO_USER = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isVisibleToUser();
|
||||
}
|
||||
};
|
||||
@@ -78,7 +79,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier ACCESSIBILITY_FOCUSED = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isAccessibilityFocused();
|
||||
}
|
||||
};
|
||||
@@ -86,7 +87,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier SELECTED = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isSelected();
|
||||
}
|
||||
};
|
||||
@@ -94,7 +95,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier CLICKABLE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isClickable();
|
||||
}
|
||||
};
|
||||
@@ -102,7 +103,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier LONG_CLICKABLE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isLongClickable();
|
||||
}
|
||||
};
|
||||
@@ -110,7 +111,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier ENABLED = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isEnabled();
|
||||
}
|
||||
};
|
||||
@@ -119,7 +120,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier PASSWORD = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isPassword();
|
||||
}
|
||||
};
|
||||
@@ -127,7 +128,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier SCROLLABLE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isScrollable();
|
||||
}
|
||||
};
|
||||
@@ -135,14 +136,14 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier EDITABLE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isEditable();
|
||||
}
|
||||
};
|
||||
public static final BooleanSupplier CONTENT_INVALID = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isContentInvalid();
|
||||
}
|
||||
};
|
||||
@@ -151,7 +152,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isContextClickable();
|
||||
}
|
||||
};
|
||||
@@ -159,7 +160,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier MULTI_LINE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isMultiLine();
|
||||
}
|
||||
};
|
||||
@@ -167,7 +168,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
public static final BooleanSupplier DISMISSABLE = new BooleanSupplier() {
|
||||
|
||||
@Override
|
||||
public boolean get(AccessibilityNodeInfo node) {
|
||||
public boolean get(UiObject node) {
|
||||
return node.isDismissable();
|
||||
}
|
||||
};
|
||||
@@ -181,7 +182,7 @@ public class BooleanFilter extends DfsFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
return nodeInfo != null && mBooleanSupplier.get(nodeInfo) == mExceptedValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.automator.UiObject;
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoHelper;
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ public class BoundsFilter extends DfsFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
if (mType == TYPE_CONTAINS) {
|
||||
return AccessibilityNodeInfoHelper.getBoundsInScreen(nodeInfo).contains(mBounds);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -10,7 +10,7 @@ public class ClassNameFilter {
|
||||
|
||||
private static final KeyGetter CLASS_NAME_GETTER = new KeyGetter() {
|
||||
@Override
|
||||
public String getKey(AccessibilityNodeInfo nodeInfo) {
|
||||
public String getKey(UiObject nodeInfo) {
|
||||
CharSequence charSequence = nodeInfo.getClassName();
|
||||
return charSequence == null ? null : charSequence.toString();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -10,7 +10,7 @@ public class DescFilter {
|
||||
|
||||
private static final KeyGetter DESC_GETTER = new KeyGetter() {
|
||||
@Override
|
||||
public String getKey(AccessibilityNodeInfo nodeInfo) {
|
||||
public String getKey(UiObject nodeInfo) {
|
||||
CharSequence charSequence = nodeInfo.getContentDescription();
|
||||
return charSequence == null ? null : charSequence.toString();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -14,41 +12,41 @@ import java.util.List;
|
||||
public abstract class DfsFilter implements ListFilter, Filter {
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, List<AccessibilityNodeInfo> nodes) {
|
||||
ArrayList<AccessibilityNodeInfo> list = new ArrayList<>();
|
||||
for (AccessibilityNodeInfo node : nodes) {
|
||||
public List<UiObject> filter(List<UiObject> nodes) {
|
||||
ArrayList<UiObject> list = new ArrayList<>();
|
||||
for (UiObject node : nodes) {
|
||||
if (isIncluded(node)) {
|
||||
list.add(node);
|
||||
}
|
||||
filterChildren(allocator, node, list);
|
||||
filterChildren(node, list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo node) {
|
||||
ArrayList<AccessibilityNodeInfo> list = new ArrayList<>();
|
||||
public List<UiObject> filter(UiObject node) {
|
||||
ArrayList<UiObject> list = new ArrayList<>();
|
||||
if (isIncluded(node)) {
|
||||
list.add(node);
|
||||
}
|
||||
filterChildren(allocator, node, list);
|
||||
filterChildren(node, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private void filterChildren(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo parent, List<AccessibilityNodeInfo> list) {
|
||||
private void filterChildren(UiObject parent, List<UiObject> list) {
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
AccessibilityNodeInfo child = allocator.getChild(parent, i);
|
||||
UiObject child = parent.child(i);
|
||||
if (child == null)
|
||||
continue;
|
||||
boolean included = isIncluded(child);
|
||||
if (included) {
|
||||
list.add(child);
|
||||
}
|
||||
filterChildren(allocator, child, list);
|
||||
filterChildren(child, list);
|
||||
if (!included) {
|
||||
child.recycle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isIncluded(AccessibilityNodeInfo nodeInfo);
|
||||
protected abstract boolean isIncluded(UiObject nodeInfo);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -12,6 +10,6 @@ import java.util.List;
|
||||
|
||||
public interface Filter {
|
||||
|
||||
List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo node);
|
||||
List<UiObject> filter(UiObject node);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -15,7 +13,7 @@ public class IdFilter extends ListFilter.Default {
|
||||
private static final KeyGetter ID_GETTER = new KeyGetter() {
|
||||
|
||||
@Override
|
||||
public String getKey(AccessibilityNodeInfo nodeInfo) {
|
||||
public String getKey(UiObject nodeInfo) {
|
||||
return nodeInfo.getViewIdResourceName();
|
||||
}
|
||||
};
|
||||
@@ -47,8 +45,8 @@ public class IdFilter extends ListFilter.Default {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo node) {
|
||||
return allocator.findAccessibilityNodeInfosByViewId(node, mId);
|
||||
public List<UiObject> filter(UiObject node) {
|
||||
return node.findByViewId(mId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -8,5 +8,5 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
public interface KeyGetter {
|
||||
|
||||
String getKey(AccessibilityNodeInfo nodeInfo);
|
||||
String getKey(UiObject nodeInfo);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -13,15 +11,15 @@ import java.util.List;
|
||||
|
||||
public interface ListFilter {
|
||||
|
||||
List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, List<AccessibilityNodeInfo> nodes);
|
||||
List<UiObject> filter(List<UiObject> nodes);
|
||||
|
||||
abstract class Default implements Filter, ListFilter {
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, List<AccessibilityNodeInfo> nodes) {
|
||||
List<AccessibilityNodeInfo> list = new ArrayList<>();
|
||||
for (AccessibilityNodeInfo node : nodes) {
|
||||
list.addAll(filter(allocator, node));
|
||||
public List<UiObject> filter(List<UiObject> nodes) {
|
||||
List<UiObject> list = new ArrayList<>();
|
||||
for (UiObject node : nodes) {
|
||||
list.addAll(filter(node));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -10,7 +10,7 @@ public class PackageNameFilter {
|
||||
|
||||
private static final KeyGetter PACKAGE_NAME_GETTER = new KeyGetter() {
|
||||
@Override
|
||||
public String getKey(AccessibilityNodeInfo nodeInfo) {
|
||||
public String getKey(UiObject nodeInfo) {
|
||||
CharSequence charSequence = nodeInfo.getPackageName();
|
||||
return charSequence == null ? null : charSequence.toString();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -16,7 +16,7 @@ public class StringContainsFilter extends DfsFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
String key = mKeyGetter.getKey(nodeInfo);
|
||||
return key != null && key.contains(mContains);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -17,7 +17,7 @@ public class StringEndsWithFilter extends DfsFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
String key = mKeyGetter.getKey(nodeInfo);
|
||||
return key != null && key.endsWith(mSuffix);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -17,7 +17,7 @@ public class StringEqualsFilter extends DfsFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
String key = mKeyGetter.getKey(nodeInfo);
|
||||
if(key != null){
|
||||
return key.equals(mText);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -17,7 +17,7 @@ public class StringMatchesFilter extends DfsFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
String key = mKeyGetter.getKey(nodeInfo);
|
||||
return key != null && key.matches(mRegex);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
@@ -17,7 +17,7 @@ public class StringStartsWithFilter extends DfsFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncluded(AccessibilityNodeInfo nodeInfo) {
|
||||
protected boolean isIncluded(UiObject nodeInfo) {
|
||||
String key = mKeyGetter.getKey(nodeInfo);
|
||||
return key != null && key.startsWith(mPrefix);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.stardust.automator.filter;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -14,7 +12,7 @@ public class TextFilter extends ListFilter.Default {
|
||||
|
||||
private static final KeyGetter TEXT_GETTER = new KeyGetter() {
|
||||
@Override
|
||||
public String getKey(AccessibilityNodeInfo nodeInfo) {
|
||||
public String getKey(UiObject nodeInfo) {
|
||||
CharSequence charSequence = nodeInfo.getText();
|
||||
return charSequence == null ? null : charSequence.toString();
|
||||
}
|
||||
@@ -48,7 +46,7 @@ public class TextFilter extends ListFilter.Default {
|
||||
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo node) {
|
||||
return allocator.findAccessibilityNodeInfosByText(node, mText);
|
||||
public List<UiObject> filter(UiObject node) {
|
||||
return node.findByText(mText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.stardust.automator.simple_action;
|
||||
import android.util.SparseArray;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.automator.UiObject;
|
||||
import com.stardust.util.SparseArrayEntries;
|
||||
|
||||
/**
|
||||
@@ -14,36 +15,36 @@ public interface Able {
|
||||
SparseArray<Able> ABLE_MAP = new SparseArrayEntries<Able>()
|
||||
.entry(AccessibilityNodeInfo.ACTION_CLICK, new Able() {
|
||||
@Override
|
||||
public boolean isAble(AccessibilityNodeInfo nodeInfo) {
|
||||
public boolean isAble(UiObject nodeInfo) {
|
||||
return nodeInfo.isClickable();
|
||||
}
|
||||
})
|
||||
.entry(AccessibilityNodeInfo.ACTION_LONG_CLICK, new Able() {
|
||||
@Override
|
||||
public boolean isAble(AccessibilityNodeInfo nodeInfo) {
|
||||
public boolean isAble(UiObject nodeInfo) {
|
||||
return nodeInfo.isLongClickable();
|
||||
}
|
||||
})
|
||||
.entry(AccessibilityNodeInfo.ACTION_FOCUS, new Able() {
|
||||
@Override
|
||||
public boolean isAble(AccessibilityNodeInfo nodeInfo) {
|
||||
public boolean isAble(UiObject nodeInfo) {
|
||||
return nodeInfo.isFocusable();
|
||||
}
|
||||
})
|
||||
.entry(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, new Able() {
|
||||
@Override
|
||||
public boolean isAble(AccessibilityNodeInfo nodeInfo) {
|
||||
public boolean isAble(UiObject nodeInfo) {
|
||||
return nodeInfo.isScrollable();
|
||||
}
|
||||
})
|
||||
.entry(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, new Able() {
|
||||
@Override
|
||||
public boolean isAble(AccessibilityNodeInfo nodeInfo) {
|
||||
public boolean isAble(UiObject nodeInfo) {
|
||||
return nodeInfo.isScrollable();
|
||||
}
|
||||
})
|
||||
.sparseArray();
|
||||
|
||||
boolean isAble(AccessibilityNodeInfo node);
|
||||
boolean isAble(UiObject node);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.os.Bundle;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.automator.UiObject;
|
||||
import com.stardust.util.MapEntries;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -45,7 +46,7 @@ public class ActionFactory {
|
||||
return new SearchTargetAction(action, new FilterAction.EditableFilter(index)) {
|
||||
|
||||
@Override
|
||||
protected void performAction(AccessibilityNodeInfo node) {
|
||||
protected void performAction(UiObject node) {
|
||||
Bundle args = new Bundle();
|
||||
args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
|
||||
node.performAction(getAction(), args);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.stardust.automator.simple_action;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
@@ -20,16 +18,16 @@ public class DepthFirstSearchTargetAction extends SearchTargetAction {
|
||||
|
||||
|
||||
@Override
|
||||
public AccessibilityNodeInfo searchTarget(AccessibilityNodeInfo n) {
|
||||
public UiObject searchTarget(UiObject n) {
|
||||
if (n == null)
|
||||
return null;
|
||||
if (mAble.isAble(n))
|
||||
return n;
|
||||
for (int i = 0; i < n.getChildCount(); i++) {
|
||||
AccessibilityNodeInfo child = getAllocator().getChild(n, i);
|
||||
UiObject child = n.child(i);
|
||||
if (child == null)
|
||||
continue;
|
||||
AccessibilityNodeInfo node = searchTarget(child);
|
||||
UiObject node = searchTarget(child);
|
||||
if (node != null)
|
||||
return node;
|
||||
else
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.stardust.automator.simple_action;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
@@ -18,7 +17,7 @@ public abstract class FilterAction extends SimpleAction {
|
||||
|
||||
public interface Filter {
|
||||
|
||||
List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo root);
|
||||
List<UiObject> filter(UiObject root);
|
||||
}
|
||||
|
||||
public static class TextFilter implements Filter {
|
||||
@@ -32,8 +31,8 @@ public abstract class FilterAction extends SimpleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo root) {
|
||||
List<AccessibilityNodeInfo> list = allocator.findAccessibilityNodeInfosByText(root, mText);
|
||||
public List<UiObject> filter(UiObject root) {
|
||||
List<UiObject> list = root.findByText(mText);
|
||||
if (mIndex == -1)
|
||||
return list;
|
||||
if (mIndex >= list.size())
|
||||
@@ -59,11 +58,11 @@ public abstract class FilterAction extends SimpleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo root) {
|
||||
return Collections.singletonList(findAccessibilityNodeInfosByBounds(allocator, root));
|
||||
public List<UiObject> filter(UiObject root) {
|
||||
return Collections.singletonList(findAccessibilityNodeInfosByBounds(root));
|
||||
}
|
||||
|
||||
private AccessibilityNodeInfo findAccessibilityNodeInfosByBounds(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo root) {
|
||||
private UiObject findAccessibilityNodeInfosByBounds(UiObject root) {
|
||||
if (root == null)
|
||||
return null;
|
||||
Rect rect = new Rect();
|
||||
@@ -72,10 +71,10 @@ public abstract class FilterAction extends SimpleAction {
|
||||
return root;
|
||||
}
|
||||
for (int i = 0; i < root.getChildCount(); i++) {
|
||||
AccessibilityNodeInfo child = allocator.getChild(root, i);
|
||||
UiObject child = root.child(i);
|
||||
if (child == null)
|
||||
continue;
|
||||
AccessibilityNodeInfo nodeInfo = findAccessibilityNodeInfosByBounds(allocator, child);
|
||||
UiObject nodeInfo = findAccessibilityNodeInfosByBounds(child);
|
||||
if (nodeInfo != null)
|
||||
return nodeInfo;
|
||||
else
|
||||
@@ -101,8 +100,8 @@ public abstract class FilterAction extends SimpleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo root) {
|
||||
List<AccessibilityNodeInfo> editableList = findEditable(allocator, root);
|
||||
public List<UiObject> filter(UiObject root) {
|
||||
List<UiObject> editableList = findEditable(root);
|
||||
if (mIndex == -1)
|
||||
return editableList;
|
||||
if (mIndex >= editableList.size())
|
||||
@@ -110,16 +109,16 @@ public abstract class FilterAction extends SimpleAction {
|
||||
return Collections.singletonList(editableList.get(mIndex));
|
||||
}
|
||||
|
||||
public static List<AccessibilityNodeInfo> findEditable(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo root) {
|
||||
public static List<UiObject> findEditable(UiObject root) {
|
||||
if (root == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (root.isEditable()) {
|
||||
return Collections.singletonList(root);
|
||||
}
|
||||
List<AccessibilityNodeInfo> list = new LinkedList<>();
|
||||
List<UiObject> list = new LinkedList<>();
|
||||
for (int i = 0; i < root.getChildCount(); i++) {
|
||||
list.addAll(findEditable(allocator, allocator.getChild(root, i)));
|
||||
list.addAll(findEditable(root.child(i)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -141,8 +140,8 @@ public abstract class FilterAction extends SimpleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccessibilityNodeInfo> filter(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo root) {
|
||||
return allocator.findAccessibilityNodeInfosByViewId(root, mId);
|
||||
public List<UiObject> filter(UiObject root) {
|
||||
return root.findByViewId(mId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,16 +159,15 @@ public abstract class FilterAction extends SimpleAction {
|
||||
mFilter = filter;
|
||||
}
|
||||
|
||||
public boolean perform(AccessibilityNodeInfo root) {
|
||||
@Override
|
||||
public boolean perform(UiObject root) {
|
||||
if (root == null)
|
||||
return false;
|
||||
List<AccessibilityNodeInfo> list = mFilter.filter(getAllocator(), root);
|
||||
boolean succeed = perform(list);
|
||||
AccessibilityNodeInfoAllocator.recycleList(root, list);
|
||||
return succeed;
|
||||
List<UiObject> list = mFilter.filter(root);
|
||||
return perform(list);
|
||||
}
|
||||
|
||||
public abstract boolean perform(List<AccessibilityNodeInfo> nodes);
|
||||
public abstract boolean perform(List<UiObject> nodes);
|
||||
|
||||
public static class SimpleFilterAction extends FilterAction {
|
||||
|
||||
@@ -181,11 +179,11 @@ public abstract class FilterAction extends SimpleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean perform(List<AccessibilityNodeInfo> nodes) {
|
||||
public boolean perform(List<UiObject> nodes) {
|
||||
if (nodes == null || nodes.isEmpty())
|
||||
return false;
|
||||
boolean succeed = true;
|
||||
for (AccessibilityNodeInfo nodeInfo : nodes) {
|
||||
for (UiObject nodeInfo : nodes) {
|
||||
if (!nodeInfo.performAction(mAction)) {
|
||||
succeed = false;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.stardust.automator.simple_action;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -20,27 +18,27 @@ public class ScrollAction extends SimpleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean perform(AccessibilityNodeInfo root) {
|
||||
List<AccessibilityNodeInfo> scrollableNodes = findScrollableNodes(root);
|
||||
public boolean perform(UiObject root) {
|
||||
List<UiObject> scrollableNodes = findScrollableNodes(root);
|
||||
boolean result = mIndex < scrollableNodes.size() && scrollableNodes.get(mIndex).performAction(mAction);
|
||||
recycle(scrollableNodes, root);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void recycle(List<AccessibilityNodeInfo> list, AccessibilityNodeInfo root) {
|
||||
for (AccessibilityNodeInfo nodeInfo : list) {
|
||||
private void recycle(List<UiObject> list, UiObject root) {
|
||||
for (UiObject nodeInfo : list) {
|
||||
if (nodeInfo != root)
|
||||
nodeInfo.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
private List<AccessibilityNodeInfo> findScrollableNodes(AccessibilityNodeInfo root) {
|
||||
List<AccessibilityNodeInfo> list = new ArrayList<>();
|
||||
findScrollableNodes(getAllocator(), root, list);
|
||||
private List<UiObject> findScrollableNodes(UiObject root) {
|
||||
List<UiObject> list = new ArrayList<>();
|
||||
findScrollableNodes(root, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static boolean findScrollableNodes(AccessibilityNodeInfoAllocator allocator, AccessibilityNodeInfo node, List<AccessibilityNodeInfo> list) {
|
||||
private static boolean findScrollableNodes(UiObject node, List<UiObject> list) {
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -48,10 +46,10 @@ public class ScrollAction extends SimpleAction {
|
||||
list.add(node);
|
||||
}
|
||||
for (int i = 0; i < node.getChildCount(); i++) {
|
||||
AccessibilityNodeInfo child = allocator.getChild(node, i);
|
||||
UiObject child = node.child(i);
|
||||
if (child == null)
|
||||
continue;
|
||||
if (!findScrollableNodes(allocator, child, list))
|
||||
if (!findScrollableNodes(child, list))
|
||||
child.recycle();
|
||||
}
|
||||
return node.isScrollable();
|
||||
|
||||
@@ -2,9 +2,8 @@ package com.stardust.automator.simple_action;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
@@ -14,15 +13,15 @@ public class ScrollMaxAction extends SimpleAction {
|
||||
|
||||
private static final String TAG = ScrollMaxAction.class.getSimpleName();
|
||||
private int mScrollAction;
|
||||
private AccessibilityNodeInfo mMaxScrollableNode;
|
||||
private AccessibilityNodeInfo mRootNode;
|
||||
private UiObject mMaxScrollableNode;
|
||||
private UiObject mRootNode;
|
||||
|
||||
public ScrollMaxAction(int scrollAction) {
|
||||
mScrollAction = scrollAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean perform(AccessibilityNodeInfo rootNodeInfo) {
|
||||
public boolean perform(UiObject rootNodeInfo) {
|
||||
reset();
|
||||
mRootNode = rootNodeInfo;
|
||||
findMaxScrollableNodeInfo(rootNodeInfo);
|
||||
@@ -38,7 +37,7 @@ public class ScrollMaxAction extends SimpleAction {
|
||||
mMaxScrollableNode = mRootNode = null;
|
||||
}
|
||||
|
||||
private void findMaxScrollableNodeInfo(AccessibilityNodeInfo nodeInfo) {
|
||||
private void findMaxScrollableNodeInfo(UiObject nodeInfo) {
|
||||
if (nodeInfo == null)
|
||||
return;
|
||||
if (nodeInfo.isScrollable()) {
|
||||
@@ -51,7 +50,7 @@ public class ScrollMaxAction extends SimpleAction {
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < nodeInfo.getChildCount(); i++) {
|
||||
AccessibilityNodeInfo child = getAllocator().getChild(nodeInfo, i);
|
||||
UiObject child = nodeInfo.child(i);
|
||||
if (child != null) {
|
||||
findMaxScrollableNodeInfo(child);
|
||||
if (mMaxScrollableNode != child) {
|
||||
@@ -61,7 +60,7 @@ public class ScrollMaxAction extends SimpleAction {
|
||||
}
|
||||
}
|
||||
|
||||
private long getAreaInScreen(AccessibilityNodeInfo nodeInfo) {
|
||||
private long getAreaInScreen(UiObject nodeInfo) {
|
||||
Rect rect = new Rect();
|
||||
nodeInfo.getBoundsInScreen(rect);
|
||||
long area = ((long) rect.width()) * rect.height();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.stardust.automator.simple_action;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -19,20 +19,19 @@ public abstract class SearchTargetAction extends FilterAction {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean perform(List<AccessibilityNodeInfo> nodes) {
|
||||
public boolean perform(List<UiObject> nodes) {
|
||||
boolean performed = false;
|
||||
for (AccessibilityNodeInfo node : nodes) {
|
||||
for (UiObject node : nodes) {
|
||||
node = searchTarget(node);
|
||||
if (node != null) {
|
||||
performAction(node);
|
||||
performed = true;
|
||||
node.recycle();
|
||||
}
|
||||
}
|
||||
return performed;
|
||||
}
|
||||
|
||||
protected void performAction(AccessibilityNodeInfo node) {
|
||||
protected void performAction(UiObject node) {
|
||||
node.performAction(mAction);
|
||||
}
|
||||
|
||||
@@ -40,7 +39,7 @@ public abstract class SearchTargetAction extends FilterAction {
|
||||
return mAction;
|
||||
}
|
||||
|
||||
public AccessibilityNodeInfo searchTarget(AccessibilityNodeInfo node) {
|
||||
public UiObject searchTarget(UiObject node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
package com.stardust.automator.simple_action;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
@@ -23,19 +19,16 @@ public class SearchUpTargetAction extends SearchTargetAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessibilityNodeInfo searchTarget(AccessibilityNodeInfo n) {
|
||||
AccessibilityNodeInfo node = n;
|
||||
public UiObject searchTarget(UiObject n) {
|
||||
UiObject node = n;
|
||||
int i = 0;
|
||||
List<AccessibilityNodeInfo> list = new ArrayList<>();
|
||||
while (node != null && !mAble.isAble(node)) {
|
||||
i++;
|
||||
if (i > LOOP_MAX) {
|
||||
node.recycle();
|
||||
return null;
|
||||
}
|
||||
AccessibilityNodeInfo parent = getAllocator().getParent(node);
|
||||
list.add(node);
|
||||
node = parent;
|
||||
node = node.parent();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
package com.stardust.automator.simple_action;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
|
||||
import java.util.List;
|
||||
import com.stardust.automator.UiObject;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
@@ -14,12 +8,10 @@ import java.util.List;
|
||||
|
||||
public abstract class SimpleAction {
|
||||
|
||||
|
||||
private volatile AccessibilityNodeInfoAllocator mAllocator = AccessibilityNodeInfoAllocator.NONE;
|
||||
private volatile boolean mValid = true;
|
||||
private volatile boolean mResult = false;
|
||||
|
||||
public abstract boolean perform(AccessibilityNodeInfo root);
|
||||
public abstract boolean perform(UiObject root);
|
||||
|
||||
public boolean getResult() {
|
||||
return mResult;
|
||||
@@ -37,12 +29,4 @@ public abstract class SimpleAction {
|
||||
return mValid;
|
||||
}
|
||||
|
||||
public AccessibilityNodeInfoAllocator getAllocator() {
|
||||
return mAllocator;
|
||||
}
|
||||
|
||||
public void setAllocator(@NonNull AccessibilityNodeInfoAllocator allocator) {
|
||||
mAllocator = allocator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
package com.stardust.automator.simple_action;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
import com.stardust.automator.UiObject;
|
||||
import com.stardust.view.accessibility.AccessibilityDelegate;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Vector;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -50,6 +46,11 @@ public class SimpleActionPerformHost implements AccessibilityDelegate {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getEventTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void performAction(AccessibilityNodeInfo root, SimpleAction simpleAction) {
|
||||
mExecutor.execute(new SimpleActionPerformRunnable(root, simpleAction));
|
||||
}
|
||||
@@ -78,7 +79,7 @@ public class SimpleActionPerformHost implements AccessibilityDelegate {
|
||||
return;
|
||||
}
|
||||
Log.i(TAG, "perform simpleAction: " + mSimpleAction);
|
||||
if (mSimpleAction.perform(mRoot)) {
|
||||
if (mSimpleAction.perform(new UiObject(mRoot))) {
|
||||
mSimpleAction.setResult(true);
|
||||
onActionPerformed(mSimpleAction);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package com.stardust.view.accessibility;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/14.
|
||||
*/
|
||||
@@ -12,4 +16,12 @@ public interface AccessibilityDelegate {
|
||||
|
||||
boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event);
|
||||
|
||||
/**
|
||||
* 返回调用onAccessibilityEvent时的EventType的集合。如果需要对所有EventType都有效,返回null。
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
Set<Integer> getEventTypes();
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.view.accessibility.AccessibilityDelegate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
@@ -35,10 +40,19 @@ public class AccessibilityInfoProvider implements AccessibilityDelegate {
|
||||
|
||||
@Override
|
||||
public boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event) {
|
||||
setLatestComponent(event.getPackageName(), event.getClassName());
|
||||
AccessibilityNodeInfo root = service.getRootInActiveWindow();
|
||||
if (root != null)
|
||||
setLatestComponent(root.getPackageName(), event.getClassName());
|
||||
else
|
||||
setLatestComponent(event.getPackageName(), event.getClassName());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getEventTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private synchronized void setLatestComponent(CharSequence latestPackage, CharSequence latestClass) {
|
||||
if (latestPackage == null)
|
||||
return;
|
||||
|
||||
@@ -126,13 +126,9 @@ public class AccessibilityNodeInfoAllocator {
|
||||
|
||||
public static void recycleList(AccessibilityNodeInfo root, List<AccessibilityNodeInfo> list) {
|
||||
for (AccessibilityNodeInfo nodeInfo : list) {
|
||||
if (nodeInfo != root) {
|
||||
try {
|
||||
nodeInfo.recycle();
|
||||
}catch (IllegalStateException e){
|
||||
// FIXME: 2017/4/30
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (nodeInfo != root && nodeInfo != null) {
|
||||
//// FIXME: 2017/5/1 Issue #180
|
||||
nodeInfo.recycle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.stardust.view.accessibility;
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/2.
|
||||
*/
|
||||
|
||||
public abstract class AccessibilityService extends android.accessibilityservice.AccessibilityService {
|
||||
|
||||
@Override
|
||||
public AccessibilityNodeInfo getRootInActiveWindow() {
|
||||
try {
|
||||
return super.getRootInActiveWindow();
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user