mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
Merge branch 'android-ime-targets' into trial-merge
This commit is contained in:
commit
9583aa365f
2 files changed
+63
No files matched your search
@@ -779,6 +779,22 @@ internal fun typeChunks(
|
||||
return typed
|
||||
}
|
||||
|
||||
// dismissSoftKeyboard closes an open IME, and issues nothing when none is open.
|
||||
//
|
||||
// The keyboard is its own window over the bottom of the app, and the hierarchy
|
||||
// carries only what is visible to the user, so every app node under it is
|
||||
// absent from the tree the picker enumerates targets from. Typing raises it, so
|
||||
// an IME left open hides a form's submit control for as long as the fuzzer
|
||||
// keeps typing into that form, which is a state it cannot type its way out of.
|
||||
//
|
||||
// The mInputShown guard is load-bearing rather than an optimisation: BACK is
|
||||
// what closes an open IME, and BACK with no IME open navigates out of the
|
||||
// screen, so an unguarded dismissal would make every InputText a back press.
|
||||
internal fun dismissSoftKeyboard(shell: (String) -> String) {
|
||||
if (!shell("dumpsys input_method").contains("mInputShown=true")) return
|
||||
shell("input keyevent 4")
|
||||
}
|
||||
|
||||
// resumedActivityPackage matches a "package/activity" component, mirroring the
|
||||
// Go scope guard's regex so both read the same dumpsys wording.
|
||||
private val resumedActivityPackage =
|
||||
@@ -885,6 +901,11 @@ class MaestroDriverBackend(private val serial: String?) : DriverBackend {
|
||||
} else {
|
||||
driver.inputText(text)
|
||||
}
|
||||
// A probe that fails reads as "no IME open", which is the safe way to be
|
||||
// wrong: it skips the dismissal rather than sending a stray BACK.
|
||||
dismissSoftKeyboard {
|
||||
runCatching { dadb.shell(it).allOutput }.getOrDefault("")
|
||||
}
|
||||
}
|
||||
|
||||
// typeShellSafe types shell-safe ASCII through adb `input text` in chunks,
|
||||
|
||||
@@ -212,4 +212,46 @@ class InputTextTest {
|
||||
assertEquals(maestro.KeyCode.ENTER, maestroKeyFor("enter"))
|
||||
assertFailsWith<IllegalArgumentException> { maestroKeyFor("zorp") }
|
||||
}
|
||||
|
||||
// An IME left open hides every app node beneath it from the hierarchy, so a
|
||||
// form whose submit button sits under the keyboard becomes unreachable for
|
||||
// as long as the fuzzer keeps typing into it. Typing must close the
|
||||
// keyboard it raised.
|
||||
@Test fun dismissSoftKeyboardClosesAnOpenIme() {
|
||||
val commands = mutableListOf<String>()
|
||||
dismissSoftKeyboard {
|
||||
commands.add(it)
|
||||
IME_OPEN_DUMPSYS
|
||||
}
|
||||
assertEquals(
|
||||
listOf("dumpsys input_method", "input keyevent 4"),
|
||||
commands,
|
||||
)
|
||||
}
|
||||
|
||||
// The guard is the dangerous half: BACK is only swallowed by an open IME,
|
||||
// so dismissing unconditionally would turn every InputText into a back
|
||||
// press and walk the fuzzer straight out of the screen it was filling in.
|
||||
@Test fun dismissSoftKeyboardSendsNoBackWhenNoImeIsOpen() {
|
||||
val commands = mutableListOf<String>()
|
||||
dismissSoftKeyboard {
|
||||
commands.add(it)
|
||||
IME_CLOSED_DUMPSYS
|
||||
}
|
||||
assertEquals(listOf("dumpsys input_method"), commands)
|
||||
}
|
||||
}
|
||||
|
||||
private val IME_OPEN_DUMPSYS =
|
||||
"""
|
||||
mCurMethodId=com.google.android.inputmethod.latin/.LatinIME
|
||||
mInputShown=true
|
||||
mSystemReady=true mInteractive=true
|
||||
""".trimIndent()
|
||||
|
||||
private val IME_CLOSED_DUMPSYS =
|
||||
"""
|
||||
mCurMethodId=com.google.android.inputmethod.latin/.LatinIME
|
||||
mInputShown=false
|
||||
mSystemReady=true mInteractive=true
|
||||
""".trimIndent()
|
||||
Reference in new issue
Block a user