增加无障碍事件
This commit is contained in:
@@ -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);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user