diff --git a/app/src/main/kotlin/li/songe/gkd/service/AbExt.kt b/app/src/main/kotlin/li/songe/gkd/service/AbExt.kt index 5a57aa2..191495e 100644 --- a/app/src/main/kotlin/li/songe/gkd/service/AbExt.kt +++ b/app/src/main/kotlin/li/songe/gkd/service/AbExt.kt @@ -57,7 +57,6 @@ fun AccessibilityNodeInfo.getDepth(): Int { return depth } - fun AccessibilityNodeInfo.querySelector( selector: Selector, quickFind: Boolean = false, @@ -69,21 +68,27 @@ fun AccessibilityNodeInfo.querySelector( } return null } - if (quickFind) { - val canQuickFind = selector.canQuickFind - if (canQuickFind != null) { - // 使用 findAccessibilityNodeInfosByXX 无法查询深层次节点 + if (quickFind && selector.canQf) { + val qfIdValue = selector.qfIdValue + val qfVidValue = selector.qfVidValue + val qfTextValue = selector.qfTextValue + val nodes = (if (qfIdValue != null) { + findAccessibilityNodeInfosByViewId(qfIdValue) + } else if (qfVidValue != null) { + findAccessibilityNodeInfosByViewId("$packageName:id/$qfVidValue") + } else if (qfTextValue != null) { + findAccessibilityNodeInfosByText(qfTextValue) + } else { + emptyList() + }) + if (nodes.isNotEmpty()) { val trackNodes = mutableListOf() - (if (selector.canQuickFind!!.first) { - findAccessibilityNodeInfosByViewId(canQuickFind.second) - } else { - findAccessibilityNodeInfosByText(canQuickFind.second) - }).forEach { childNode -> + nodes.forEach { childNode -> val targetNode = selector.match(childNode, abTransform, trackNodes) if (targetNode != null) return targetNode } - return null } + return null } // 在一些开屏广告的界面会造成1-2s的阻塞 return abTransform.querySelector(this, selector) @@ -113,6 +118,13 @@ private val getChildren: (AccessibilityNodeInfo) -> Sequence Any? = { node, name -> when (name) { "id" -> node.viewIdResourceName + "vid" -> node.viewIdResourceName?.let { id -> + id.subSequence( + (node.packageName?.length ?: 0) + ":id/".length, + id.length + ) + } + "name" -> node.className "text" -> node.text "text.length" -> node.text?.length diff --git a/selector/src/commonMain/kotlin/li/songe/selector/Selector.kt b/selector/src/commonMain/kotlin/li/songe/selector/Selector.kt index f19c434..2f19e8a 100644 --- a/selector/src/commonMain/kotlin/li/songe/selector/Selector.kt +++ b/selector/src/commonMain/kotlin/li/songe/selector/Selector.kt @@ -40,21 +40,32 @@ class Selector internal constructor(private val propertyWrapper: PropertyWrapper return propertyWrapper.matchTracks(node, transform, trackNodes) } - // true: use findById, false: use findByText - val canQuickFind = propertyWrapper.propertySegment.expressions.firstOrNull().let { e -> - if (e is BinaryExpression && e.value is String) { - if (e.name == "id" && e.operator == CompareOperator.Equal) { - true to e.value - } else if (e.name == "text" && (e.operator == CompareOperator.Equal || e.operator == CompareOperator.Start || e.operator == CompareOperator.Include || e.operator == CompareOperator.End)) { - false to e.value - } else { - null - } + val qfIdValue = propertyWrapper.propertySegment.expressions.firstOrNull().let { e -> + if (e is BinaryExpression && e.name == "id" && e.operator == CompareOperator.Equal && e.value is String) { + e.value } else { null } } + val qfVidValue = propertyWrapper.propertySegment.expressions.firstOrNull().let { e -> + if (e is BinaryExpression && e.name == "vid" && e.operator == CompareOperator.Equal && e.value is String) { + e.value + } else { + null + } + } + + val qfTextValue = propertyWrapper.propertySegment.expressions.firstOrNull().let { e -> + if (e is BinaryExpression && e.name == "id" && (e.operator == CompareOperator.Equal || e.operator == CompareOperator.Start || e.operator == CompareOperator.Include || e.operator == CompareOperator.End) && e.value is String) { + e.value + } else { + null + } + } + + val canQf = qfIdValue != null || qfVidValue != null || qfTextValue != null + // 主动查询 val isMatchRoot = propertyWrapper.propertySegment.expressions.firstOrNull().let { e -> e is BinaryExpression && e.name == "depth" && e.operator == CompareOperator.Equal && e.value == 0