From da1a308c5d8e769545c0f58382ddcf5a239d5390 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Tue, 5 May 2026 13:33:41 +0200 Subject: [PATCH] fix(sae): keyboard structural markers to be regex based for safety --- GramAddict/core/situational_awareness.py | 45 ++++++++++++------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/GramAddict/core/situational_awareness.py b/GramAddict/core/situational_awareness.py index 5371c1c..3627bad 100644 --- a/GramAddict/core/situational_awareness.py +++ b/GramAddict/core/situational_awareness.py @@ -339,29 +339,30 @@ class SituationalAwarenessEngine: return SituationType.OBSTACLE_SYSTEM # ── Keyboard Detection (Fast Path) ── - keyboard_pkgs = { - "com.google.android.inputmethod.latin", - "com.samsung.android.honeyboard", - "com.sec.android.inputmethod", - "com.touchtype.swiftkey", - "com.apple.android.inputmethod", - } - if any(pkg in keyboard_pkgs for pkg in packages): - # Differentiate between actual EditText focus and layout-induced phantom keyboard signals - is_actual_keyboard = False - if 'focused="true"' in xml_dump and "EditText" in xml_dump: - if re.search(r'class="[^"]*EditText"[^>]*focused="true"', xml_dump) or re.search( - r'focused="true"[^>]*class="[^"]*EditText"', xml_dump - ): - is_actual_keyboard = True + # Instead of relying on brittle package names (which may be missing or custom), + # an open keyboard is definitively proven if an EditText is focused, + # or if unmistakable keyboard structural markers exist. + is_actual_keyboard = False + if 'focused="true"' in xml_dump and "EditText" in xml_dump: + if re.search(r'class="[^"]*EditText"[^>]*focused="true"', xml_dump) or re.search( + r'focused="true"[^>]*class="[^"]*EditText"', xml_dump + ): + is_actual_keyboard = True + + # Structural fallback: certain strings are exclusive to keyboards + # We match these securely against content-desc or resource-id to avoid false positives from user post text. + keyboard_markers = [ + r'content-desc="[^"]*(?:Symboltastatur|Switch input method|Leerzeichen|Spracheingabe verwenden)[^"]*"', + r'resource-id="[^"]*input_method_nav_ime_switcher[^"]*"' + ] + if not is_actual_keyboard and any(re.search(marker, xml_dump, re.IGNORECASE) for marker in keyboard_markers): + is_actual_keyboard = True - if is_actual_keyboard: - logger.info( - "📱 [SAE Perceive] On-screen Keyboard explicitly detected (EditText focused). Treating as obstacle." - ) - return SituationType.OBSTACLE_KEYBOARD - else: - logger.debug("📱 [SAE Perceive] Phantom keyboard signal detected (No focused EditText). Ignoring.") + if is_actual_keyboard: + logger.info( + "📱 [SAE Perceive] On-screen Keyboard explicitly detected. Treating as obstacle." + ) + return SituationType.OBSTACLE_KEYBOARD # ── Foreign Environment Detection (package-based) ── # If the main app package is completely absent from the UI hierarchy,