Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,15 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
override fun onAccessibilityEvent(service: AccessibilityService, event: AccessibilityEvent): Boolean {
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
val window = service.getWindow(event.windowId)
if (window?.isFocused != false) {
val activeRoot = if (window == null) service.rootInActiveWindow else null
if (shouldAcceptWindowStateChange(
eventWindowId = event.windowId,
eventPackage = event.packageName,
eventWindowFocused = window?.isFocused,
activeRootWindowId = activeRoot?.windowId,
activeRootPackage = activeRoot?.packageName,
)) {
setLatestComponent(event.packageName, event.className)
return false
}
}
return false
Expand Down Expand Up @@ -189,6 +195,20 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
}
}

internal fun shouldAcceptWindowStateChange(
eventWindowId: Int,
eventPackage: CharSequence?,
eventWindowFocused: Boolean?,
activeRootWindowId: Int?,
activeRootPackage: CharSequence?,
): Boolean = when (eventWindowFocused) {
true -> true
false -> false
null -> eventPackage != null &&
eventWindowId == activeRootWindowId &&
eventPackage.toString() == activeRootPackage?.toString()
}

private fun AccessibilityService.getWindow(windowId: Int): AccessibilityWindowInfo? {
windows.forEach {
if (it.id == windowId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,15 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
override fun onAccessibilityEvent(service: AccessibilityService, event: AccessibilityEvent): Boolean {
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
val window = service.getWindow(event.windowId)
if (window?.isFocused != false) {
val activeRoot = if (window == null) service.rootInActiveWindow else null
if (shouldAcceptWindowStateChange(
eventWindowId = event.windowId,
eventPackage = event.packageName,
eventWindowFocused = window?.isFocused,
activeRootWindowId = activeRoot?.windowId,
activeRootPackage = activeRoot?.packageName,
)) {
setLatestComponent(event.packageName, event.className)
return false
}
}
return false
Expand Down Expand Up @@ -191,6 +197,20 @@ class ActivityInfoProvider(private val context: Context) : AccessibilityDelegate
}
}

internal fun shouldAcceptWindowStateChange(
eventWindowId: Int,
eventPackage: CharSequence?,
eventWindowFocused: Boolean?,
activeRootWindowId: Int?,
activeRootPackage: CharSequence?,
): Boolean = when (eventWindowFocused) {
true -> true
false -> false
null -> eventPackage != null &&
eventWindowId == activeRootWindowId &&
eventPackage.toString() == activeRootPackage?.toString()
}

private fun AccessibilityService.getWindow(windowId: Int): AccessibilityWindowInfo? {
windows.forEach {
if (it.id == windowId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.stardust.autojs.core.activity

import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class ActivityInfoProviderPolicyTest {

@Test
fun `accepts a focused event window`() {
assertTrue(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = true,
activeRootWindowId = 8,
activeRootPackage = "com.example.other",
),
)
}

@Test
fun `rejects an unfocused event window even when the active root matches`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = false,
activeRootWindowId = 7,
activeRootPackage = "com.example.app",
),
)
}

@Test
fun `rejects a missing event window when the active root window differs`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = null,
activeRootWindowId = 8,
activeRootPackage = "com.example.app",
),
)
}

@Test
fun `rejects a missing event window when the active root package differs`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = null,
activeRootWindowId = 7,
activeRootPackage = "com.example.other",
),
)
}

@Test
fun `accepts a missing event window verified by the active root`() {
assertTrue(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = null,
activeRootWindowId = 7,
activeRootPackage = "com.example.app",
),
)
}

@Test
fun `rejects a missing event window with no package evidence`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = null,
eventWindowFocused = null,
activeRootWindowId = 7,
activeRootPackage = null,
),
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.autojs.autojs.core.activity

import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class ActivityInfoProviderPolicyTest {

@Test
fun `accepts a focused event window`() {
assertTrue(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = true,
activeRootWindowId = 8,
activeRootPackage = "com.example.other",
),
)
}

@Test
fun `rejects an unfocused event window even when the active root matches`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = false,
activeRootWindowId = 7,
activeRootPackage = "com.example.app",
),
)
}

@Test
fun `rejects a missing event window when the active root window differs`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = null,
activeRootWindowId = 8,
activeRootPackage = "com.example.app",
),
)
}

@Test
fun `rejects a missing event window when the active root package differs`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = null,
activeRootWindowId = 7,
activeRootPackage = "com.example.other",
),
)
}

@Test
fun `accepts a missing event window verified by the active root`() {
assertTrue(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = "com.example.app",
eventWindowFocused = null,
activeRootWindowId = 7,
activeRootPackage = "com.example.app",
),
)
}

@Test
fun `rejects a missing event window with no package evidence`() {
assertFalse(
shouldAcceptWindowStateChange(
eventWindowId = 7,
eventPackage = null,
eventWindowFocused = null,
activeRootWindowId = 7,
activeRootPackage = null,
),
)
}

}