| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- package com.example.modifier.service
- import android.accessibilityservice.AccessibilityService
- import android.accessibilityservice.GestureDescription
- import android.content.Intent
- import android.graphics.Path
- import android.graphics.Rect
- import android.provider.Settings
- import android.util.Log
- import android.view.accessibility.AccessibilityNodeInfo
- import com.draco.ladb.utils.ADB
- import com.example.modifier.TraverseResult
- import com.example.modifier.constants.CMD_BACK
- import com.example.modifier.constants.CMD_RCS_SETTINGS_ACTIVITY
- import com.example.modifier.utils.currentActivity
- import com.example.modifier.utils.findAllScrollable
- import com.example.modifier.utils.findFirstByDesc
- import com.example.modifier.utils.findFirstByIdAndText
- import com.example.modifier.utils.findFirstScrollable
- import com.example.modifier.utils.shellRun
- import kotlinx.coroutines.delay
- import kotlinx.coroutines.withTimeoutOrNull
- class ScreenController(val context: AccessibilityService, private val inspector: ScreenInspector) {
- companion object {
- private const val TAG = "ScreenController"
- }
- suspend fun toggleRcsSwitch(state: Boolean, retry: Int = 3): Boolean {
- val res = TraverseResult()
- shellRun(CMD_RCS_SETTINGS_ACTIVITY, "sleep 2")
- val success = run repeatBlock@{
- repeat(retry) {
- res.rcsSwitch = null
- inspector.traverseNode(res)
- if (res.rcsSwitch == null) {
- shellRun(CMD_BACK, "sleep 0.5", CMD_RCS_SETTINGS_ACTIVITY, "sleep 1")
- } else {
- if (res.rcsSwitch!!.isChecked == state) {
- return@repeatBlock true
- }
- val rect = Rect()
- res.rcsSwitch!!.getBoundsInScreen(rect)
- if (state) {
- shellRun(
- "input tap ${rect.centerX()} ${rect.centerY()}", "sleep 1",
- )
- val btn =
- context.rootInActiveWindow.findAccessibilityNodeInfosByViewId("android:id/button1")
- .firstOrNull()
- if (btn != null) {
- btn.performAction(AccessibilityNodeInfo.ACTION_CLICK)
- delay(1000)
- }
- while (currentActivity()?.contains("RcsSettingsActivity") == true ||
- currentActivity()?.contains("TurnOffRcsActivity") == true
- ) {
- shellRun(CMD_BACK)
- delay(500)
- }
- shellRun(CMD_RCS_SETTINGS_ACTIVITY, "sleep 1")
- } else {
- shellRun(
- "input tap ${rect.centerX()} ${rect.centerY()}", "sleep 1",
- )
- if (currentActivity()?.contains("TurnOffRcsActivity") == true) {
- inspector.traverseNode(res)
- if (res.closeBtn != null) {
- val rect1 = Rect()
- res.closeBtn!!.getBoundsInScreen(rect1)
- shellRun(
- "input tap ${rect1.centerX()} ${rect1.centerY()}", "sleep 1",
- )
- }
- } else {
- context.rootInActiveWindow.findAccessibilityNodeInfosByViewId("android:id/button1")
- .firstOrNull()?.performAction(AccessibilityNodeInfo.ACTION_CLICK)
- }
- delay(1000)
- while (currentActivity()?.contains("RcsSettingsActivity") == true ||
- currentActivity()?.contains("TurnOffRcsActivity") == true
- ) {
- shellRun(CMD_BACK)
- delay(500)
- }
- shellRun(CMD_RCS_SETTINGS_ACTIVITY, "sleep 1")
- }
- res.rcsSwitch = null
- inspector.traverseNode(res)
- if (res.rcsSwitch?.isChecked == state) {
- return@repeatBlock true
- }
- }
- }
- false
- }
- while (currentActivity()?.contains("RcsSettingsActivity") == true) {
- shellRun(CMD_BACK)
- delay(500)
- }
- return success
- }
- suspend fun adbPair(): Pair<String, String>? {
- val i = Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- context.startActivity(i)
- delay(500)
- withTimeoutOrNull(10000) {
- while (true) {
- val node = context.rootInActiveWindow.findFirstByIdAndText(
- "android:id/title",
- "Wireless debugging"
- )
- if (node != null) {
- Log.i(TAG, "found wireless debugging")
- delay(500)
- tapNode(node)
- delay(1000)
- return@withTimeoutOrNull context.rootInActiveWindow.findFirstByIdAndText(
- "android:id/title",
- "Pair device with pairing code"
- )?.let {
- Log.i(TAG, "found pair device with pairing code")
- it.parent.parent.performAction(AccessibilityNodeInfo.ACTION_CLICK)
- delay(1000)
- val code = context.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
- "com.android.settings:id/pairing_code"
- ).firstOrNull()?.text?.toString()
- val ip = context.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
- "com.android.settings:id/ip_addr"
- ).firstOrNull()?.text?.toString()
- Log.i(TAG, "pairing code: $code, ip: $ip")
- if (code != null && ip != null) {
- return@let Pair(code, ip)
- } else {
- }
- }
- return@withTimeoutOrNull
- }
- context.rootInActiveWindow.findAllScrollable().forEach {
- Log.i(TAG, "scrolling ${it.viewIdResourceName}")
- it.performAction(AccessibilityNodeInfo.ACTION_FOCUS)
- it.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)
- }
- delay(500)
- }
- null
- }
- }
- fun tapNode(node: AccessibilityNodeInfo) {
- val rect = Rect()
- node.getBoundsInScreen(rect)
- val path = Path()
- path.moveTo(rect.centerX().toFloat(), rect.centerY().toFloat())
- context.dispatchGesture(
- GestureDescription.Builder().addStroke(
- GestureDescription.StrokeDescription(path, 0, 100)
- ).build(), null, null
- )
- }
- }
|