11package io.github.sds100.keymapper.base.expertmode
22
33import android.app.ActivityManager
4+ import android.graphics.Rect
45import android.os.Build
56import android.view.accessibility.AccessibilityEvent
67import android.view.accessibility.AccessibilityNodeInfo
@@ -19,6 +20,7 @@ import io.github.sds100.keymapper.base.utils.ui.ResourceProvider
1920import io.github.sds100.keymapper.common.KeyMapperClassProvider
2021import io.github.sds100.keymapper.common.notifications.KMNotificationAction
2122import io.github.sds100.keymapper.common.utils.Constants
23+ import io.github.sds100.keymapper.common.utils.InputEventAction
2224import io.github.sds100.keymapper.common.utils.onFailure
2325import io.github.sds100.keymapper.common.utils.onSuccess
2426import io.github.sds100.keymapper.data.Keys
@@ -74,6 +76,11 @@ class SystemBridgeSetupAssistantController @AssistedInject constructor(
7476 Regex (
7577 " ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\ .){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" ,
7678 )
79+
80+ private val PAIRING_CODE_BUTTON_TEXT_FILTER = arrayOf(
81+ " pairing code" , // English
82+ " kode penyambungan" , // Indonesian
83+ )
7784 }
7885
7986 private enum class InteractionStep {
@@ -240,24 +247,21 @@ class SystemBridgeSetupAssistantController @AssistedInject constructor(
240247 }
241248
242249 private fun clickPairWithCodeButton (rootNode : AccessibilityNodeInfo ) {
243- rootNode
244- .findNodeRecursively { it.className == " androidx.recyclerview.widget.RecyclerView" }
245- ?.takeIf { recyclerView ->
246- // There are many settings screens with RecyclerViews so make sure
247- // the correct page is showing before clicking. It is not as simple
248- // as checking the words on the screen due to different languages.
249- val ipAddressPortText: CharSequence? =
250- runCatching {
251- // RecyclerView -> LinearLayout -> RelativeLayout -> TextView
252- recyclerView.getChild(1 ).getChild(0 ).getChild(1 )
253- }.getOrNull()?.text
254-
255- val ipText = ipAddressPortText?.split(" :" )?.firstOrNull()
256- ipText != null && IPV4_REGEX .matches(ipText)
257- }
258- ?.runCatching { getChild(3 ) }
259- ?.getOrNull()
260- ?.performAction(AccessibilityNodeInfo .ACTION_CLICK )
250+ // This works more maintainable/adaptable then traversing the tree
251+ // and trying to find the clickable node. This can change subtly between
252+ // Android devices and ROMs.
253+ val textNode = rootNode.findNodeRecursively { node ->
254+ PAIRING_CODE_BUTTON_TEXT_FILTER .any { text -> node.text?.contains(text) == true }
255+ } ? : return
256+
257+ val bounds = Rect ()
258+ textNode.getBoundsInScreen(bounds)
259+
260+ accessibilityService.tapScreen(
261+ bounds.centerX(),
262+ bounds.centerY(),
263+ InputEventAction .DOWN_UP ,
264+ )
261265 }
262266
263267 private fun showNotification (
0 commit comments