增加无障碍事件

This commit is contained in:
抠脚本人
2023-07-10 19:19:56 +08:00
parent 1db2837506
commit a59b46fd6e
6 changed files with 90 additions and 12 deletions

View File

@@ -61,9 +61,15 @@ module.exports = function (scriptRuntime, scope) {
return util.java.toJsArray(a11yBridge.windowRoots(), false) return util.java.toJsArray(a11yBridge.windowRoots(), false)
.map(root => UiObject.createRoot(root)); .map(root => UiObject.createRoot(root));
}, },
stateListener(listener){ stateListener(listener) {
return a11yBridge.setAccessibilityListener(listener); return a11yBridge.setAccessibilityListener(listener);
}, },
registerEvents(name, listener) {
return rtAutomator.registerEvents(name, listener);
},
removeEvents(name) {
return rtAutomator.removeEvents(name);
},
waitFor(timeout) { waitFor(timeout) {
automator.waitForService(timeout); automator.waitForService(timeout);
}, },

View File

@@ -9,16 +9,17 @@ import android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED
import android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED import android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
import android.view.accessibility.AccessibilityNodeInfo import android.view.accessibility.AccessibilityNodeInfo
import org.autojs.autojs.AutoJs import org.autojs.autojs.AutoJs
import org.autojs.autojs.core.automator.AccessibilityEventWrapper
import org.autojs.autojs.event.EventDispatcher import org.autojs.autojs.event.EventDispatcher
import org.autojs.autojs.pref.Pref import org.autojs.autojs.pref.Pref
import java.util.TreeMap import java.util.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
interface AccessibilityServiceCallback { interface AccessibilityServiceCallback {
fun onServiceConnected() fun onConnected()
fun onServiceDisconnected() fun onDisconnected()
} }
/** /**
* Created by Stardust on 2017/5/2. * Created by Stardust on 2017/5/2.
@@ -28,16 +29,38 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
val keyInterrupterObserver = KeyInterceptor.Observer() val keyInterrupterObserver = KeyInterceptor.Observer()
var fastRootInActiveWindow: AccessibilityNodeInfo? = null var fastRootInActiveWindow: AccessibilityNodeInfo? = null
var bridge: AccessibilityBridge? = null var bridge: AccessibilityBridge? = null
private val eventBox = TreeMap<Int, AccessibilityEventCallback>()
private val gestureEventDispatcher = EventDispatcher<GestureListener>() private val gestureEventDispatcher = EventDispatcher<GestureListener>()
private val eventExecutor by lazy { Executors.newSingleThreadExecutor() } private val eventExecutor by lazy { Executors.newSingleThreadExecutor() }
private fun eventNameToType(str: String): Int {
return try {
val sb = StringBuilder()
sb.append("TYPE_")
val upperCase = str.uppercase(Locale.getDefault())
sb.append(upperCase)
AccessibilityEvent::class.java.getField(sb.toString()).get(null) as Int
} catch (unused: NoSuchFieldException) {
throw IllegalArgumentException("unknown event type: $str")
}
}
fun addAccessibilityEventCallback(name: String, callback: AccessibilityEventCallback) {
eventBox[eventNameToType(name)] = callback
}
fun removeAccessibilityEventCallback(name: String) {
eventBox.remove(eventNameToType(name))
}
override fun onAccessibilityEvent(event: AccessibilityEvent) { override fun onAccessibilityEvent(event: AccessibilityEvent) {
if (instance != this) { if (instance != this) {
instance = this instance = this
} }
val type = event.eventType val type = event.eventType
eventBox[type]?.onAccessibilityEvent(AccessibilityEventWrapper(event))
if (containsAllEventTypes || eventTypes.contains(type)) { if (containsAllEventTypes || eventTypes.contains(type)) {
if (type == TYPE_WINDOW_STATE_CHANGED || type == TYPE_VIEW_FOCUSED) { if (type == TYPE_WINDOW_STATE_CHANGED || type == TYPE_VIEW_FOCUSED) {
rootInActiveWindow?.also { fastRootInActiveWindow = it } rootInActiveWindow?.also { fastRootInActiveWindow = it }
@@ -90,7 +113,7 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
instance = null instance = null
bridge = null bridge = null
eventExecutor.shutdownNow() eventExecutor.shutdownNow()
callback?.onServiceDisconnected() callback?.onDisconnected()
super.onDestroy() super.onDestroy()
} }
@@ -107,7 +130,7 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
} }
} }
} }
callback?.onServiceConnected() callback?.onConnected()
super.onServiceConnected() super.onServiceConnected()
LOCK.lock() LOCK.lock()
@@ -147,6 +170,7 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
fun isNotRunning() = !isRunning() fun isNotRunning() = !isRunning()
fun addDelegate(uniquePriority: Int, delegate: AccessibilityDelegate) { fun addDelegate(uniquePriority: Int, delegate: AccessibilityDelegate) {
//用于记录eventTypes中的事件id
delegates[uniquePriority] = delegate delegates[uniquePriority] = delegate
val set = delegate.eventTypes val set = delegate.eventTypes
if (set == null) { if (set == null) {
@@ -184,7 +208,9 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
LOCK.unlock() LOCK.unlock()
} }
} }
fun clearAccessibilityEventCallback() {
instance?.eventBox?.clear()
}
fun setCallback(listener: AccessibilityServiceCallback) { fun setCallback(listener: AccessibilityServiceCallback) {
callback = listener callback = listener
} }

View File

@@ -16,6 +16,7 @@ import androidx.annotation.RequiresApi
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import org.autojs.autojs.annotation.ScriptInterface import org.autojs.autojs.annotation.ScriptInterface
import org.autojs.autojs.core.accessibility.AccessibilityService.Companion.isRunning import org.autojs.autojs.core.accessibility.AccessibilityService.Companion.isRunning
import org.autojs.autojs.core.automator.AccessibilityEventWrapper
import org.autojs.autojs.core.automator.GlobalActionAutomator import org.autojs.autojs.core.automator.GlobalActionAutomator
import org.autojs.autojs.core.automator.UiObject import org.autojs.autojs.core.automator.UiObject
import org.autojs.autojs.core.automator.action.ActionFactory import org.autojs.autojs.core.automator.action.ActionFactory
@@ -27,7 +28,11 @@ import org.autojs.autojs.runtime.accessibility.AccessibilityConfig
import org.autojs.autojs.runtime.api.ScreenMetrics import org.autojs.autojs.runtime.api.ScreenMetrics
import org.autojs.autojs.runtime.api.ScriptPromiseAdapter import org.autojs.autojs.runtime.api.ScriptPromiseAdapter
import org.autojs.autojs.util.DeveloperUtils import org.autojs.autojs.util.DeveloperUtils
import java.util.concurrent.atomic.AtomicInteger
interface AccessibilityEventCallback {
fun onAccessibilityEvent(event: AccessibilityEventWrapper)
}
/** /**
* Created by Stardust on 2017/4/2. * Created by Stardust on 2017/4/2.
@@ -182,6 +187,18 @@ class SimpleActionAutomator(private val accessibilityBridge: AccessibilityBridge
@ScriptInterface @ScriptInterface
fun ensureService() = accessibilityBridge.ensureServiceEnabled() fun ensureService() = accessibilityBridge.ensureServiceEnabled()
//todo:优化实现方式
fun registerEvents(eventName: String,callback: AccessibilityEventCallback) {
ensureService()
val service = org.autojs.autojs.core.accessibility.AccessibilityService.instance
service?.addAccessibilityEventCallback(eventName,callback)
}
fun removeEvents(eventName: String) {
val service = org.autojs.autojs.core.accessibility.AccessibilityService.instance
service?.removeAccessibilityEventCallback(eventName)
}
private fun performAction(simpleAction: SimpleAction): Boolean { private fun performAction(simpleAction: SimpleAction): Boolean {
ensureService() ensureService()
if (AccessibilityConfig.isUnintendedGuardEnabled() && isRunningPackageSelf) { if (AccessibilityConfig.isUnintendedGuardEnabled() && isRunningPackageSelf) {
@@ -239,7 +256,7 @@ class SimpleActionAutomator(private val accessibilityBridge: AccessibilityBridge
} }
companion object { companion object {
val accessibilityDelegateCounter = AtomicInteger(1000)
val TAG: String = SimpleActionAutomator::class.java.name val TAG: String = SimpleActionAutomator::class.java.name
} }

View File

@@ -0,0 +1,27 @@
package org.autojs.autojs.core.automator
import android.view.accessibility.AccessibilityEvent
class AccessibilityEventWrapper(event: AccessibilityEvent) {
private val node = event.source
val source = if (node != null) UiObject(node, null, getDepth(), getIndexInParent()) else null
private fun getDepth(): Int {
var depth = 0
if (node == null) return 0
while (node.parent != null) {
depth++
}
return depth
}
private fun getIndexInParent(): Int {
val parent = node!!.parent
var index = 0
while (parent.getChild(index) != node) {
index++
}
return index
}
}

View File

@@ -11,6 +11,7 @@ import org.autojs.autojs.AutoJs;
import org.autojs.autojs.annotation.ScriptVariable; import org.autojs.autojs.annotation.ScriptVariable;
import org.autojs.autojs.concurrent.VolatileDispose; import org.autojs.autojs.concurrent.VolatileDispose;
import org.autojs.autojs.core.accessibility.AccessibilityBridge; import org.autojs.autojs.core.accessibility.AccessibilityBridge;
import org.autojs.autojs.core.accessibility.AccessibilityService;
import org.autojs.autojs.core.accessibility.SimpleActionAutomator; import org.autojs.autojs.core.accessibility.SimpleActionAutomator;
import org.autojs.autojs.core.accessibility.UiSelector; import org.autojs.autojs.core.accessibility.UiSelector;
import org.autojs.autojs.core.activity.ActivityInfoProvider; import org.autojs.autojs.core.activity.ActivityInfoProvider;
@@ -527,7 +528,8 @@ public class ScriptRuntime {
console.hideDelayed(); console.hideDelayed();
} }
}); });
//清空无障碍事件
ignoresException(AccessibilityService.Companion::clearAccessibilityEventCallback);
ignoresException(RootUtils::resetRuntimeOverriddenRootModeState); ignoresException(RootUtils::resetRuntimeOverriddenRootModeState);
ignoresException(ImageWrapper::recycleAll); ignoresException(ImageWrapper::recycleAll);

View File

@@ -1,8 +1,8 @@
#Mon Jul 10 09:35:09 CST 2023 #Mon Jul 10 18:23:10 CST 2023
BUILD_TIME=1688952909391 BUILD_TIME=1688984590330
COMPILE_SDK_VERSION=33 COMPILE_SDK_VERSION=33
JAVA_VERSION=20 JAVA_VERSION=20
MIN_SDK_VERSION=24 MIN_SDK_VERSION=24
TARGET_SDK_VERSION=33 TARGET_SDK_VERSION=33
VERSION_BUILD=2000 VERSION_BUILD=2006
VERSION_NAME=6.3.2 VERSION_NAME=6.3.2