6.1.0 - 变更包名 新增投影媒体权限开关/tasks模块 扩展内置模块方法 重构内置模块及构建脚本

This commit is contained in:
SuperMonster003 committed 2022-05-26 19:18:16 +08:00
1 parent e0374a835e
commit f68ad1c993
770 files changed
+15821 -14759

No files matched your search

+4 -36
View File
@@ -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)
}
}
@@ -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())
}
}
@@ -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())
}
}
+2 -8
View File
@@ -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 {
@@ -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 {
/**
@@ -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 {
/**
@@ -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.
*/