6.7.0 - Alpha13 - 新增 auto.state 属性 (getter) 及 shizuku.state 属性 (getter)
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$data": {
|
"$data": {
|
||||||
"v6.7.0": {
|
"v6.7.0": {
|
||||||
"released_date": "2026/01/06",
|
"released_date": "2026/01/08",
|
||||||
"feature": [
|
"feature": [
|
||||||
"插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮)",
|
"插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮)",
|
||||||
"cvt 模块, 用于数据单位转换 (参阅 项目文档 > [单位转换](https://docs.autojs6.com/#/cvt))",
|
"cvt 模块, 用于数据单位转换 (参阅 项目文档 > [单位转换](https://docs.autojs6.com/#/cvt))",
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
"http 模块请求相关方法支持缓存控制选项参数 (cacheBody/bodyCacheThresholdBytes)",
|
"http 模块请求相关方法支持缓存控制选项参数 (cacheBody/bodyCacheThresholdBytes)",
|
||||||
"http 模块请求相关方法支持不安全选项参数 (isInsecure/insecure), 用于忽略证书相关异常 _[`issue #417`](http://issues.autojs6.com/417)_",
|
"http 模块请求相关方法支持不安全选项参数 (isInsecure/insecure), 用于忽略证书相关异常 _[`issue #417`](http://issues.autojs6.com/417)_",
|
||||||
"http 模块请求相关方法支持 options.client 选项, 用于配置 OkHttpClient.Builder (如 followRedirects 等) _[`issue #454`](http://issues.autojs6.com/454)_",
|
"http 模块请求相关方法支持 options.client 选项, 用于配置 OkHttpClient.Builder (如 followRedirects 等) _[`issue #454`](http://issues.autojs6.com/454)_",
|
||||||
|
"auto.state 属性 (getter) 及 shizuku.state 属性 (getter), 用于获取无障碍服务状态及 Shizuku 服务状态",
|
||||||
"runtime.(set/is)JavaPrimitiveWrap 方法, 用于设置或获取 Java 原始类型包装策略 _[`issue #435`](http://issues.autojs6.com/435)_",
|
"runtime.(set/is)JavaPrimitiveWrap 方法, 用于设置或获取 Java 原始类型包装策略 _[`issue #435`](http://issues.autojs6.com/435)_",
|
||||||
"autojs.(restart/exit) 方法, 用于重启或退出 AutoJs6 应用, 并支持应用重启时自动运行其参数指定的脚本 _[`issue #460`](http://issues.autojs6.com/460)_",
|
"autojs.(restart/exit) 方法, 用于重启或退出 AutoJs6 应用, 并支持应用重启时自动运行其参数指定的脚本 _[`issue #460`](http://issues.autojs6.com/460)_",
|
||||||
"UiObject#isShifted 方法, 用于检测控件位置变化 _[`issue #469`](http://issues.autojs6.com/469)_",
|
"UiObject#isShifted 方法, 用于检测控件位置变化 _[`issue #469`](http://issues.autojs6.com/469)_",
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class AccessibilityBridgeImpl extends AccessibilityBridge {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ensureServiceStarted(boolean isForcibleRestart) {
|
public void ensureServiceStarted(boolean isForcibleRestart) {
|
||||||
if (isForcibleRestart && mA11yTool.serviceExists()) {
|
if (isForcibleRestart && mA11yTool.hasService()) {
|
||||||
mA11yTool.stopService(true);
|
mA11yTool.stopService(true);
|
||||||
Log.d(TAG, "isForcibleRestart");
|
Log.d(TAG, "isForcibleRestart");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import java.util.concurrent.locks.ReentrantLock
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on May 2, 2017.
|
* Created by Stardust on May 2, 2017.
|
||||||
* Modified by SuperMonster003 as of Dec 29, 2025.
|
* Modified by SuperMonster003 as of Jan 7, 2026.
|
||||||
*/
|
*/
|
||||||
open class AccessibilityService : android.accessibilityservice.AccessibilityService() {
|
open class AccessibilityService : android.accessibilityservice.AccessibilityService() {
|
||||||
|
|
||||||
@@ -87,6 +87,10 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
|||||||
instance = this
|
instance = this
|
||||||
val type = event.eventType
|
val type = event.eventType
|
||||||
|
|
||||||
|
// Mark service as operational when we receive the first accessibility event.
|
||||||
|
// zh-CN: 当收到首个无障碍事件时, 将服务标记为可工作状态.
|
||||||
|
markOperationalStateIfNeeded()
|
||||||
|
|
||||||
// Snapshot callbacks to avoid holding lock while invoking user code.
|
// Snapshot callbacks to avoid holding lock while invoking user code.
|
||||||
// zh-CN: 为回调建立快照, 以避免在调用用户代码时持锁.
|
// zh-CN: 为回调建立快照, 以避免在调用用户代码时持锁.
|
||||||
val callbacks: List<AccessibilityEventCallback> = synchronized(eventBoxLock) {
|
val callbacks: List<AccessibilityEventCallback> = synchronized(eventBoxLock) {
|
||||||
@@ -149,6 +153,8 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
|||||||
instance = null
|
instance = null
|
||||||
bridge = null
|
bridge = null
|
||||||
|
|
||||||
|
resetOperationalState()
|
||||||
|
|
||||||
mEventExecutor?.shutdownNow()
|
mEventExecutor?.shutdownNow()
|
||||||
callback?.onDisconnected()
|
callback?.onDisconnected()
|
||||||
EventBus.getDefault().post(object : AccessibilityServiceStateChangedEvent {})
|
EventBus.getDefault().post(object : AccessibilityServiceStateChangedEvent {})
|
||||||
@@ -183,8 +189,13 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
|||||||
|
|
||||||
private val LOCK = ReentrantLock()
|
private val LOCK = ReentrantLock()
|
||||||
private val ENABLED = LOCK.newCondition()
|
private val ENABLED = LOCK.newCondition()
|
||||||
|
private val OPERATIONAL = LOCK.newCondition()
|
||||||
|
|
||||||
private var callback: AccessibilityServiceCallback? = null
|
private var callback: AccessibilityServiceCallback? = null
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
var hasOperationalState = false
|
||||||
|
|
||||||
var instance: AccessibilityService? = null
|
var instance: AccessibilityService? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@@ -198,6 +209,27 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
|||||||
|
|
||||||
fun hasInstance() = instance != null
|
fun hasInstance() = instance != null
|
||||||
|
|
||||||
|
private fun markOperationalStateIfNeeded() {
|
||||||
|
if (hasOperationalState) return
|
||||||
|
LOCK.lock()
|
||||||
|
try {
|
||||||
|
if (hasOperationalState) return
|
||||||
|
hasOperationalState = true
|
||||||
|
OPERATIONAL.signalAll()
|
||||||
|
} finally {
|
||||||
|
LOCK.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetOperationalState() {
|
||||||
|
LOCK.lock()
|
||||||
|
try {
|
||||||
|
hasOperationalState = false
|
||||||
|
} finally {
|
||||||
|
LOCK.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun addDelegate(uniquePriority: Int, delegate: AccessibilityDelegate) {
|
fun addDelegate(uniquePriority: Int, delegate: AccessibilityDelegate) {
|
||||||
// @Hint by 抠脚本人 (https://github.com/little-alei) on Jul 10, 2023.
|
// @Hint by 抠脚本人 (https://github.com/little-alei) on Jul 10, 2023.
|
||||||
// ! 用于记录 eventTypes 中的事件 id.
|
// ! 用于记录 eventTypes 中的事件 id.
|
||||||
@@ -239,6 +271,30 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait until the service becomes operational (not only connected).
|
||||||
|
// zh-CN: 等待服务进入可工作状态 (不只是已连接).
|
||||||
|
fun waitForOperational(timeout: Long = DEFAULT_A11Y_SERVICE_START_TIMEOUT): Boolean {
|
||||||
|
if (hasInstance() && hasOperationalState) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
LOCK.lock()
|
||||||
|
try {
|
||||||
|
if (hasInstance() && hasOperationalState) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (timeout == -1L) {
|
||||||
|
OPERATIONAL.await()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return OPERATIONAL.await(timeout, TimeUnit.MILLISECONDS)
|
||||||
|
} catch (e: InterruptedException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
return false
|
||||||
|
} finally {
|
||||||
|
LOCK.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun clearAccessibilityEventCallback() {
|
fun clearAccessibilityEventCallback() {
|
||||||
instance?.let { svc ->
|
instance?.let { svc ->
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mApplicationContext.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
|
mApplicationContext.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (_: ActivityNotFoundException) {
|
||||||
ViewUtils.showToast(mContext, R.string.go_to_accessibility_settings, true)
|
ViewUtils.showToast(mContext, R.string.go_to_accessibility_settings, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,20 +60,27 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
else -> emptyArray()
|
else -> emptyArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
fun isServiceRunning() = hasInstance() && serviceExists()
|
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun hasInstance() = AccessibilityService.hasInstance()
|
fun hasInstance() = AccessibilityService.hasInstance()
|
||||||
|
|
||||||
|
// Means the service is enabled in system settings.
|
||||||
|
// zh-CN: 表示服务在系统设置中处于已启用状态.
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun serviceExists(): Boolean {
|
fun hasService(): Boolean {
|
||||||
val services = Secure.getString(
|
val services = Secure.getString(
|
||||||
mApplicationContext.contentResolver, Secure.ENABLED_ACCESSIBILITY_SERVICES
|
mApplicationContext.contentResolver, Secure.ENABLED_ACCESSIBILITY_SERVICES
|
||||||
) ?: return false
|
) ?: return false
|
||||||
return services.split(SERVICES_DELIMITER).any { it.trim() == mServiceName }
|
return services.split(SERVICES_DELIMITER).any { it.trim() == mServiceName }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun isRunning() = hasService() && hasInstance()
|
||||||
|
|
||||||
|
// Means the service is enabled and confirmed workable in current process.
|
||||||
|
// zh-CN: 表示服务已启用, 且在当前进程中已确认可用.
|
||||||
|
@ScriptInterface
|
||||||
|
fun isOperational() = isRunning() && AccessibilityService.hasOperationalState
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun startService(withLaunchSettings: Boolean = true): Boolean {
|
fun startService(withLaunchSettings: Boolean = true): Boolean {
|
||||||
@@ -81,7 +88,7 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
if (startServiceWithConvenientWaysIfPossible()) {
|
if (startServiceWithConvenientWaysIfPossible()) {
|
||||||
result = true.also { Log.d(TAG, "Accessibility service enabled successfully by a certain \"convenient way\"") }
|
result = true.also { Log.d(TAG, "Accessibility service enabled successfully by a certain \"convenient way\"") }
|
||||||
}
|
}
|
||||||
if (isServiceRunning()) {
|
if (isRunning()) {
|
||||||
result = true.also { Log.d(TAG, "Accessibility service is running") }
|
result = true.also { Log.d(TAG, "Accessibility service is running") }
|
||||||
}
|
}
|
||||||
return result || false.also { if (withLaunchSettings) launchSettings() }
|
return result || false.also { if (withLaunchSettings) launchSettings() }
|
||||||
@@ -102,7 +109,7 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
if (AccessibilityService.stop() && !serviceExists()) {
|
if (AccessibilityService.stop() && !hasService()) {
|
||||||
result = true.also { Log.d(TAG, "Accessibility service disabled successfully by \"disableSelf\"") }
|
result = true.also { Log.d(TAG, "Accessibility service disabled successfully by \"disableSelf\"") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,7 +129,7 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun startServiceAndWaitFor(timeout: Long = DEFAULT_A11Y_SERVICE_START_TIMEOUT) {
|
fun startServiceAndWaitFor(timeout: Long = DEFAULT_A11Y_SERVICE_START_TIMEOUT) {
|
||||||
if (isServiceRunning()) return
|
if (isRunning()) return
|
||||||
if (startServiceWithConvenientWaysIfPossibleAndWaitFor()) return
|
if (startServiceWithConvenientWaysIfPossibleAndWaitFor()) return
|
||||||
launchSettings()
|
launchSettings()
|
||||||
if (!AccessibilityService.waitForStarted(timeout)) {
|
if (!AccessibilityService.waitForStarted(timeout)) {
|
||||||
@@ -130,6 +137,23 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start service and wait until it becomes operational.
|
||||||
|
// zh-CN: 启动服务并等待其进入可工作状态.
|
||||||
|
@JvmOverloads
|
||||||
|
@ScriptInterface
|
||||||
|
fun startServiceAndWaitForOperational(timeout: Long = DEFAULT_A11Y_SERVICE_START_TIMEOUT) {
|
||||||
|
if (isOperational()) return
|
||||||
|
if (startServiceWithConvenientWaysIfPossibleAndWaitFor(timeout)) {
|
||||||
|
AccessibilityService.waitForOperational(timeout)
|
||||||
|
if (isOperational()) return
|
||||||
|
} else {
|
||||||
|
launchSettings()
|
||||||
|
}
|
||||||
|
if (!AccessibilityService.waitForOperational(timeout)) {
|
||||||
|
throw ScriptInterruptedException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun startServiceWithConvenientWaysIfPossible() = when {
|
private fun startServiceWithConvenientWaysIfPossible() = when {
|
||||||
startServiceWithRootIfPossible() -> true
|
startServiceWithRootIfPossible() -> true
|
||||||
startServiceWithSecureIfPossible() -> true
|
startServiceWithSecureIfPossible() -> true
|
||||||
@@ -144,12 +168,26 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun ensureService() {
|
fun ensureService() {
|
||||||
if (isServiceRunning()) return
|
if (isRunning()) return
|
||||||
if (startServiceWithConvenientWaysIfPossibleAndWaitFor()) return
|
if (startServiceWithConvenientWaysIfPossibleAndWaitFor()) return
|
||||||
launchSettings()
|
launchSettings()
|
||||||
if (AccessibilityService.waitForStarted()) return
|
if (AccessibilityService.waitForStarted()) return
|
||||||
when {
|
when {
|
||||||
!serviceExists() -> throw ScriptException(mContext.getString(R.string.text_a11y_service_enabled_but_not_running))
|
!hasService() -> throw ScriptException(mContext.getString(R.string.text_a11y_service_enabled_but_not_running))
|
||||||
|
else -> throw ScriptException(mContext.getString(R.string.error_no_accessibility_permission))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure service is operational, otherwise throw a concrete error.
|
||||||
|
// zh-CN: 确保服务处于可工作状态, 否则抛出明确的错误信息.
|
||||||
|
@ScriptInterface
|
||||||
|
fun ensureServiceOperational(timeout: Long = DEFAULT_A11Y_SERVICE_START_TIMEOUT) {
|
||||||
|
if (isOperational()) return
|
||||||
|
startServiceAndWaitForOperational(timeout)
|
||||||
|
if (isOperational()) return
|
||||||
|
when {
|
||||||
|
!hasService() -> throw ScriptException(mContext.getString(R.string.text_a11y_service_enabled_but_not_running))
|
||||||
|
!hasInstance() -> throw ScriptException(mContext.getString(R.string.text_a11y_service_enabled_but_not_running))
|
||||||
else -> throw ScriptException(mContext.getString(R.string.error_no_accessibility_permission))
|
else -> throw ScriptException(mContext.getString(R.string.error_no_accessibility_permission))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,8 +197,8 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
private fun isRootAccessible() = Pref.shouldStartA11yServiceWithRoot() && RootUtils.isRootAvailable()
|
private fun isRootAccessible() = Pref.shouldStartA11yServiceWithRoot() && RootUtils.isRootAvailable()
|
||||||
|
|
||||||
private fun startServiceWithRoot(timeout: Long? = null): Boolean = when (timeout != null) {
|
private fun startServiceWithRoot(timeout: Long? = null): Boolean = when (timeout != null) {
|
||||||
true -> startServiceWithRoot() && AccessibilityService.waitForStarted(timeout.toLong())
|
true -> startServiceWithRoot() && AccessibilityService.waitForStarted(timeout)
|
||||||
else -> try {
|
else -> runCatching {
|
||||||
stopServiceWithRoot()
|
stopServiceWithRoot()
|
||||||
|
|
||||||
val services = getServicesWithRoot(true)
|
val services = getServicesWithRoot(true)
|
||||||
@@ -172,31 +210,27 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
val resultState = ProcessShell.execCommand(cmdState, true)
|
val resultState = ProcessShell.execCommand(cmdState, true)
|
||||||
|
|
||||||
TextUtils.isEmpty(resultServices.error) && TextUtils.isEmpty(resultState.error)
|
TextUtils.isEmpty(resultServices.error) && TextUtils.isEmpty(resultState.error)
|
||||||
} catch (e: Exception) {
|
}.isSuccess
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startServiceWithRootIfPossible(timeout: Long? = null) = isRootAccessible() && startServiceWithRoot(timeout)
|
private fun startServiceWithRootIfPossible(timeout: Long? = null) = isRootAccessible() && startServiceWithRoot(timeout)
|
||||||
|
|
||||||
private fun startServiceWithSecure(timeout: Long? = null): Boolean = when (timeout != null) {
|
private fun startServiceWithSecure(timeout: Long? = null): Boolean = when (timeout != null) {
|
||||||
true -> startServiceWithSecure() && AccessibilityService.waitForStarted(timeout)
|
true -> startServiceWithSecure() && AccessibilityService.waitForStarted(timeout)
|
||||||
else -> try {
|
else -> runCatching {
|
||||||
stopServiceWithSecure()
|
stopServiceWithSecure()
|
||||||
|
|
||||||
val services = getServicesWithSecure(true)
|
val services = getServicesWithSecure(true)
|
||||||
Secure.putString(mApplicationContext.contentResolver, Secure.ENABLED_ACCESSIBILITY_SERVICES, services)
|
Secure.putString(mApplicationContext.contentResolver, Secure.ENABLED_ACCESSIBILITY_SERVICES, services)
|
||||||
Secure.putInt(mApplicationContext.contentResolver, Secure.ACCESSIBILITY_ENABLED, 1)
|
Secure.putInt(mApplicationContext.contentResolver, Secure.ACCESSIBILITY_ENABLED, 1)
|
||||||
|
|
||||||
serviceExists()
|
hasService()
|
||||||
} catch (e: Exception) {
|
}.isSuccess
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startServiceWithSecureIfPossible(timeout: Long? = null) = isSecureAccessible() && startServiceWithSecure(timeout)
|
private fun startServiceWithSecureIfPossible(timeout: Long? = null) = isSecureAccessible() && startServiceWithSecure(timeout)
|
||||||
|
|
||||||
private fun stopServiceWithRoot() = try {
|
private fun stopServiceWithRoot() = runCatching {
|
||||||
val services = getServicesWithRoot(false)
|
val services = getServicesWithRoot(false)
|
||||||
|
|
||||||
val cmdServices = "settings put secure enabled_accessibility_services $services"
|
val cmdServices = "settings put secure enabled_accessibility_services $services"
|
||||||
@@ -206,20 +240,16 @@ class AccessibilityTool(private val context: Context? = null) {
|
|||||||
val resultState = ProcessShell.execCommand(cmdState, true)
|
val resultState = ProcessShell.execCommand(cmdState, true)
|
||||||
|
|
||||||
TextUtils.isEmpty(resultServices.error) && TextUtils.isEmpty(resultState.error)
|
TextUtils.isEmpty(resultServices.error) && TextUtils.isEmpty(resultState.error)
|
||||||
} catch (e: Exception) {
|
}.isSuccess
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun stopServiceWithSecure() = try {
|
private fun stopServiceWithSecure() = runCatching {
|
||||||
val services = getServicesWithSecure(false)
|
val services = getServicesWithSecure(false)
|
||||||
|
|
||||||
Secure.putString(mApplicationContext.contentResolver, Secure.ENABLED_ACCESSIBILITY_SERVICES, services)
|
Secure.putString(mApplicationContext.contentResolver, Secure.ENABLED_ACCESSIBILITY_SERVICES, services)
|
||||||
Secure.putInt(mApplicationContext.contentResolver, Secure.ACCESSIBILITY_ENABLED, 0)
|
Secure.putInt(mApplicationContext.contentResolver, Secure.ACCESSIBILITY_ENABLED, 0)
|
||||||
|
|
||||||
!serviceExists()
|
!hasService()
|
||||||
} catch (e: Exception) {
|
}.isSuccess
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getServicesWithRoot(withAutoJs: Boolean? = null): String = when (withAutoJs) {
|
private fun getServicesWithRoot(withAutoJs: Boolean? = null): String = when (withAutoJs) {
|
||||||
true -> attachAutoJsService(getServicesWithRoot(false))
|
true -> attachAutoJsService(getServicesWithRoot(false))
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public abstract class LayoutInspectTileService extends TileService implements La
|
|||||||
/* Ignored. */
|
/* Ignored. */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mA11yTool.isServiceRunning()) {
|
if (mA11yTool.isRunning()) {
|
||||||
mCapturing = true;
|
mCapturing = true;
|
||||||
captureCurrentWindowDelayed();
|
captureCurrentWindowDelayed();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -128,14 +128,17 @@ object WrappedShizuku {
|
|||||||
fun isInstalled(context: Context) = getLaunchIntent(context) != null
|
fun isInstalled(context: Context) = getLaunchIntent(context) != null
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun hasPermission() = try {
|
fun hasPermission() = runCatching {
|
||||||
Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
|
Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
|
||||||
} catch (e: Throwable) {
|
}.getOrElse { e ->
|
||||||
false.also { if (e.message?.contains(Regex("binder .+n[o']t been received", RegexOption.IGNORE_CASE)) == false) e.printStackTrace() }
|
if (e.message?.contains(Regex("binder .+n[o']t been received", RegexOption.IGNORE_CASE)) == false) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return@getOrElse false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun isOperational(): Boolean = isRunning() && hasPermission()
|
fun isOperational() = isRunning() && hasPermission()
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun isRunning() = mHasBinder
|
fun isRunning() = mHasBinder
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
|
|||||||
import org.autojs.autojs.extension.FlexibleArray
|
import org.autojs.autojs.extension.FlexibleArray
|
||||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
|
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
|
||||||
|
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||||
import org.autojs.autojs.runtime.ScriptRuntime
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||||
import org.autojs.autojs.runtime.api.augment.Invokable
|
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||||
@@ -22,6 +23,7 @@ import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
|||||||
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
|
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
|
||||||
import org.autojs.autojs.util.RhinoUtils.callFunction
|
import org.autojs.autojs.util.RhinoUtils.callFunction
|
||||||
import org.autojs.autojs.util.RhinoUtils.newNativeArray
|
import org.autojs.autojs.util.RhinoUtils.newNativeArray
|
||||||
|
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||||
import org.mozilla.javascript.BaseFunction
|
import org.mozilla.javascript.BaseFunction
|
||||||
import org.mozilla.javascript.Context
|
import org.mozilla.javascript.Context
|
||||||
import org.mozilla.javascript.NativeArray
|
import org.mozilla.javascript.NativeArray
|
||||||
@@ -38,8 +40,11 @@ class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
|
|||||||
::stop.name,
|
::stop.name,
|
||||||
::enable.name,
|
::enable.name,
|
||||||
::disable.name,
|
::disable.name,
|
||||||
::isRunning.name,
|
::hasInstance.name,
|
||||||
|
::hasService.name,
|
||||||
::exists.name,
|
::exists.name,
|
||||||
|
::isRunning.name,
|
||||||
|
::isOperational.name,
|
||||||
::stateListener.name,
|
::stateListener.name,
|
||||||
::registerEvent.name,
|
::registerEvent.name,
|
||||||
::registerEvents.name,
|
::registerEvents.name,
|
||||||
@@ -75,6 +80,14 @@ class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
|
|||||||
"windowRoots" to Supplier {
|
"windowRoots" to Supplier {
|
||||||
scriptRuntime.accessibilityBridge.windowRoots().map { UiObject.createRoot(it) }.toNativeArray()
|
scriptRuntime.accessibilityBridge.windowRoots().map { UiObject.createRoot(it) }.toNativeArray()
|
||||||
},
|
},
|
||||||
|
"state" to Supplier {
|
||||||
|
newNativeObject().also { o ->
|
||||||
|
o.defineProp("hasInstance", accessibilityTool.hasInstance())
|
||||||
|
o.defineProp("hasService", accessibilityTool.hasService())
|
||||||
|
o.defineProp("isRunning", accessibilityTool.isRunning())
|
||||||
|
o.defineProp("isOperational", accessibilityTool.isOperational())
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun invoke(vararg args: Any?): Any = ensureArgumentsAtMost(args, 2) {
|
override fun invoke(vararg args: Any?): Any = ensureArgumentsAtMost(args, 2) {
|
||||||
@@ -139,14 +152,32 @@ class Auto(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun isRunning(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsIsEmpty(args) {
|
fun hasInstance(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsIsEmpty(args) {
|
||||||
accessibilityTool.isServiceRunning()
|
accessibilityTool.hasInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@RhinoRuntimeFunctionInterface
|
||||||
|
fun hasService(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsIsEmpty(args) {
|
||||||
|
accessibilityTool.hasService()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun exists(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsIsEmpty(args) {
|
fun exists(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsIsEmpty(args) {
|
||||||
accessibilityTool.serviceExists()
|
accessibilityTool.hasService()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@RhinoRuntimeFunctionInterface
|
||||||
|
fun isRunning(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsIsEmpty(args) {
|
||||||
|
accessibilityTool.isRunning()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@RhinoRuntimeFunctionInterface
|
||||||
|
fun isOperational(scriptRuntime: ScriptRuntime, args: Array<out Any?>) = ensureArgumentsIsEmpty(args) {
|
||||||
|
accessibilityTool.isOperational()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.autojs.autojs.runtime.api.augment.shizuku
|
package org.autojs.autojs.runtime.api.augment.shizuku
|
||||||
|
|
||||||
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
|
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
|
||||||
|
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||||
import org.autojs.autojs.runtime.ScriptRuntime
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
import org.autojs.autojs.runtime.api.AbstractShell
|
import org.autojs.autojs.runtime.api.AbstractShell
|
||||||
import org.autojs.autojs.runtime.api.WrappedShizuku
|
import org.autojs.autojs.runtime.api.WrappedShizuku
|
||||||
@@ -8,6 +9,8 @@ import org.autojs.autojs.runtime.api.augment.Augmentable
|
|||||||
import org.autojs.autojs.runtime.api.augment.Invokable
|
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||||
import org.autojs.autojs.runtime.api.augment.app.App
|
import org.autojs.autojs.runtime.api.augment.app.App
|
||||||
import org.autojs.autojs.runtime.api.augment.shell.Shell
|
import org.autojs.autojs.runtime.api.augment.shell.Shell
|
||||||
|
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
@Suppress("unused", "UNUSED_PARAMETER")
|
@Suppress("unused", "UNUSED_PARAMETER")
|
||||||
class Shizuku(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
class Shizuku(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
||||||
@@ -21,6 +24,17 @@ class Shizuku(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRunt
|
|||||||
::currentComponent.name,
|
::currentComponent.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>(
|
||||||
|
"state" to Supplier {
|
||||||
|
newNativeObject().also { o ->
|
||||||
|
o.defineProp("isInstalled", WrappedShizuku.isInstalled(globalContext))
|
||||||
|
o.defineProp("isRunning", WrappedShizuku.isRunning())
|
||||||
|
o.defineProp("hasPermission", WrappedShizuku.hasPermission())
|
||||||
|
o.defineProp("isOperational", WrappedShizuku.isOperational())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
override fun invoke(vararg args: Any?): AbstractShell.Result = execCommand(scriptRuntime, args)
|
override fun invoke(vararg args: Any?): AbstractShell.Result = execCommand(scriptRuntime, args)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ open class AccessibilityService(final override val context: Context) : ServiceIt
|
|||||||
private val mA11yTool = AccessibilityTool(context)
|
private val mA11yTool = AccessibilityTool(context)
|
||||||
|
|
||||||
override val isRunning
|
override val isRunning
|
||||||
get() = mA11yTool.serviceExists() || mA11yTool.isServiceRunning()
|
get() = mA11yTool.hasService() || mA11yTool.isRunning()
|
||||||
|
|
||||||
override fun active(): Boolean {
|
override fun active(): Boolean {
|
||||||
return mA11yTool.restartService(true)
|
return mA11yTool.restartService(true)
|
||||||
@@ -44,7 +44,7 @@ open class AccessibilityService(final override val context: Context) : ServiceIt
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onToggleSuccess() {
|
override fun onToggleSuccess() {
|
||||||
if (mA11yTool.serviceExists() && !mA11yTool.isServiceRunning()) {
|
if (mA11yTool.hasService() && !mA11yTool.isRunning()) {
|
||||||
ViewUtils.showToast(context, R.string.text_a11y_service_enabled_but_not_running, true)
|
ViewUtils.showToast(context, R.string.text_a11y_service_enabled_but_not_running, true)
|
||||||
}
|
}
|
||||||
super.onToggleSuccess()
|
super.onToggleSuccess()
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||||||
// @Dubious by SuperMonster003 on Oct 28, 2024.
|
// @Dubious by SuperMonster003 on Oct 28, 2024.
|
||||||
// ! Is it property to start a11y service automatically here?
|
// ! Is it property to start a11y service automatically here?
|
||||||
// ! zh-CN: 无障碍服务自启动放在这里是否合适?
|
// ! zh-CN: 无障碍服务自启动放在这里是否合适?
|
||||||
AccessibilityTool(this).apply { if (!isServiceRunning()) startService(false) }
|
AccessibilityTool(this).apply { if (!isRunning()) startService(false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setApplicationLocale(context: Context) {
|
private fun setApplicationLocale(context: Context) {
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener {
|
|||||||
mLayoutInspectDialog.dismiss();
|
mLayoutInspectDialog.dismiss();
|
||||||
mLayoutInspectDialog = null;
|
mLayoutInspectDialog = null;
|
||||||
}
|
}
|
||||||
if (!mA11yTool.isServiceRunning()) {
|
if (!mA11yTool.isRunning()) {
|
||||||
if (!mA11yTool.startService(false)) {
|
if (!mA11yTool.startService(false)) {
|
||||||
ViewUtils.showToast(mContext, mContext.getString(R.string.error_no_accessibility_permission_to_capture));
|
ViewUtils.showToast(mContext, mContext.getString(R.string.error_no_accessibility_permission_to_capture));
|
||||||
mA11yTool.launchSettings();
|
mA11yTool.launchSettings();
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ open class DrawerFragment : Fragment() {
|
|||||||
override fun refreshSubtitle(aimState: Boolean) {
|
override fun refreshSubtitle(aimState: Boolean) {
|
||||||
val oldSubtitle = mAccessibilityServiceItem.subtitle
|
val oldSubtitle = mAccessibilityServiceItem.subtitle
|
||||||
if (aimState) {
|
if (aimState) {
|
||||||
if (mA11yTool.serviceExists() && !mA11yTool.isServiceRunning()) {
|
if (mA11yTool.hasService() && !mA11yTool.isRunning()) {
|
||||||
mAccessibilityServiceItem.subtitle = context.getString(R.string.text_malfunctioning)
|
mAccessibilityServiceItem.subtitle = context.getString(R.string.text_malfunctioning)
|
||||||
} else {
|
} else {
|
||||||
mAccessibilityServiceItem.subtitle = null
|
mAccessibilityServiceItem.subtitle = null
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Tue Jan 06 21:47:58 CST 2026
|
#Thu Jan 08 01:30:58 CST 2026
|
||||||
BUILD_TIME=1767707278134
|
BUILD_TIME=1767807058123
|
||||||
COMPILE_SDK_VERSION=36
|
COMPILE_SDK_VERSION=36
|
||||||
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
||||||
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
||||||
@@ -27,6 +27,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
|
|||||||
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
||||||
TARGET_SDK_VERSION=36
|
TARGET_SDK_VERSION=36
|
||||||
TARGET_SDK_VERSION_INRT=29
|
TARGET_SDK_VERSION_INRT=29
|
||||||
VERSION_BUILD=3581
|
VERSION_BUILD=3583
|
||||||
VERSION_NAME=6.7.0 Alpha13
|
VERSION_NAME=6.7.0 Alpha13
|
||||||
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
||||||
|
|||||||
Reference in New Issue
Block a user