6.1.0 - 变更包名 新增投影媒体权限开关/tasks模块 扩展内置模块方法 重构内置模块及构建脚本
This commit is contained in:
1 parent
e0374a835e
commit
f68ad1c993
770 files changed
+15821
-14759
No files matched your search
+4
-36
@@ -1,43 +1,11 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_16
|
||||
}
|
||||
ext {
|
||||
namespace = 'com.stardust.automator'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion versions.project.compile
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion versions.project.mini
|
||||
targetSdkVersion versions.project.target
|
||||
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_16
|
||||
targetCompatibility JavaVersion.VERSION_16
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
apply {
|
||||
from rootProject.file('config.gradle')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation "junit:junit:${versions.junit}"
|
||||
|
||||
api project(':common')
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.stardust.automator
|
||||
|
||||
import android.content.Context
|
||||
import android.support.test.InstrumentationRegistry
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumentation test, which will execute on an Android device.
|
||||
*
|
||||
* @see [Testing documentation](http://d.android.com/tools/testing)
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getTargetContext()
|
||||
|
||||
assertEquals("com.stardust.automator.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
package com.stardust.automator.simple_action
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
import com.stardust.automator.UiObject
|
||||
import com.stardust.automator.test.TestUiObject
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/5.
|
||||
*/
|
||||
class DepthFirstSearchTargetActionTest {
|
||||
|
||||
@Test
|
||||
fun perform() {
|
||||
val action = DepthFirstSearchTargetAction(AccessibilityNodeInfo.ACTION_CLICK, FilterAction.Filter { root ->
|
||||
val list = ArrayList<UiObject>()
|
||||
for (i in 0 until root.childCount) {
|
||||
list.add(root.child(i))
|
||||
}
|
||||
list
|
||||
})
|
||||
val root = TestUiObject(5)
|
||||
action.perform(root)
|
||||
println(TestUiObject.max)
|
||||
assertEquals(1, TestUiObject.count.toLong())
|
||||
}
|
||||
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
package com.stardust.automator.simple_action
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
import com.stardust.automator.UiObject
|
||||
import com.stardust.automator.test.TestUiObject
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/5.
|
||||
*/
|
||||
class ScrollMaxActionTest {
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun perform() {
|
||||
val action = ScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)
|
||||
val root = TestUiObject(20)
|
||||
action.perform(root)
|
||||
println(TestUiObject.max)
|
||||
assertEquals(1, TestUiObject.count.toLong())
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.stardust.automator">
|
||||
|
||||
package="com.stardust.automator"
|
||||
>
|
||||
|
||||
<application
|
||||
android:supportsRtl="true"
|
||||
>
|
||||
|
||||
</application>
|
||||
<application android:supportsRtl="true" />
|
||||
|
||||
</manifest>
|
||||
@@ -5,7 +5,6 @@ import android.os.Bundle
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
abstract class ActionArgument private constructor(protected val mKey: String) {
|
||||
|
||||
abstract fun putIn(bundle: Bundle)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.stardust.automator
|
||||
|
||||
import android.accessibilityservice.AccessibilityService
|
||||
import android.accessibilityservice.AccessibilityService.*
|
||||
import android.accessibilityservice.GestureDescription
|
||||
import android.graphics.Path
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.annotation.RequiresApi
|
||||
import android.view.ViewConfiguration
|
||||
|
||||
import com.stardust.concurrent.VolatileBox
|
||||
@@ -16,7 +16,6 @@ import com.stardust.util.ScreenMetrics
|
||||
/**
|
||||
* Created by Stardust on 2017/5/16.
|
||||
*/
|
||||
|
||||
class GlobalActionAutomator(private val mHandler: Handler?, private val serviceProvider: () -> AccessibilityService) {
|
||||
|
||||
private val service: AccessibilityService
|
||||
@@ -28,41 +27,72 @@ class GlobalActionAutomator(private val mHandler: Handler?, private val serviceP
|
||||
mScreenMetrics = screenMetrics
|
||||
}
|
||||
|
||||
fun back(): Boolean {
|
||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
|
||||
fun back(): Boolean = performGlobalAction(GLOBAL_ACTION_BACK)
|
||||
|
||||
fun home(): Boolean = performGlobalAction(GLOBAL_ACTION_HOME)
|
||||
|
||||
fun recents(): Boolean = performGlobalAction(GLOBAL_ACTION_RECENTS)
|
||||
|
||||
fun notifications(): Boolean = performGlobalAction(GLOBAL_ACTION_NOTIFICATIONS)
|
||||
|
||||
fun quickSettings(): Boolean = performGlobalAction(GLOBAL_ACTION_QUICK_SETTINGS)
|
||||
|
||||
fun powerDialog(): Boolean = performGlobalAction(GLOBAL_ACTION_POWER_DIALOG)
|
||||
|
||||
fun splitScreen(): Boolean = performGlobalAction(GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)
|
||||
|
||||
fun lockScreen(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_LOCK_SCREEN)
|
||||
}
|
||||
|
||||
fun home(): Boolean {
|
||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME)
|
||||
fun takeScreenshot(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> performGlobalAction(GLOBAL_ACTION_TAKE_SCREENSHOT)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_TAKE_SCREENSHOT)
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
fun powerDialog(): Boolean {
|
||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG)
|
||||
fun headsethook(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> performGlobalAction(GLOBAL_ACTION_KEYCODE_HEADSETHOOK)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_KEYCODE_HEADSETHOOK)
|
||||
}
|
||||
|
||||
private fun performGlobalAction(globalAction: Int): Boolean {
|
||||
return service.performGlobalAction(globalAction)
|
||||
fun accessibilityButton(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> performGlobalAction(GLOBAL_ACTION_ACCESSIBILITY_BUTTON)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_ACCESSIBILITY_BUTTON)
|
||||
}
|
||||
|
||||
fun notifications(): Boolean {
|
||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS)
|
||||
fun accessibilityButtonChooser(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> performGlobalAction(GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER)
|
||||
}
|
||||
|
||||
fun quickSettings(): Boolean {
|
||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS)
|
||||
fun accessibilityShortcut(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> performGlobalAction(GLOBAL_ACTION_ACCESSIBILITY_SHORTCUT)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_ACCESSIBILITY_SHORTCUT)
|
||||
}
|
||||
|
||||
fun recents(): Boolean {
|
||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS)
|
||||
fun accessibilityAllApps(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> performGlobalAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS)
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun splitScreen(): Boolean {
|
||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)
|
||||
fun dismissNotificationShade(): Boolean = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> performGlobalAction(GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE)
|
||||
else -> tryPerformGlobalActionWithLowerApi(GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE)
|
||||
}
|
||||
|
||||
private fun performGlobalAction(globalAction: Int): Boolean = service.performGlobalAction(globalAction)
|
||||
|
||||
// @Hint by SuperMonster003 on May 12, 2022.
|
||||
// ! Global actions such as GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS requires API Level S.
|
||||
// ! However, there is a high possibility that global actions mentioned above
|
||||
// ! can be performed NORMALLY on lower API Level device (e.g. API R).
|
||||
private fun tryPerformGlobalActionWithLowerApi(action: Int) = try {
|
||||
performGlobalAction(action)
|
||||
} catch (e: Throwable) {
|
||||
false
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun gesture(start: Long, duration: Long, vararg points: IntArray): Boolean {
|
||||
val path = pointsToPath(points)
|
||||
return gestures(GestureDescription.StrokeDescription(path, start, duration))
|
||||
@@ -78,13 +108,11 @@ class GlobalActionAutomator(private val mHandler: Handler?, private val serviceP
|
||||
return path
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun gestureAsync(start: Long, duration: Long, vararg points: IntArray) {
|
||||
val path = pointsToPath(points)
|
||||
gesturesAsync(GestureDescription.StrokeDescription(path, start, duration))
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun gestures(vararg strokes: GestureDescription.StrokeDescription): Boolean {
|
||||
val builder = GestureDescription.Builder()
|
||||
for (stroke in strokes) {
|
||||
@@ -98,7 +126,6 @@ class GlobalActionAutomator(private val mHandler: Handler?, private val serviceP
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
private fun gesturesWithHandler(handler: Handler, description: GestureDescription): Boolean {
|
||||
val result = VolatileDispose<Boolean>()
|
||||
service.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
|
||||
@@ -113,7 +140,6 @@ class GlobalActionAutomator(private val mHandler: Handler?, private val serviceP
|
||||
return result.blockedGet()
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
private fun gesturesWithoutHandler(description: GestureDescription): Boolean {
|
||||
prepareLooperIfNeeded()
|
||||
val result = VolatileBox(false)
|
||||
@@ -136,7 +162,6 @@ class GlobalActionAutomator(private val mHandler: Handler?, private val serviceP
|
||||
return result.get()
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun gesturesAsync(vararg strokes: GestureDescription.StrokeDescription) {
|
||||
val builder = GestureDescription.Builder()
|
||||
for (stroke in strokes) {
|
||||
@@ -156,32 +181,16 @@ class GlobalActionAutomator(private val mHandler: Handler?, private val serviceP
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun click(x: Int, y: Int): Boolean {
|
||||
return press(x, y, ViewConfiguration.getTapTimeout() + 50)
|
||||
}
|
||||
fun click(x: Int, y: Int): Boolean = press(x, y, ViewConfiguration.getTapTimeout() + 50)
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun press(x: Int, y: Int, delay: Int): Boolean {
|
||||
return gesture(0, delay.toLong(), intArrayOf(x, y))
|
||||
}
|
||||
fun press(x: Int, y: Int, delay: Int): Boolean = gesture(0, delay.toLong(), intArrayOf(x, y))
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun longClick(x: Int, y: Int): Boolean {
|
||||
return gesture(0, (ViewConfiguration.getLongPressTimeout() + 200).toLong(), intArrayOf(x, y))
|
||||
}
|
||||
fun longClick(x: Int, y: Int): Boolean = gesture(0, (ViewConfiguration.getLongPressTimeout() + 200).toLong(), intArrayOf(x, y))
|
||||
|
||||
private fun scaleX(x: Int): Int {
|
||||
return mScreenMetrics?.scaleX(x) ?: x
|
||||
}
|
||||
private fun scaleX(x: Int): Int = mScreenMetrics?.scaleX(x) ?: x
|
||||
|
||||
private fun scaleY(y: Int): Int {
|
||||
return mScreenMetrics?.scaleX(y) ?: y
|
||||
}
|
||||
private fun scaleY(y: Int): Int = mScreenMetrics?.scaleX(y) ?: y
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
fun swipe(x1: Int, y1: Int, x2: Int, y2: Int, delay: Long): Boolean {
|
||||
return gesture(0, delay, intArrayOf(x1, y1), intArrayOf(x2, y2))
|
||||
}
|
||||
fun swipe(x1: Int, y1: Int, x2: Int, y2: Int, delay: Long): Boolean = gesture(0, delay, intArrayOf(x1, y1), intArrayOf(x2, y2))
|
||||
|
||||
}
|
||||
@@ -1,17 +1,14 @@
|
||||
package com.stardust.automator
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import com.stardust.automator.filter.*
|
||||
import com.stardust.automator.search.BFS
|
||||
import com.stardust.automator.search.DFS
|
||||
import com.stardust.automator.search.SearchAlgorithm
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/8.
|
||||
*/
|
||||
|
||||
open class UiGlobalSelector {
|
||||
|
||||
private val mSelector = Selector()
|
||||
@@ -162,7 +159,7 @@ open class UiGlobalSelector {
|
||||
fun drawingOrder(order: Int): UiGlobalSelector {
|
||||
mSelector.add(object : Filter {
|
||||
override fun filter(node: UiObject): Boolean {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && node.drawingOrder == order
|
||||
return node.drawingOrder == order
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
|
||||
@@ -23,11 +23,10 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
* Modified by SuperMonster003 as of May 26, 2022.
|
||||
*/
|
||||
|
||||
open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllocator?, depth: Int, private val mIndexInParent: Int) : AccessibilityNodeInfoCompat(info) {
|
||||
|
||||
|
||||
private var mStackTrace = ""
|
||||
private var mDepth = 0
|
||||
|
||||
@@ -41,16 +40,29 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
|
||||
}
|
||||
|
||||
|
||||
constructor(info: Any?, allocator: AccessibilityNodeInfoAllocator, indexInParent: Int) : this(info, allocator, 0, indexInParent) {}
|
||||
constructor(info: Any?, allocator: AccessibilityNodeInfoAllocator, indexInParent: Int) : this(info, allocator, 0, indexInParent)
|
||||
|
||||
@JvmOverloads
|
||||
constructor(info: Any?, depth: Int = 0, indexInParent: Int = -1) : this(info, null, depth, indexInParent)
|
||||
|
||||
open fun parent(): UiObject? {
|
||||
try {
|
||||
val parent = super.getParent() ?: return null
|
||||
return UiObject(parent.info, mDepth - 1, -1)
|
||||
val node = super.getParent() ?: return null
|
||||
val parent = node.parent;
|
||||
var indexInParent = -1
|
||||
if (parent == null) {
|
||||
indexInParent = 0
|
||||
} else {
|
||||
// @Dubious by SuperMonster003 on May 26, 2022.
|
||||
// ! May lead to poor performance?
|
||||
for (i in 0 until parent.childCount) {
|
||||
if (parent.getChild(i) == node) {
|
||||
indexInParent = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return UiObject(node.unwrap(), mDepth - 1, indexInParent)
|
||||
} catch (e: IllegalStateException) {
|
||||
// FIXME: 2017/5/5
|
||||
return null
|
||||
@@ -61,7 +73,7 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
open fun child(i: Int): UiObject? {
|
||||
try {
|
||||
val child = super.getChild(i) ?: return null
|
||||
return UiObject(child.info, mDepth + 1, i)
|
||||
return UiObject(child.unwrap(), mDepth + 1, i)
|
||||
} catch (e: IllegalStateException) {
|
||||
// FIXME: 2017/5/5
|
||||
return null
|
||||
@@ -164,55 +176,55 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
}
|
||||
|
||||
fun click(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_CLICK)
|
||||
return performAction(ACTION_CLICK)
|
||||
}
|
||||
|
||||
fun longClick(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK)
|
||||
return performAction(ACTION_LONG_CLICK)
|
||||
}
|
||||
|
||||
fun accessibilityFocus(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS)
|
||||
return performAction(ACTION_ACCESSIBILITY_FOCUS)
|
||||
}
|
||||
|
||||
fun clearAccessibilityFocus(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS)
|
||||
return performAction(ACTION_CLEAR_ACCESSIBILITY_FOCUS)
|
||||
}
|
||||
|
||||
fun focus(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_FOCUS)
|
||||
return performAction(ACTION_FOCUS)
|
||||
}
|
||||
|
||||
fun clearFocus(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_FOCUS)
|
||||
return performAction(ACTION_CLEAR_FOCUS)
|
||||
}
|
||||
|
||||
fun copy(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_COPY)
|
||||
return performAction(ACTION_COPY)
|
||||
}
|
||||
|
||||
fun paste(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_PASTE)
|
||||
return performAction(ACTION_PASTE)
|
||||
}
|
||||
|
||||
fun select(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_SELECT)
|
||||
return performAction(ACTION_SELECT)
|
||||
}
|
||||
|
||||
fun cut(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_CUT)
|
||||
return performAction(ACTION_CUT)
|
||||
}
|
||||
|
||||
fun collapse(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_COLLAPSE)
|
||||
return performAction(ACTION_COLLAPSE)
|
||||
}
|
||||
|
||||
fun expand(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_EXPAND)
|
||||
return performAction(ACTION_EXPAND)
|
||||
}
|
||||
|
||||
fun dismiss(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_DISMISS)
|
||||
return performAction(ACTION_DISMISS)
|
||||
}
|
||||
|
||||
fun show(): Boolean {
|
||||
@@ -220,11 +232,11 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
}
|
||||
|
||||
fun scrollForward(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD)
|
||||
return performAction(ACTION_SCROLL_FORWARD)
|
||||
}
|
||||
|
||||
fun scrollBackward(): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD)
|
||||
return performAction(ACTION_SCROLL_BACKWARD)
|
||||
}
|
||||
|
||||
fun scrollUp(): Boolean {
|
||||
@@ -248,66 +260,67 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
}
|
||||
|
||||
fun setSelection(s: Int, e: Int): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_SET_SELECTION,
|
||||
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, s),
|
||||
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, e))
|
||||
return performAction(
|
||||
ACTION_SET_SELECTION,
|
||||
ActionArgument.IntActionArgument(ACTION_ARGUMENT_SELECTION_START_INT, s),
|
||||
ActionArgument.IntActionArgument(ACTION_ARGUMENT_SELECTION_END_INT, e)
|
||||
)
|
||||
}
|
||||
|
||||
fun setText(text: String): Boolean {
|
||||
return performAction(AccessibilityNodeInfoCompat.ACTION_SET_TEXT,
|
||||
ActionArgument.CharSequenceActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text))
|
||||
return performAction(
|
||||
ACTION_SET_TEXT,
|
||||
ActionArgument.CharSequenceActionArgument(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text)
|
||||
)
|
||||
}
|
||||
|
||||
fun setProgress(value: Float): Boolean {
|
||||
return performAction(ACTION_SET_PROGRESS.id,
|
||||
ActionArgument.FloatActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE, value))
|
||||
return performAction(
|
||||
ACTION_SET_PROGRESS.id,
|
||||
ActionArgument.FloatActionArgument(ACTION_ARGUMENT_PROGRESS_VALUE, value)
|
||||
)
|
||||
}
|
||||
|
||||
fun scrollTo(row: Int, column: Int): Boolean {
|
||||
return performAction(ACTION_SCROLL_TO_POSITION.id,
|
||||
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_ROW_INT, row),
|
||||
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT, column))
|
||||
return performAction(
|
||||
ACTION_SCROLL_TO_POSITION.id,
|
||||
ActionArgument.IntActionArgument(ACTION_ARGUMENT_ROW_INT, row),
|
||||
ActionArgument.IntActionArgument(ACTION_ARGUMENT_COLUMN_INT, column)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getChild(index: Int): AccessibilityNodeInfoCompat {
|
||||
return if (allocator == null) super.getChild(index) else allocator.getChild(this, index)
|
||||
return allocator?.getChild(this, index) ?: super.getChild(index)
|
||||
}
|
||||
|
||||
override fun getParent(): AccessibilityNodeInfoCompat {
|
||||
return if (allocator == null) super.getParent() else allocator.getParent(this)
|
||||
return allocator?.getParent(this) ?: super.getParent()
|
||||
}
|
||||
|
||||
|
||||
open fun checkable(): Boolean {
|
||||
return isCheckable
|
||||
}
|
||||
|
||||
|
||||
open fun checked(): Boolean {
|
||||
return isChecked
|
||||
}
|
||||
|
||||
|
||||
open fun focusable(): Boolean {
|
||||
return isFocusable
|
||||
}
|
||||
|
||||
|
||||
open fun focused(): Boolean {
|
||||
return isFocused
|
||||
}
|
||||
|
||||
|
||||
open fun visibleToUser(): Boolean {
|
||||
return isVisibleToUser
|
||||
}
|
||||
|
||||
|
||||
open fun accessibilityFocused(): Boolean {
|
||||
return isAccessibilityFocused
|
||||
}
|
||||
|
||||
|
||||
open fun selected(): Boolean {
|
||||
return isSelected
|
||||
}
|
||||
@@ -316,22 +329,18 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
return isClickable
|
||||
}
|
||||
|
||||
|
||||
open fun longClickable(): Boolean {
|
||||
return isLongClickable
|
||||
}
|
||||
|
||||
|
||||
open fun enabled(): Boolean {
|
||||
return isEnabled
|
||||
}
|
||||
|
||||
|
||||
fun password(): Boolean {
|
||||
return isPassword
|
||||
}
|
||||
|
||||
|
||||
open fun scrollable(): Boolean {
|
||||
return isScrollable
|
||||
}
|
||||
@@ -348,7 +357,6 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
return if (collectionItemInfo == null) -1 else collectionItemInfo.rowSpan
|
||||
}
|
||||
|
||||
|
||||
open fun columnSpan(): Int {
|
||||
return if (collectionItemInfo == null) -1 else collectionItemInfo.columnSpan
|
||||
}
|
||||
@@ -357,14 +365,13 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
return if (collectionInfo == null) 0 else collectionInfo.rowCount
|
||||
}
|
||||
|
||||
|
||||
open fun columnCount(): Int {
|
||||
return if (collectionInfo == null) 0 else collectionInfo.columnCount
|
||||
}
|
||||
|
||||
override fun findAccessibilityNodeInfosByText(text: String): List<AccessibilityNodeInfoCompat> {
|
||||
return allocator?.findAccessibilityNodeInfosByText(this, text)
|
||||
?: super.findAccessibilityNodeInfosByText(text)
|
||||
?: super.findAccessibilityNodeInfosByText(text)
|
||||
}
|
||||
|
||||
fun findByText(text: String): List<UiObject> {
|
||||
@@ -373,7 +380,7 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
|
||||
override fun findAccessibilityNodeInfosByViewId(viewId: String): List<AccessibilityNodeInfoCompat> {
|
||||
return allocator?.findAccessibilityNodeInfosByViewId(this, viewId)
|
||||
?: super.findAccessibilityNodeInfosByViewId(viewId)
|
||||
?: super.findAccessibilityNodeInfosByViewId(viewId)
|
||||
}
|
||||
|
||||
fun findByViewId(viewId: String): List<UiObject> {
|
||||
@@ -391,17 +398,21 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
|
||||
companion object {
|
||||
|
||||
val ACTION_APPEND_TEXT = 0x00200001
|
||||
const val ACTION_APPEND_TEXT = 0x00200001
|
||||
|
||||
private const val TAG = "UiObject"
|
||||
private const val DEBUG = false
|
||||
|
||||
|
||||
fun createRoot(root: AccessibilityNodeInfo): UiObject {
|
||||
// @Hint by SuperMonster003 on May 12, 2022.
|
||||
// ! Param root should be nullable because an exception
|
||||
// ! will happen on devices with API Level higher than 31.
|
||||
// ! Wrapped java.lang.NullPointerException: Parameter specified as non-null is null:
|
||||
// ! method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter root.
|
||||
fun createRoot(root: AccessibilityNodeInfo?): UiObject {
|
||||
return UiObject(root, null, 0, -1)
|
||||
}
|
||||
|
||||
fun createRoot(root: AccessibilityNodeInfo, allocator: AccessibilityNodeInfoAllocator?): UiObject {
|
||||
fun createRoot(root: AccessibilityNodeInfo?, allocator: AccessibilityNodeInfoAllocator?): UiObject {
|
||||
return UiObject(root, allocator, 0, -1)
|
||||
}
|
||||
|
||||
@@ -414,5 +425,4 @@ open class UiObject(info: Any?, private val allocator: AccessibilityNodeInfoAllo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,19 +1,8 @@
|
||||
package com.stardust.automator
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
import com.stardust.util.Consumer
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.*
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_ROW_INT
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_CLEAR_FOCUS
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_CLICK
|
||||
@@ -38,11 +27,11 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_UP
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_PROGRESS
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SHOW_ON_SCREEN
|
||||
import com.stardust.util.Consumer
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class UiObjectCollection private constructor(private val mNodes: List<UiObject?>) {
|
||||
|
||||
|
||||
@@ -253,7 +242,7 @@ class UiObjectCollection private constructor(private val mNodes: List<UiObject?>
|
||||
|
||||
companion object {
|
||||
|
||||
val EMPTY = UiObjectCollection.of(emptyList())
|
||||
val EMPTY = of(emptyList())
|
||||
|
||||
fun of(list: List<UiObject?>): UiObjectCollection {
|
||||
return UiObjectCollection(list)
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
package com.stardust.automator.filter
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
import com.stardust.automator.UiObject
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class BooleanFilter(private val mBooleanSupplier: BooleanSupplier, private val mExceptedValue: Boolean) : Filter {
|
||||
|
||||
interface BooleanSupplier {
|
||||
@@ -24,7 +18,7 @@ class BooleanFilter(private val mBooleanSupplier: BooleanSupplier, private val m
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return mBooleanSupplier.toString() + "(" + mExceptedValue + ")"
|
||||
return "$mBooleanSupplier($mExceptedValue)"
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -199,7 +193,6 @@ class BooleanFilter(private val mBooleanSupplier: BooleanSupplier, private val m
|
||||
|
||||
val CONTEXT_CLICKABLE: BooleanSupplier = object : BooleanSupplier {
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
override fun get(node: UiObject): Boolean {
|
||||
return node.isContextClickable
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import java.util.Locale
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class BoundsFilter(private val mBounds: Rect, private val mType: Int) : Filter {
|
||||
|
||||
override fun filter(node: UiObject): Boolean {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
object ClassNameFilters {
|
||||
|
||||
private val CLASS_NAME_GETTER = object : KeyGetter {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
object DescFilters {
|
||||
|
||||
private val DESC_GETTER = object : KeyGetter {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
interface Filter {
|
||||
|
||||
fun filter(node: UiObject): Boolean
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
object IdFilter {
|
||||
|
||||
private val ID_GETTER = object : KeyGetter {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/11/5.
|
||||
*/
|
||||
|
||||
class IntFilter(private val mIntProperty: IntProperty, private val mValue: Int) : Filter {
|
||||
|
||||
interface IntProperty {
|
||||
@@ -17,7 +16,7 @@ class IntFilter(private val mIntProperty: IntProperty, private val mValue: Int)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return mIntProperty.toString() + "(" + mValue + ")"
|
||||
return "$mIntProperty($mValue)"
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
interface KeyGetter {
|
||||
|
||||
fun getKey(nodeInfo: UiObject): String?
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
object PackageNameFilter {
|
||||
|
||||
private val PACKAGE_NAME_GETTER = object : KeyGetter {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class StringContainsFilter internal constructor(private val mContains: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
|
||||
override fun filter(node: UiObject): Boolean {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class StringEndsWithFilter(private val mSuffix: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
|
||||
override fun filter(node: UiObject): Boolean {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class StringEqualsFilter(private val mValue: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
|
||||
override fun filter(node: UiObject): Boolean {
|
||||
@@ -16,6 +15,6 @@ class StringEqualsFilter(private val mValue: String, private val mKeyGetter: Key
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return mKeyGetter.toString() + "(\"" + mValue + "\")"
|
||||
return "$mKeyGetter(\"$mValue\")"
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class StringMatchesFilter internal constructor(private val mRegex: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
|
||||
override fun filter(node: UiObject): Boolean {
|
||||
@@ -14,6 +13,6 @@ class StringMatchesFilter internal constructor(private val mRegex: String, priva
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return mKeyGetter.toString() + "Matches(\"" + mRegex + "\")"
|
||||
return "${mKeyGetter}Matches(\"$mRegex\")"
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
class StringStartsWithFilter(private val mPrefix: String, private val mKeyGetter: KeyGetter) : Filter {
|
||||
|
||||
override fun filter(node: UiObject): Boolean {
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
object TextFilters {
|
||||
|
||||
private val TEXT_GETTER = object : KeyGetter {
|
||||
|
||||
@@ -9,7 +9,6 @@ import kotlin.collections.ArrayList
|
||||
/**
|
||||
* Created by Stardust on 2017/3/9.
|
||||
*/
|
||||
|
||||
object DFS : SearchAlgorithm {
|
||||
|
||||
override fun search(root: UiObject, filter: Filter, limit: Int): ArrayList<UiObject> {
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.stardust.util.SparseArrayEntries
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
interface Able {
|
||||
|
||||
fun isAble(node: UiObject): Boolean
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
package com.stardust.automator.simple_action
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.RequiresApi
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
import com.stardust.automator.UiObject
|
||||
import com.stardust.util.MapBuilder
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
object ActionFactory {
|
||||
|
||||
private val searchUpAction = MapBuilder<Int, Any>()
|
||||
@@ -39,7 +35,6 @@ object ActionFactory {
|
||||
DepthFirstSearchTargetAction(action, FilterAction.BoundsFilter(rect))
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
fun createActionWithEditableFilter(action: Int, index: Int, text: String): SimpleAction {
|
||||
return object : SearchTargetAction(action, FilterAction.EditableFilter(index)) {
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package com.stardust.automator.simple_action
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
interface ActionTarget {
|
||||
|
||||
fun createAction(action: Int, vararg params: Any): SimpleAction
|
||||
@@ -26,7 +23,6 @@ interface ActionTarget {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
class EditableActionTarget(private val mIndex: Int) : ActionTarget {
|
||||
|
||||
override fun createAction(action: Int, vararg params: Any): SimpleAction {
|
||||
|
||||
-1
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
class DepthFirstSearchTargetAction(action: Int, filter: FilterAction.Filter) : SearchTargetAction(action, filter) {
|
||||
|
||||
private val mAble: Able = Able.ABLE_MAP.get(action)
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.util.*
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
abstract class FilterAction(private val mFilter: Filter) : SimpleAction() {
|
||||
|
||||
abstract fun perform(nodes: List<UiObject>): Boolean
|
||||
|
||||
@@ -10,7 +10,6 @@ import java.util.HashSet
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
class ScrollMaxAction(private val mScrollAction: Int) : SimpleAction() {
|
||||
private var mMaxScrollableNode: UiObject? = null
|
||||
private var mRootNode: UiObject? = null
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package com.stardust.automator.simple_action
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
|
||||
import com.stardust.automator.UiObject
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
abstract class SearchTargetAction(val action: Int, filter: FilterAction.Filter) : FilterAction(filter) {
|
||||
|
||||
override fun perform(nodes: List<UiObject>): Boolean {
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
class SearchUpTargetAction(action: Int, filter: Filter) : SearchTargetAction(action, filter) {
|
||||
private val mAble: Able = Able.ABLE_MAP.get(action)
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.stardust.automator.UiObject
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
abstract class SimpleAction {
|
||||
|
||||
@Volatile
|
||||
|
||||
@@ -2,29 +2,28 @@ package com.stardust.automator.test
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import com.stardust.automator.UiObject
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/5.
|
||||
*/
|
||||
|
||||
class TestUiObject @JvmOverloads constructor(private val mChildCount: Int = Math.max(0, random.nextInt(6) - 2)) : UiObject(null) {
|
||||
class TestUiObject @JvmOverloads constructor(private val mChildCount: Int = max(0, random.nextInt(6) - 2)) : UiObject(null) {
|
||||
|
||||
private val mHashCode = random.nextInt()
|
||||
private var mRecycled = false
|
||||
|
||||
init {
|
||||
count++
|
||||
max = Math.max(max, count)
|
||||
max = max(max, count)
|
||||
}
|
||||
|
||||
override fun child(i: Int): UiObject? {
|
||||
override fun child(i: Int): UiObject {
|
||||
return TestUiObject()
|
||||
}
|
||||
|
||||
override fun parent(): UiObject? {
|
||||
override fun parent(): UiObject {
|
||||
return TestUiObject()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
package com.stardust.notification
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.os.Build
|
||||
import android.os.Parcel
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/30.
|
||||
*/
|
||||
|
||||
class Notification private constructor(val packageName: String) : android.app.Notification() {
|
||||
|
||||
val text: String?
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
get() = extras.getString(EXTRA_TEXT)
|
||||
|
||||
val title: String?
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
get() = extras.getString(EXTRA_TITLE)
|
||||
|
||||
fun click() {
|
||||
@@ -38,13 +32,11 @@ class Notification private constructor(val packageName: String) : android.app.No
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
"Notification{" +
|
||||
"packageName='" + packageName + "', " +
|
||||
"title='" + title + ", " +
|
||||
"text='" + text + "'" +
|
||||
"} "
|
||||
} else super.toString()
|
||||
return "Notification{" +
|
||||
"packageName='" + packageName + "', " +
|
||||
"title='" + title + ", " +
|
||||
"text='" + text + "'" +
|
||||
"} "
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -68,14 +60,12 @@ class Notification private constructor(val packageName: String) : android.app.No
|
||||
to.tickerView = from.tickerView
|
||||
to.contentView = from.contentView
|
||||
to.bigContentView = from.bigContentView
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
to.headsUpContentView = from.headsUpContentView
|
||||
to.audioAttributes = from.audioAttributes
|
||||
to.color = from.color
|
||||
to.visibility = from.visibility
|
||||
to.category = from.category
|
||||
to.publicVersion = from.publicVersion
|
||||
}
|
||||
to.headsUpContentView = from.headsUpContentView
|
||||
to.audioAttributes = from.audioAttributes
|
||||
to.color = from.color
|
||||
to.visibility = from.visibility
|
||||
to.category = from.category
|
||||
to.publicVersion = from.publicVersion
|
||||
to.largeIcon = from.largeIcon
|
||||
to.sound = from.sound
|
||||
to.audioStreamType = from.audioStreamType
|
||||
@@ -86,10 +76,8 @@ class Notification private constructor(val packageName: String) : android.app.No
|
||||
to.defaults = from.defaults
|
||||
to.flags = from.flags
|
||||
to.priority = from.priority
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
to.extras = from.extras
|
||||
to.actions = from.actions
|
||||
}
|
||||
to.extras = from.extras
|
||||
to.actions = from.actions
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
package com.stardust.notification
|
||||
|
||||
import android.app.Notification
|
||||
import android.os.Build
|
||||
import android.os.Parcel
|
||||
import android.service.notification.StatusBarNotification
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
import com.stardust.view.accessibility.NotificationListener
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/10/30.
|
||||
*/
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
class NotificationListenerService : android.service.notification.NotificationListenerService() {
|
||||
|
||||
private val mNotificationListeners = CopyOnWriteArrayList<NotificationListener>()
|
||||
|
||||
@@ -2,12 +2,10 @@ package com.stardust.view.accessibility
|
||||
|
||||
import android.accessibilityservice.AccessibilityService
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/14.
|
||||
*/
|
||||
|
||||
interface AccessibilityDelegate {
|
||||
|
||||
/**
|
||||
|
||||
+3
-19
@@ -1,20 +1,14 @@
|
||||
package com.stardust.view.accessibility
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||
import android.util.Log
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||
import com.stardust.automator.BuildConfig
|
||||
|
||||
import java.util.Arrays
|
||||
import java.util.HashMap
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/22.
|
||||
*/
|
||||
|
||||
open class AccessibilityNodeInfoAllocator {
|
||||
|
||||
private val mAccessibilityNodeInfoList = HashMap<AccessibilityNodeInfo, String?>()
|
||||
@@ -53,7 +47,6 @@ open class AccessibilityNodeInfoAllocator {
|
||||
return list
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
open fun findAccessibilityNodeInfosByViewId(root: AccessibilityNodeInfo, id: String): List<AccessibilityNodeInfo> {
|
||||
val list = root.findAccessibilityNodeInfosByViewId(id)
|
||||
addAll(list)
|
||||
@@ -135,7 +128,6 @@ open class AccessibilityNodeInfoAllocator {
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
override fun findAccessibilityNodeInfosByViewId(root: AccessibilityNodeInfo, id: String): List<AccessibilityNodeInfo> {
|
||||
return root.findAccessibilityNodeInfosByViewId(id)
|
||||
}
|
||||
@@ -148,14 +140,6 @@ open class AccessibilityNodeInfoAllocator {
|
||||
return root.findAccessibilityNodeInfosByText(text)
|
||||
}
|
||||
|
||||
override fun recycle(nodeInfo: AccessibilityNodeInfo) {
|
||||
super.recycle(nodeInfo)
|
||||
}
|
||||
|
||||
override fun recycle(nodeInfo: AccessibilityNodeInfoCompat) {
|
||||
super.recycle(nodeInfo)
|
||||
}
|
||||
|
||||
override fun recycleAll(): Int {
|
||||
return -1
|
||||
}
|
||||
@@ -167,7 +151,7 @@ open class AccessibilityNodeInfoAllocator {
|
||||
|
||||
val NONE: AccessibilityNodeInfoAllocator = NoOpAllocator()
|
||||
|
||||
private val TAG = "AccessibilityAllocator"
|
||||
private const val TAG = "AccessibilityAllocator"
|
||||
private val DEBUG = BuildConfig.DEBUG
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||
/**
|
||||
* Created by Stardust on 2017/3/6.
|
||||
*/
|
||||
|
||||
object AccessibilityNodeInfoHelper {
|
||||
|
||||
/**
|
||||
|
||||
+2
-3
@@ -12,12 +12,11 @@ import java.util.concurrent.CopyOnWriteArrayList
|
||||
/**
|
||||
* Created by Stardust on 2017/11/3.
|
||||
*/
|
||||
|
||||
class AccessibilityNotificationObserver(private val mContext: Context) : NotificationListener, AccessibilityDelegate {
|
||||
private val mNotificationListeners = CopyOnWriteArrayList<NotificationListener>()
|
||||
private val mToastListeners = CopyOnWriteArrayList<ToastListener>()
|
||||
|
||||
override val eventTypes: Set<Int>?
|
||||
override val eventTypes: Set<Int>
|
||||
get() = EVENT_TYPES
|
||||
|
||||
inner class Toast(val packageName: String, texts: List<CharSequence>) {
|
||||
@@ -112,7 +111,7 @@ class AccessibilityNotificationObserver(private val mContext: Context) : Notific
|
||||
|
||||
private val EVENT_TYPES = setOf(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)
|
||||
|
||||
private val TAG = "NotificationObserver"
|
||||
private const val TAG = "NotificationObserver"
|
||||
private val EMPTY = arrayOfNulls<String>(0)
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import android.view.KeyEvent
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import com.stardust.event.EventDispatcher
|
||||
import java.util.*
|
||||
import java.util.TreeMap
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -14,8 +14,6 @@ import java.util.concurrent.locks.ReentrantLock
|
||||
/**
|
||||
* Created by Stardust on 2017/5/2.
|
||||
*/
|
||||
|
||||
|
||||
open class AccessibilityService : android.accessibilityservice.AccessibilityService() {
|
||||
|
||||
interface GestureListener {
|
||||
@@ -73,6 +71,8 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
||||
return keyInterrupterObserver.onInterceptKeyEvent(event)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onGesture(gestureId: Int): Boolean {
|
||||
eventExecutor.execute {
|
||||
gestureEventDispatcher.dispatchEvent {
|
||||
@@ -100,7 +100,7 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
||||
|
||||
|
||||
override fun onServiceConnected() {
|
||||
Log.v(TAG, "onServiceConnected: " + serviceInfo.toString())
|
||||
Log.v(TAG, "onServiceConnected: $serviceInfo")
|
||||
instance = this
|
||||
super.onServiceConnected()
|
||||
LOCK.lock()
|
||||
@@ -116,7 +116,7 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = "AccessibilityService"
|
||||
private const val TAG = "AccessibilityService"
|
||||
|
||||
private val mDelegates = TreeMap<Int, AccessibilityDelegate>()
|
||||
private val LOCK = ReentrantLock()
|
||||
@@ -144,18 +144,18 @@ open class AccessibilityService : android.accessibilityservice.AccessibilityServ
|
||||
return false
|
||||
}
|
||||
|
||||
fun waitForEnabled(timeOut: Long): Boolean {
|
||||
fun waitForEnabled(timeout: Long): Boolean {
|
||||
if (instance != null)
|
||||
return true
|
||||
LOCK.lock()
|
||||
try {
|
||||
if (instance != null)
|
||||
return true
|
||||
if (timeOut == -1L) {
|
||||
if (timeout == -1L) {
|
||||
ENABLED.await()
|
||||
return true
|
||||
}
|
||||
return ENABLED.await(timeOut, TimeUnit.MILLISECONDS)
|
||||
return ENABLED.await(timeout, TimeUnit.MILLISECONDS)
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.util.concurrent.CopyOnWriteArrayList
|
||||
/**
|
||||
* Created by Stardust on 2018/2/27.
|
||||
*/
|
||||
|
||||
interface KeyInterceptor {
|
||||
|
||||
fun onInterceptKeyEvent(event: KeyEvent): Boolean
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.stardust.view.accessibility
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/7/13.
|
||||
*/
|
||||
|
||||
class LayoutInspectService : AccessibilityService() {
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
package com.stardust.view.accessibility
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import android.util.Log
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/10.
|
||||
*/
|
||||
|
||||
class LayoutInspector(private val mContext: Context) {
|
||||
@Volatile
|
||||
var capture: NodeInfo? = null
|
||||
@@ -65,7 +60,6 @@ class LayoutInspector(private val mContext: Context) {
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
private fun refreshChildList(root: AccessibilityNodeInfo?) {
|
||||
if (root == null)
|
||||
return
|
||||
|
||||
@@ -1,21 +1,10 @@
|
||||
package com.stardust.view.accessibility
|
||||
|
||||
import android.accessibilityservice.AccessibilityService
|
||||
import android.content.Context
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.util.Log
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
|
||||
import com.stardust.notification.Notification
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/8/1.
|
||||
*/
|
||||
|
||||
interface NotificationListener {
|
||||
|
||||
|
||||
|
||||
@@ -2,14 +2,11 @@ package com.stardust.view.accessibility
|
||||
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/7/18.
|
||||
*/
|
||||
|
||||
interface OnKeyListener {
|
||||
|
||||
fun onKeyEvent(keyCode: Int, event: KeyEvent)
|
||||
@@ -39,7 +36,7 @@ interface OnKeyListener {
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = "OnKeyListenerObserver"
|
||||
private const val TAG = "OnKeyListenerObserver"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
package com.stardust.automator
|
||||
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package com.stardust.automator.simple_action
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
|
||||
import com.stardust.automator.test.TestUiObject
|
||||
import com.stardust.automator.UiObject
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/5.
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user