修复 选择器有多个条件时无法找到目标的问题

优化 选择器搜索效率
This commit is contained in:
hyb1996
2018-12-04 13:14:06 +08:00
parent 754819b23f
commit 4b3d4ab84c
26 changed files with 282 additions and 457 deletions

View File

@@ -1,133 +0,0 @@
package androidx.recyclerview.widget
import android.content.Context
import android.os.Build.VERSION
import android.util.AttributeSet
import android.widget.EdgeEffect
import androidx.annotation.Nullable
import androidx.core.widget.EdgeEffectCompat
import com.stardust.theme.ThemeColor
import com.stardust.theme.ThemeColorManager
import com.stardust.theme.ThemeColorMutable
import java.lang.reflect.Field
open class ThemeColorRecyclerView : RecyclerView, ThemeColorMutable {
private var mLeftGlowField: Field? = null
private var mTopGlowField: Field? = null
private var mRightGlowField: Field? = null
private var mBottomGlowField: Field? = null
private var mEdgeEffectField: Field? = null
private var mColorPrimary: Int = 0
private var hasAppliedThemeColorLeft: Boolean = false
private var hasAppliedThemeColorTop: Boolean = false
private var hasAppliedThemeColorRight: Boolean = false
private var hasAppliedThemeColorBottom: Boolean = false
constructor(context: Context) : super(context) {
this.init()
}
constructor(context: Context, @Nullable attrs: AttributeSet) : super(context, attrs) {
this.init()
}
constructor(context: Context, @Nullable attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
this.init()
}
private fun applyThemeColor(edgeEffectCompatField: Field?): Boolean {
try {
val edgeEffectCompat = edgeEffectCompatField?.get(this) as EdgeEffectCompat?
if (edgeEffectCompat != null) {
return this.setEdgeEffectColor(edgeEffectCompat, this.mColorPrimary)
}
} catch (var3: Exception) {
}
return false
}
private fun init() {
try {
this.mEdgeEffectField = EdgeEffectCompat::class.java.getDeclaredField("mEdgeEffect")
this.mEdgeEffectField!!.isAccessible = true
this.mLeftGlowField = RecyclerView::class.java.getDeclaredField("mLeftGlow")
this.mLeftGlowField!!.isAccessible = true
this.mRightGlowField = RecyclerView::class.java.getDeclaredField("mRightGlow")
this.mRightGlowField!!.isAccessible = true
this.mTopGlowField = RecyclerView::class.java.getDeclaredField("mTopGlow")
this.mTopGlowField!!.isAccessible = true
this.mBottomGlowField = RecyclerView::class.java.getDeclaredField("mBottomGlow")
this.mBottomGlowField!!.isAccessible = true
} catch (var2: Exception) {
var2.printStackTrace()
}
ThemeColorManager.add(this)
}
private fun setEdgeEffectColor(compat: EdgeEffectCompat?, color: Int): Boolean {
return if (compat == null) {
false
} else {
try {
if (VERSION.SDK_INT >= 21) {
val edgeEffect = this.mEdgeEffectField!!.get(compat) as EdgeEffect
edgeEffect.color = color
}
true
} catch (var4: Exception) {
true
}
}
}
override fun setThemeColor(color: ThemeColor) {
if (color.colorPrimary != this.mColorPrimary) {
this.mColorPrimary = color.colorPrimary
this.invalidateGlows()
}
}
internal override fun invalidateGlows() {
super.invalidateGlows()
this.hasAppliedThemeColorTop = false
this.hasAppliedThemeColorRight = this.hasAppliedThemeColorTop
this.hasAppliedThemeColorLeft = this.hasAppliedThemeColorRight
this.hasAppliedThemeColorBottom = this.hasAppliedThemeColorLeft
}
internal override fun ensureLeftGlow() {
super.ensureLeftGlow()
if (!this.hasAppliedThemeColorLeft) {
this.hasAppliedThemeColorLeft = this.applyThemeColor(this.mLeftGlowField)
}
}
internal override fun ensureRightGlow() {
super.ensureLeftGlow()
if (!this.hasAppliedThemeColorRight) {
this.hasAppliedThemeColorRight = this.applyThemeColor(this.mRightGlowField)
}
}
internal override fun ensureTopGlow() {
super.ensureTopGlow()
if (!this.hasAppliedThemeColorTop) {
this.hasAppliedThemeColorTop = this.applyThemeColor(this.mTopGlowField)
}
}
internal override fun ensureBottomGlow() {
super.ensureBottomGlow()
if (!this.hasAppliedThemeColorBottom) {
this.hasAppliedThemeColorBottom = this.applyThemeColor(this.mBottomGlowField)
}
}
}

View File

@@ -15,10 +15,12 @@ import com.stardust.automator.ActionArgument;
import com.stardust.automator.UiGlobalSelector; import com.stardust.automator.UiGlobalSelector;
import com.stardust.automator.UiObject; import com.stardust.automator.UiObject;
import com.stardust.automator.UiObjectCollection; import com.stardust.automator.UiObjectCollection;
import com.stardust.automator.filter.DfsFilter; import com.stardust.automator.filter.Filter;
import com.stardust.concurrent.VolatileBox; import com.stardust.concurrent.VolatileBox;
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator; import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
import org.jetbrains.annotations.NotNull;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE;
@@ -106,7 +108,7 @@ public class UiSelector extends UiGlobalSelector {
} }
@Override @Override
public UiGlobalSelector textMatches(String regex) { public UiGlobalSelector textMatches(@NotNull String regex) {
return super.textMatches(convertRegex(regex)); return super.textMatches(convertRegex(regex));
} }
@@ -120,22 +122,22 @@ public class UiSelector extends UiGlobalSelector {
@Override @Override
public UiGlobalSelector classNameMatches(String regex) { public UiGlobalSelector classNameMatches(@NotNull String regex) {
return super.classNameMatches(convertRegex(regex)); return super.classNameMatches(convertRegex(regex));
} }
@Override @Override
public UiGlobalSelector idMatches(String regex) { public UiGlobalSelector idMatches(@NotNull String regex) {
return super.idMatches(convertRegex(regex)); return super.idMatches(convertRegex(regex));
} }
@Override @Override
public UiGlobalSelector packageNameMatches(String regex) { public UiGlobalSelector packageNameMatches(@NotNull String regex) {
return super.packageNameMatches(convertRegex(regex)); return super.packageNameMatches(convertRegex(regex));
} }
@Override @Override
public UiGlobalSelector descMatches(String regex) { public UiGlobalSelector descMatches(@NotNull String regex) {
return super.descMatches(convertRegex(regex)); return super.descMatches(convertRegex(regex));
} }
@@ -224,13 +226,13 @@ public class UiSelector extends UiGlobalSelector {
} }
@ScriptInterface @ScriptInterface
public UiSelector id(final String id) { public UiSelector id(@NotNull final String id) {
if (!id.contains(":")) { if (!id.contains(":")) {
addFilter(new DfsFilter() { addFilter(new Filter() {
@Override @Override
protected boolean isIncluded(UiObject nodeInfo) { public boolean filter(@NotNull UiObject node) {
String fullId = mAccessibilityBridge.getInfoProvider().getLatestPackage() + ":id/" + id; String fullId = mAccessibilityBridge.getInfoProvider().getLatestPackage() + ":id/" + id;
return fullId.equals(nodeInfo.getViewIdResourceName()); return fullId.equals(node.getViewIdResourceName());
} }
@Override @Override
@@ -245,11 +247,11 @@ public class UiSelector extends UiGlobalSelector {
} }
@Override @Override
public UiGlobalSelector idStartsWith(String prefix) { public UiGlobalSelector idStartsWith(@NotNull String prefix) {
if (!prefix.contains(":")) { if (!prefix.contains(":")) {
addFilter(new DfsFilter() { addFilter(new Filter() {
@Override @Override
protected boolean isIncluded(UiObject nodeInfo) { public boolean filter(@NotNull UiObject nodeInfo) {
String fullIdPrefix = mAccessibilityBridge.getInfoProvider().getLatestPackage() + ":id/" + prefix; String fullIdPrefix = mAccessibilityBridge.getInfoProvider().getLatestPackage() + ":id/" + prefix;
String id = nodeInfo.getViewIdResourceName(); String id = nodeInfo.getViewIdResourceName();
return id != null && id.startsWith(fullIdPrefix); return id != null && id.startsWith(fullIdPrefix);

View File

@@ -2,23 +2,7 @@ package com.stardust.automator
import android.graphics.Rect import android.graphics.Rect
import android.os.Build import android.os.Build
import com.stardust.automator.filter.*
import com.stardust.automator.filter.BooleanFilter
import com.stardust.automator.filter.BoundsFilter
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
import java.util.Queue
/** /**
* Created by Stardust on 2017/3/8. * Created by Stardust on 2017/3/8.
@@ -26,154 +10,154 @@ import java.util.Queue
open class UiGlobalSelector { open class UiGlobalSelector {
private val mFilters = LinkedList<ListFilter>() private val mSelector = Selector()
//// 第一类筛选条件 //// 第一类筛选条件
open fun id(id: String): UiGlobalSelector { open fun id(id: String): UiGlobalSelector {
mFilters.add(IdFilter.equals(id)) mSelector.add(IdFilter.equals(id))
return this return this
} }
fun idContains(str: String): UiGlobalSelector { fun idContains(str: String): UiGlobalSelector {
mFilters.add(IdFilter.contains(str)) mSelector.add(IdFilter.contains(str))
return this return this
} }
open fun idStartsWith(prefix: String): UiGlobalSelector { open fun idStartsWith(prefix: String): UiGlobalSelector {
mFilters.add(IdFilter.startsWith(prefix)) mSelector.add(IdFilter.startsWith(prefix))
return this return this
} }
fun idEndsWith(suffix: String): UiGlobalSelector { fun idEndsWith(suffix: String): UiGlobalSelector {
mFilters.add(IdFilter.endsWith(suffix)) mSelector.add(IdFilter.endsWith(suffix))
return this return this
} }
open fun idMatches(regex: String): UiGlobalSelector { open fun idMatches(regex: String): UiGlobalSelector {
mFilters.add(IdFilter.matches(regex)) mSelector.add(IdFilter.matches(regex))
return this return this
} }
fun text(text: String): UiGlobalSelector { fun text(text: String): UiGlobalSelector {
mFilters.add(TextFilter.equals(text)) mSelector.add(TextFilters.equals(text))
return this return this
} }
fun textContains(str: String): UiGlobalSelector { fun textContains(str: String): UiGlobalSelector {
mFilters.add(TextFilter.contains(str)) mSelector.add(TextFilters.contains(str))
return this return this
} }
fun textStartsWith(prefix: String): UiGlobalSelector { fun textStartsWith(prefix: String): UiGlobalSelector {
mFilters.add(TextFilter.startsWith(prefix)) mSelector.add(TextFilters.startsWith(prefix))
return this return this
} }
fun textEndsWith(suffix: String): UiGlobalSelector { fun textEndsWith(suffix: String): UiGlobalSelector {
mFilters.add(TextFilter.endsWith(suffix)) mSelector.add(TextFilters.endsWith(suffix))
return this return this
} }
open fun textMatches(regex: String): UiGlobalSelector { open fun textMatches(regex: String): UiGlobalSelector {
mFilters.add(TextFilter.matches(regex)) mSelector.add(TextFilters.matches(regex))
return this return this
} }
fun desc(desc: String): UiGlobalSelector { fun desc(desc: String): UiGlobalSelector {
mFilters.add(DescFilter.equals(desc)) mSelector.add(DescFilters.equals(desc))
return this return this
} }
fun descContains(str: String): UiGlobalSelector { fun descContains(str: String): UiGlobalSelector {
mFilters.add(DescFilter.contains(str)) mSelector.add(DescFilters.contains(str))
return this return this
} }
fun descStartsWith(prefix: String): UiGlobalSelector { fun descStartsWith(prefix: String): UiGlobalSelector {
mFilters.add(DescFilter.startsWith(prefix)) mSelector.add(DescFilters.startsWith(prefix))
return this return this
} }
fun descEndsWith(suffix: String): UiGlobalSelector { fun descEndsWith(suffix: String): UiGlobalSelector {
mFilters.add(DescFilter.endsWith(suffix)) mSelector.add(DescFilters.endsWith(suffix))
return this return this
} }
open fun descMatches(regex: String): UiGlobalSelector { open fun descMatches(regex: String): UiGlobalSelector {
mFilters.add(DescFilter.matches(regex)) mSelector.add(DescFilters.matches(regex))
return this return this
} }
fun className(className: String): UiGlobalSelector { fun className(className: String): UiGlobalSelector {
mFilters.add(ClassNameFilter.equals(className)) mSelector.add(ClassNameFilters.equals(className))
return this return this
} }
fun classNameContains(str: String): UiGlobalSelector { fun classNameContains(str: String): UiGlobalSelector {
mFilters.add(ClassNameFilter.contains(str)) mSelector.add(ClassNameFilters.contains(str))
return this return this
} }
fun classNameStartsWith(prefix: String): UiGlobalSelector { fun classNameStartsWith(prefix: String): UiGlobalSelector {
mFilters.add(ClassNameFilter.startsWith(prefix)) mSelector.add(ClassNameFilters.startsWith(prefix))
return this return this
} }
fun classNameEndsWith(suffix: String): UiGlobalSelector { fun classNameEndsWith(suffix: String): UiGlobalSelector {
mFilters.add(ClassNameFilter.endsWith(suffix)) mSelector.add(ClassNameFilters.endsWith(suffix))
return this return this
} }
open fun classNameMatches(regex: String): UiGlobalSelector { open fun classNameMatches(regex: String): UiGlobalSelector {
mFilters.add(ClassNameFilter.matches(regex)) mSelector.add(ClassNameFilters.matches(regex))
return this return this
} }
fun packageName(packageName: String): UiGlobalSelector { fun packageName(packageName: String): UiGlobalSelector {
mFilters.add(PackageNameFilter.equals(packageName)) mSelector.add(PackageNameFilter.equals(packageName))
return this return this
} }
fun packageNameContains(str: String): UiGlobalSelector { fun packageNameContains(str: String): UiGlobalSelector {
mFilters.add(PackageNameFilter.contains(str)) mSelector.add(PackageNameFilter.contains(str))
return this return this
} }
fun packageNameStartsWith(prefix: String): UiGlobalSelector { fun packageNameStartsWith(prefix: String): UiGlobalSelector {
mFilters.add(PackageNameFilter.startsWith(prefix)) mSelector.add(PackageNameFilter.startsWith(prefix))
return this return this
} }
fun packageNameEndsWith(suffix: String): UiGlobalSelector { fun packageNameEndsWith(suffix: String): UiGlobalSelector {
mFilters.add(PackageNameFilter.endsWith(suffix)) mSelector.add(PackageNameFilter.endsWith(suffix))
return this return this
} }
open fun packageNameMatches(regex: String): UiGlobalSelector { open fun packageNameMatches(regex: String): UiGlobalSelector {
mFilters.add(PackageNameFilter.matches(regex)) mSelector.add(PackageNameFilter.matches(regex))
return this return this
} }
fun bounds(l: Int, t: Int, r: Int, b: Int): UiGlobalSelector { fun bounds(l: Int, t: Int, r: Int, b: Int): UiGlobalSelector {
mFilters.add(BoundsFilter(Rect(l, t, r, b), BoundsFilter.TYPE_EQUALS)) mSelector.add(BoundsFilter(Rect(l, t, r, b), BoundsFilter.TYPE_EQUALS))
return this return this
} }
fun boundsInside(l: Int, t: Int, r: Int, b: Int): UiGlobalSelector { fun boundsInside(l: Int, t: Int, r: Int, b: Int): UiGlobalSelector {
mFilters.add(BoundsFilter(Rect(l, t, r, b), BoundsFilter.TYPE_INSIDE)) mSelector.add(BoundsFilter(Rect(l, t, r, b), BoundsFilter.TYPE_INSIDE))
return this return this
} }
fun boundsContains(l: Int, t: Int, r: Int, b: Int): UiGlobalSelector { fun boundsContains(l: Int, t: Int, r: Int, b: Int): UiGlobalSelector {
mFilters.add(BoundsFilter(Rect(l, t, r, b), BoundsFilter.TYPE_CONTAINS)) mSelector.add(BoundsFilter(Rect(l, t, r, b), BoundsFilter.TYPE_CONTAINS))
return this return this
} }
fun drawingOrder(order: Int): UiGlobalSelector { fun drawingOrder(order: Int): UiGlobalSelector {
mFilters.add(object : DfsFilter() { mSelector.add(object : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && nodeInfo.drawingOrder == order return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && node.drawingOrder == order
} }
override fun toString(): String { override fun toString(): String {
@@ -186,222 +170,222 @@ open class UiGlobalSelector {
//// 第二类筛选条件 -able //// 第二类筛选条件 -able
fun checkable(b: Boolean): UiGlobalSelector { fun checkable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CHECKABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.CHECKABLE, b])
return this return this
} }
fun checked(b: Boolean): UiGlobalSelector { fun checked(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CHECKED, b]) mSelector.add(BooleanFilter[BooleanFilter.CHECKED, b])
return this return this
} }
fun focusable(b: Boolean): UiGlobalSelector { fun focusable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.FOCUSABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.FOCUSABLE, b])
return this return this
} }
fun focused(b: Boolean): UiGlobalSelector { fun focused(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.FOCUSED, b]) mSelector.add(BooleanFilter[BooleanFilter.FOCUSED, b])
return this return this
} }
fun visibleToUser(b: Boolean): UiGlobalSelector { fun visibleToUser(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.VISIBLE_TO_USER, b]) mSelector.add(BooleanFilter[BooleanFilter.VISIBLE_TO_USER, b])
return this return this
} }
fun accessibilityFocused(b: Boolean): UiGlobalSelector { fun accessibilityFocused(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.ACCESSIBILITY_FOCUSED, b]) mSelector.add(BooleanFilter[BooleanFilter.ACCESSIBILITY_FOCUSED, b])
return this return this
} }
fun selected(b: Boolean): UiGlobalSelector { fun selected(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.SELECTED, b]) mSelector.add(BooleanFilter[BooleanFilter.SELECTED, b])
return this return this
} }
fun clickable(b: Boolean): UiGlobalSelector { fun clickable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CLICKABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.CLICKABLE, b])
return this return this
} }
fun longClickable(b: Boolean): UiGlobalSelector { fun longClickable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.LONG_CLICKABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.LONG_CLICKABLE, b])
return this return this
} }
fun enabled(b: Boolean): UiGlobalSelector { fun enabled(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.ENABLED, b]) mSelector.add(BooleanFilter[BooleanFilter.ENABLED, b])
return this return this
} }
fun password(b: Boolean): UiGlobalSelector { fun password(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.PASSWORD, b]) mSelector.add(BooleanFilter[BooleanFilter.PASSWORD, b])
return this return this
} }
fun scrollable(b: Boolean): UiGlobalSelector { fun scrollable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.SCROLLABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.SCROLLABLE, b])
return this return this
} }
fun editable(b: Boolean): UiGlobalSelector { fun editable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.EDITABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.EDITABLE, b])
return this return this
} }
fun contentInvalid(b: Boolean): UiGlobalSelector { fun contentInvalid(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CONTENT_INVALID, b]) mSelector.add(BooleanFilter[BooleanFilter.CONTENT_INVALID, b])
return this return this
} }
fun contextClickable(b: Boolean): UiGlobalSelector { fun contextClickable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CONTEXT_CLICKABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.CONTEXT_CLICKABLE, b])
return this return this
} }
fun multiLine(b: Boolean): UiGlobalSelector { fun multiLine(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.MULTI_LINE, b]) mSelector.add(BooleanFilter[BooleanFilter.MULTI_LINE, b])
return this return this
} }
fun dismissable(b: Boolean): UiGlobalSelector { fun dismissable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.DISMISSABLE, b]) mSelector.add(BooleanFilter[BooleanFilter.DISMISSABLE, b])
return this return this
} }
fun checkable(): UiGlobalSelector { fun checkable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CHECKABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.CHECKABLE, true])
return this return this
} }
fun checked(): UiGlobalSelector { fun checked(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CHECKED, true]) mSelector.add(BooleanFilter[BooleanFilter.CHECKED, true])
return this return this
} }
fun focusable(): UiGlobalSelector { fun focusable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.FOCUSABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.FOCUSABLE, true])
return this return this
} }
fun focused(): UiGlobalSelector { fun focused(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.FOCUSED, true]) mSelector.add(BooleanFilter[BooleanFilter.FOCUSED, true])
return this return this
} }
fun visibleToUser(): UiGlobalSelector { fun visibleToUser(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.VISIBLE_TO_USER, true]) mSelector.add(BooleanFilter[BooleanFilter.VISIBLE_TO_USER, true])
return this return this
} }
fun accessibilityFocused(): UiGlobalSelector { fun accessibilityFocused(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.ACCESSIBILITY_FOCUSED, true]) mSelector.add(BooleanFilter[BooleanFilter.ACCESSIBILITY_FOCUSED, true])
return this return this
} }
fun selected(): UiGlobalSelector { fun selected(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.SELECTED, true]) mSelector.add(BooleanFilter[BooleanFilter.SELECTED, true])
return this return this
} }
fun clickable(): UiGlobalSelector { fun clickable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CLICKABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.CLICKABLE, true])
return this return this
} }
fun longClickable(): UiGlobalSelector { fun longClickable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.LONG_CLICKABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.LONG_CLICKABLE, true])
return this return this
} }
fun enabled(): UiGlobalSelector { fun enabled(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.ENABLED, true]) mSelector.add(BooleanFilter[BooleanFilter.ENABLED, true])
return this return this
} }
fun password(): UiGlobalSelector { fun password(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.PASSWORD, true]) mSelector.add(BooleanFilter[BooleanFilter.PASSWORD, true])
return this return this
} }
fun scrollable(): UiGlobalSelector { fun scrollable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.SCROLLABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.SCROLLABLE, true])
return this return this
} }
fun editable(): UiGlobalSelector { fun editable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.EDITABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.EDITABLE, true])
return this return this
} }
fun contentInvalid(): UiGlobalSelector { fun contentInvalid(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CONTENT_INVALID, true]) mSelector.add(BooleanFilter[BooleanFilter.CONTENT_INVALID, true])
return this return this
} }
fun contextClickable(): UiGlobalSelector { fun contextClickable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.CONTEXT_CLICKABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.CONTEXT_CLICKABLE, true])
return this return this
} }
fun multiLine(): UiGlobalSelector { fun multiLine(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.MULTI_LINE, true]) mSelector.add(BooleanFilter[BooleanFilter.MULTI_LINE, true])
return this return this
} }
fun dismissable(): UiGlobalSelector { fun dismissable(): UiGlobalSelector {
mFilters.add(BooleanFilter[BooleanFilter.DISMISSABLE, true]) mSelector.add(BooleanFilter[BooleanFilter.DISMISSABLE, true])
return this return this
} }
//第三类 int //第三类 int
fun depth(d: Int): UiGlobalSelector { fun depth(d: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.DEPTH, d)) mSelector.add(IntFilter(IntFilter.DEPTH, d))
return this return this
} }
fun row(d: Int): UiGlobalSelector { fun row(d: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.ROW, d)) mSelector.add(IntFilter(IntFilter.ROW, d))
return this return this
} }
fun rowCount(d: Int): UiGlobalSelector { fun rowCount(d: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.ROW_COUNT, d)) mSelector.add(IntFilter(IntFilter.ROW_COUNT, d))
return this return this
} }
fun rowSpan(d: Int): UiGlobalSelector { fun rowSpan(d: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.ROW_SPAN, d)) mSelector.add(IntFilter(IntFilter.ROW_SPAN, d))
return this return this
} }
fun column(d: Int): UiGlobalSelector { fun column(d: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.COLUMN, d)) mSelector.add(IntFilter(IntFilter.COLUMN, d))
return this return this
} }
fun columnCount(d: Int): UiGlobalSelector { fun columnCount(d: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.COLUMN_COUNT, d)) mSelector.add(IntFilter(IntFilter.COLUMN_COUNT, d))
return this return this
} }
fun columnSpan(d: Int): UiGlobalSelector { fun columnSpan(d: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.COLUMN_SPAN, d)) mSelector.add(IntFilter(IntFilter.COLUMN_SPAN, d))
return this return this
} }
fun indexInParent(index: Int): UiGlobalSelector { fun indexInParent(index: Int): UiGlobalSelector {
mFilters.add(IntFilter(IntFilter.INDEX_IN_PARENT, index)) mSelector.add(IntFilter(IntFilter.INDEX_IN_PARENT, index))
return this return this
} }
fun filter(filter: BooleanFilter.BooleanSupplier): UiGlobalSelector { fun filter(filter: BooleanFilter.BooleanSupplier): UiGlobalSelector {
mFilters.add(object : DfsFilter() { mSelector.add(object : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
return filter[nodeInfo] return filter[node]
} }
}) })
return this return this
@@ -416,14 +400,7 @@ open class UiGlobalSelector {
} }
fun findAndReturnList(node: UiObject, max: Int = Int.MAX_VALUE): List<UiObject> { fun findAndReturnList(node: UiObject, max: Int = Int.MAX_VALUE): List<UiObject> {
var list: List<UiObject> = listOf(node) return DFS(mSelector, max).search(node)
for (filter in mFilters) {
val oldMax = filter.maxCount
filter.maxCount = max
list = filter.filter(list)
filter.maxCount = oldMax
}
return list
} }
fun findOneOf(node: UiObject): UiObject? { fun findOneOf(node: UiObject): UiObject? {
@@ -433,19 +410,12 @@ open class UiGlobalSelector {
} else collection[0] } else collection[0]
} }
fun addFilter(filter: ListFilter): UiGlobalSelector { fun addFilter(filter: Filter): UiGlobalSelector {
mFilters.add(filter) mSelector.add(filter)
return this return this
} }
override fun toString(): String { override fun toString(): String {
val str = StringBuilder() return mSelector.toString()
for (filter in mFilters) {
str.append(filter.toString()).append(".")
}
if (str.isNotEmpty()) {
str.deleteCharAt(str.length - 1)
}
return str.toString()
} }
} }

View File

@@ -0,0 +1,10 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
class BFS(val filter: Filter, val limit: Int = Int.MAX_VALUE) {
fun search(node: UiObject) {
}
}

View File

@@ -11,7 +11,7 @@ import java.util.HashMap
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
class BooleanFilter(private val mBooleanSupplier: BooleanSupplier, private val mExceptedValue: Boolean) : DfsFilter() { class BooleanFilter(private val mBooleanSupplier: BooleanSupplier, private val mExceptedValue: Boolean) : Filter {
interface BooleanSupplier { interface BooleanSupplier {
@@ -19,8 +19,8 @@ class BooleanFilter(private val mBooleanSupplier: BooleanSupplier, private val m
} }
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
return mBooleanSupplier[nodeInfo] == mExceptedValue return mBooleanSupplier[node] == mExceptedValue
} }
override fun toString(): String { override fun toString(): String {

View File

@@ -11,13 +11,13 @@ import java.util.Locale
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
class BoundsFilter(private val mBounds: Rect, private val mType: Int) : DfsFilter() { class BoundsFilter(private val mBounds: Rect, private val mType: Int) : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
if (mType == TYPE_CONTAINS) { if (mType == TYPE_CONTAINS) {
return AccessibilityNodeInfoHelper.getBoundsInScreen(nodeInfo).contains(mBounds) return AccessibilityNodeInfoHelper.getBoundsInScreen(node).contains(mBounds)
} }
val boundsInScreen = AccessibilityNodeInfoHelper.getBoundsInScreen(nodeInfo) val boundsInScreen = AccessibilityNodeInfoHelper.getBoundsInScreen(node)
return if (mType == TYPE_EQUALS) boundsInScreen == mBounds else mBounds.contains(boundsInScreen) return if (mType == TYPE_EQUALS) boundsInScreen == mBounds else mBounds.contains(boundsInScreen)
} }

View File

@@ -6,7 +6,7 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
object ClassNameFilter { object ClassNameFilters {
private val CLASS_NAME_GETTER = object : KeyGetter { private val CLASS_NAME_GETTER = object : KeyGetter {
override fun getKey(nodeInfo: UiObject): String? { override fun getKey(nodeInfo: UiObject): String? {
@@ -19,27 +19,27 @@ object ClassNameFilter {
} }
} }
fun equals(text: String): ListFilter { fun equals(text: String): Filter {
var text = text var className = text
if (!text.contains(".")) { if (!className.contains(".")) {
text = "android.widget.$text" className = "android.widget.$className"
} }
return StringEqualsFilter(text, CLASS_NAME_GETTER) return StringEqualsFilter(className, CLASS_NAME_GETTER)
} }
fun contains(str: String): ListFilter { fun contains(str: String): Filter {
return StringContainsFilter(str, CLASS_NAME_GETTER) return StringContainsFilter(str, CLASS_NAME_GETTER)
} }
fun startsWith(prefix: String): ListFilter { fun startsWith(prefix: String): Filter {
return StringStartsWithFilter(prefix, CLASS_NAME_GETTER) return StringStartsWithFilter(prefix, CLASS_NAME_GETTER)
} }
fun endsWith(suffix: String): ListFilter { fun endsWith(suffix: String): Filter {
return StringEndsWithFilter(suffix, CLASS_NAME_GETTER) return StringEndsWithFilter(suffix, CLASS_NAME_GETTER)
} }
fun matches(regex: String): ListFilter { fun matches(regex: String): Filter {
return StringMatchesFilter(regex, CLASS_NAME_GETTER) return StringMatchesFilter(regex, CLASS_NAME_GETTER)
} }
} }

View File

@@ -0,0 +1,42 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
import java.util.ArrayList
/**
* Created by Stardust on 2017/3/9.
*/
class DFS(val filter: Filter, val limit: Int = Int.MAX_VALUE) {
fun search(node: UiObject): List<UiObject> {
val list = ArrayList<UiObject>()
if (filter.filter(node)) {
list.add(node)
if (list.size >= limit) {
return list
}
}
filterChildren(node, list)
return list
}
private fun filterChildren(parent: UiObject, list: MutableList<UiObject>) {
for (i in 0 until parent.childCount) {
val child = parent.child(i) ?: continue
val included = filter.filter(child)
if (included) {
list.add(child)
if (list.size >= limit) {
break
}
}
filterChildren(child, list)
if (!included) {
child.recycle()
}
}
}
}

View File

@@ -6,7 +6,7 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
object DescFilter { object DescFilters {
private val DESC_GETTER = object : KeyGetter { private val DESC_GETTER = object : KeyGetter {
override fun getKey(nodeInfo: UiObject): String? { override fun getKey(nodeInfo: UiObject): String? {
@@ -19,23 +19,23 @@ object DescFilter {
} }
} }
fun equals(text: String): ListFilter { fun equals(text: String): Filter {
return StringEqualsFilter(text, DESC_GETTER) return StringEqualsFilter(text, DESC_GETTER)
} }
fun contains(str: String): ListFilter { fun contains(str: String): Filter {
return StringContainsFilter(str, DESC_GETTER) return StringContainsFilter(str, DESC_GETTER)
} }
fun startsWith(prefix: String): ListFilter { fun startsWith(prefix: String): Filter {
return StringStartsWithFilter(prefix, DESC_GETTER) return StringStartsWithFilter(prefix, DESC_GETTER)
} }
fun endsWith(suffix: String): ListFilter { fun endsWith(suffix: String): Filter {
return StringEndsWithFilter(suffix, DESC_GETTER) return StringEndsWithFilter(suffix, DESC_GETTER)
} }
fun matches(regex: String): ListFilter { fun matches(regex: String): Filter {
return StringMatchesFilter(regex, DESC_GETTER) return StringMatchesFilter(regex, DESC_GETTER)
} }
} }

View File

@@ -1,57 +0,0 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
import java.util.ArrayList
/**
* Created by Stardust on 2017/3/9.
*/
abstract class DfsFilter : ListFilter(), Filter {
override fun filter(nodes: List<UiObject>): List<UiObject> {
val list = ArrayList<UiObject>()
for (node in nodes) {
if (isIncluded(node)) {
list.add(node)
}
if (list.size >= maxCount) {
break
}
filterChildren(node, list)
}
return list
}
override fun filter(node: UiObject): List<UiObject> {
val list = ArrayList<UiObject>()
if (isIncluded(node)) {
list.add(node)
}
if (list.size >= maxCount) {
return list
}
filterChildren(node, list)
return list
}
private fun filterChildren(parent: UiObject, list: MutableList<UiObject>) {
for (i in 0 until parent.childCount) {
val child = parent.child(i) ?: continue
val included = isIncluded(child)
if (included) {
list.add(child)
}
if (list.size >= maxCount) {
break
}
filterChildren(child, list)
if (!included) {
child.recycle()
}
}
}
protected abstract fun isIncluded(nodeInfo: UiObject): Boolean
}

View File

@@ -8,6 +8,6 @@ import com.stardust.automator.UiObject
interface Filter { interface Filter {
fun filter(node: UiObject): List<UiObject> fun filter(node: UiObject): Boolean
} }

View File

@@ -19,10 +19,6 @@ object IdFilter {
} }
} }
interface FullIdGetter {
fun getFullId(id: String): String
}
fun equals(id: String): StringEqualsFilter { fun equals(id: String): StringEqualsFilter {
return StringEqualsFilter(id, ID_GETTER) return StringEqualsFilter(id, ID_GETTER)
} }
@@ -31,7 +27,7 @@ object IdFilter {
return StringStartsWithFilter(prefix, ID_GETTER) return StringStartsWithFilter(prefix, ID_GETTER)
} }
fun endsWith(suffix: String): ListFilter { fun endsWith(suffix: String): StringEndsWithFilter {
return StringEndsWithFilter(suffix, ID_GETTER) return StringEndsWithFilter(suffix, ID_GETTER)
} }

View File

@@ -6,14 +6,14 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/11/5. * Created by Stardust on 2017/11/5.
*/ */
class IntFilter(private val mIntProperty: IntProperty, private val mValue: Int) : DfsFilter() { class IntFilter(private val mIntProperty: IntProperty, private val mValue: Int) : Filter {
interface IntProperty { interface IntProperty {
operator fun get(`object`: UiObject): Int operator fun get(`object`: UiObject): Int
} }
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
return mIntProperty[nodeInfo] == mValue return mIntProperty[node] == mValue
} }
override fun toString(): String { override fun toString(): String {

View File

@@ -1,31 +0,0 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
import java.util.ArrayList
/**
* Created by Stardust on 2017/3/9.
*/
abstract class ListFilter {
var maxCount: Int = Integer.MAX_VALUE
abstract fun filter(nodes: List<UiObject>): List<UiObject>
abstract class Default : Filter, ListFilter() {
override fun filter(nodes: List<UiObject>): List<UiObject> {
val list = ArrayList<UiObject>()
for (node in nodes) {
list.addAll(filter(node))
if (list.size >= maxCount) {
break
}
}
return list
}
}
}

View File

@@ -19,23 +19,23 @@ object PackageNameFilter {
} }
} }
fun equals(text: String): ListFilter { fun equals(text: String): Filter {
return StringEqualsFilter(text, PACKAGE_NAME_GETTER) return StringEqualsFilter(text, PACKAGE_NAME_GETTER)
} }
fun contains(str: String): ListFilter { fun contains(str: String): Filter {
return StringContainsFilter(str, PACKAGE_NAME_GETTER) return StringContainsFilter(str, PACKAGE_NAME_GETTER)
} }
fun startsWith(prefix: String): ListFilter { fun startsWith(prefix: String): Filter {
return StringStartsWithFilter(prefix, PACKAGE_NAME_GETTER) return StringStartsWithFilter(prefix, PACKAGE_NAME_GETTER)
} }
fun endsWith(suffix: String): ListFilter { fun endsWith(suffix: String): Filter {
return StringEndsWithFilter(suffix, PACKAGE_NAME_GETTER) return StringEndsWithFilter(suffix, PACKAGE_NAME_GETTER)
} }
fun matches(regex: String): ListFilter { fun matches(regex: String): Filter {
return StringMatchesFilter(regex, PACKAGE_NAME_GETTER) return StringMatchesFilter(regex, PACKAGE_NAME_GETTER)
} }
} }

View File

@@ -0,0 +1,33 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
import java.util.*
class Selector : Filter {
private val mFilters = LinkedList<Filter>()
override fun filter(node: UiObject): Boolean {
for (filter in mFilters) {
if (!filter.filter(node)) {
return false
}
}
return true
}
fun add(filter: Filter) {
mFilters.add(filter)
}
override fun toString(): String {
val str = StringBuilder()
for (filter in mFilters) {
str.append(filter.toString()).append(".")
}
if (str.isNotEmpty()) {
str.deleteCharAt(str.length - 1)
}
return str.toString()
}
}

View File

@@ -6,10 +6,10 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
class StringContainsFilter internal constructor(private val mContains: String, private val mKeyGetter: KeyGetter) : DfsFilter() { class StringContainsFilter internal constructor(private val mContains: String, private val mKeyGetter: KeyGetter) : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
val key = mKeyGetter.getKey(nodeInfo) val key = mKeyGetter.getKey(node)
return key != null && key.contains(mContains) return key != null && key.contains(mContains)
} }

View File

@@ -6,10 +6,10 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
class StringEndsWithFilter(private val mSuffix: String, private val mKeyGetter: KeyGetter) : DfsFilter() { class StringEndsWithFilter(private val mSuffix: String, private val mKeyGetter: KeyGetter) : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
val key = mKeyGetter.getKey(nodeInfo) val key = mKeyGetter.getKey(node)
return key != null && key.endsWith(mSuffix) return key != null && key.endsWith(mSuffix)
} }

View File

@@ -6,10 +6,10 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
class StringEqualsFilter(private val mValue: String, private val mKeyGetter: KeyGetter) : DfsFilter() { class StringEqualsFilter(private val mValue: String, private val mKeyGetter: KeyGetter) : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
val key = mKeyGetter.getKey(nodeInfo) val key = mKeyGetter.getKey(node)
return if (key != null) { return if (key != null) {
key == mValue key == mValue
} else false } else false

View File

@@ -6,10 +6,10 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
class StringMatchesFilter internal constructor(private val mRegex: String, private val mKeyGetter: KeyGetter) : DfsFilter() { class StringMatchesFilter internal constructor(private val mRegex: String, private val mKeyGetter: KeyGetter) : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
val key = mKeyGetter.getKey(nodeInfo) val key = mKeyGetter.getKey(node)
return key != null && key.matches(mRegex.toRegex()) return key != null && key.matches(mRegex.toRegex())
} }

View File

@@ -6,10 +6,10 @@ import com.stardust.automator.UiObject
* Created by Stardust on 2017/3/9. * Created by Stardust on 2017/3/9.
*/ */
class StringStartsWithFilter(private val mPrefix: String, private val mKeyGetter: KeyGetter) : DfsFilter() { class StringStartsWithFilter(private val mPrefix: String, private val mKeyGetter: KeyGetter) : Filter {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
val key = mKeyGetter.getKey(nodeInfo) val key = mKeyGetter.getKey(node)
return key != null && key.startsWith(mPrefix) return key != null && key.startsWith(mPrefix)
} }

View File

@@ -1,48 +0,0 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
/**
* Created by Stardust on 2017/3/9.
*/
class TextFilter private constructor(private val mText: String) : ListFilter.Default() {
override fun filter(node: UiObject): List<UiObject> {
return node.findByText(mText)
}
companion object {
private val TEXT_GETTER = object : KeyGetter {
override fun getKey(nodeInfo: UiObject): String? {
val charSequence = nodeInfo.text
return charSequence?.toString()
}
override fun toString(): String {
return "text"
}
}
fun equals(text: String): ListFilter {
return StringEqualsFilter(text, TEXT_GETTER)
}
fun contains(str: String): ListFilter {
return StringContainsFilter(str, TEXT_GETTER)
}
fun startsWith(prefix: String): ListFilter {
return StringStartsWithFilter(prefix, TEXT_GETTER)
}
fun endsWith(suffix: String): ListFilter {
return StringEndsWithFilter(suffix, TEXT_GETTER)
}
fun matches(regex: String): ListFilter {
return StringMatchesFilter(regex, TEXT_GETTER)
}
}
}

View File

@@ -0,0 +1,41 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
/**
* Created by Stardust on 2017/3/9.
*/
object TextFilters {
private val TEXT_GETTER = object : KeyGetter {
override fun getKey(nodeInfo: UiObject): String? {
val charSequence = nodeInfo.text
return charSequence?.toString()
}
override fun toString(): String {
return "text"
}
}
fun equals(text: String): Filter {
return StringEqualsFilter(text, TEXT_GETTER)
}
fun contains(str: String): Filter {
return StringContainsFilter(str, TEXT_GETTER)
}
fun startsWith(prefix: String): Filter {
return StringStartsWithFilter(prefix, TEXT_GETTER)
}
fun endsWith(suffix: String): Filter {
return StringEndsWithFilter(suffix, TEXT_GETTER)
}
fun matches(regex: String): Filter {
return StringMatchesFilter(regex, TEXT_GETTER)
}
}

View File

@@ -13,11 +13,11 @@ import org.junit.Assert.*
*/ */
class DfsFilterTest { class DfsFilterTest {
private class RandomDfsFilter : DfsFilter() { private class RandomFilter : Filter {
private val mRandom = Random() private val mRandom = Random()
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun filter(node: UiObject): Boolean {
return mRandom.nextBoolean() return mRandom.nextBoolean()
} }
} }
@@ -25,9 +25,9 @@ class DfsFilterTest {
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun filter() { fun filter() {
val filter = RandomDfsFilter() val filter = RandomFilter()
val root = TestUiObject(10) val root = TestUiObject(10)
val list = filter.filter(root) val list = DFS(filter).search(root)
for (uiObject in list) { for (uiObject in list) {
if (root !== uiObject) if (root !== uiObject)
uiObject.recycle() uiObject.recycle()

View File

@@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":450,"versionName":"4.0.5 Alpha","enabled":true,"outputFile":"commonRelease-4.0.5 Alpha.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.5 Alpha.apk","properties":{}}] [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":451,"versionName":"4.1.0 Alpha","enabled":true,"outputFile":"commonRelease-4.1.0 Alpha.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.1.0 Alpha.apk","properties":{}}]

View File

@@ -1,8 +1,8 @@
{ {
"appVersionCode": 450, "appVersionCode": 451,
"appVersionName": "4.0.5 Alpha", "appVersionName": "4.1.0 Alpha",
"target": 28, "target": 28,
"mini": 17, "mini": 17,
"compile": 28, "compile": 28,
"buildTool": "28.0.3" "buildTool": "28.0.3"
} }