From f4c83bedc01c814beee5aa7fa9ae6b2522d491b7 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Thu, 21 May 2026 00:42:19 +0200 Subject: [PATCH] chore(tv): guard text input diagnostics --- .../kotlin/com/edde746/plezy/MainActivity.kt | 30 ++++++++++++------- lib/focus/focusable_text_field.dart | 5 ++-- lib/focus/focusable_wrapper.dart | 6 ++-- lib/services/gamepad_service.dart | 4 +-- lib/utils/key_event_simulator.dart | 6 ++-- lib/utils/text_input_diagnostics.dart | 11 +++++++ 6 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 lib/utils/text_input_diagnostics.dart diff --git a/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt b/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt index 075bc130..e1f8366d 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt @@ -41,6 +41,7 @@ class MainActivity : FlutterActivity() { companion object { private const val TAG = "MainActivity" + private const val TEXT_INPUT_DIAGNOSTICS_ENABLED = false var usingSkia = false } @@ -54,6 +55,12 @@ class MainActivity : FlutterActivity() { private var watchNextPlugin: WatchNextPlugin? = null private var nativeTextInputFocused = false + private inline fun logTextInputDiag(message: () -> String) { + if (TEXT_INPUT_DIAGNOSTICS_ENABLED) { + Log.i(TAG, "TextInputDiag ${message()}") + } + } + // Auto PiP state private var autoPipReady = false private var autoPipWidth: Int = 16 @@ -118,7 +125,7 @@ class MainActivity : FlutterActivity() { private fun shouldForwardDpadBeforeIme(): Boolean { val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val forward = !nativeTextInputFocused && !isImeVisible() && !imm.isAcceptingText - Log.i(TAG, "TextInputDiag shouldForwardDpadBeforeIme=$forward ${describeImeState()}") + logTextInputDiag { "shouldForwardDpadBeforeIme=$forward ${describeImeState()}" } return forward } @@ -184,7 +191,7 @@ class MainActivity : FlutterActivity() { val wrapper = object : FrameLayout(this) { override fun dispatchKeyEventPreIme(event: KeyEvent): Boolean { if (isDpadKeyCode(event.keyCode)) { - Log.i(TAG, "TextInputDiag preIme received ${describeKeyEvent(event)} ${describeImeState()}") + logTextInputDiag { "preIme received ${describeKeyEvent(event)} ${describeImeState()}" } } when (event.keyCode) { KeyEvent.KEYCODE_DPAD_UP, @@ -193,16 +200,16 @@ class MainActivity : FlutterActivity() { KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_CENTER -> { if (shouldForwardDpadBeforeIme()) { - Log.i(TAG, "TextInputDiag preIme forwarding-to-Flutter-and-consuming ${describeKeyEvent(event)}") + logTextInputDiag { "preIme forwarding-to-Flutter-and-consuming ${describeKeyEvent(event)}" } super.dispatchKeyEvent(event) return true } - Log.i(TAG, "TextInputDiag preIme letting-IME-handle ${describeKeyEvent(event)}") + logTextInputDiag { "preIme letting-IME-handle ${describeKeyEvent(event)}" } } } val handled = super.dispatchKeyEventPreIme(event) if (isDpadKeyCode(event.keyCode)) { - Log.i(TAG, "TextInputDiag preIme superResult=$handled ${describeKeyEvent(event)} ${describeImeState()}") + logTextInputDiag { "preIme superResult=$handled ${describeKeyEvent(event)} ${describeImeState()}" } } return handled } @@ -232,11 +239,13 @@ class MainActivity : FlutterActivity() { override fun dispatchKeyEvent(event: KeyEvent): Boolean { if (isDpadKeyCode(event.keyCode)) { - Log.i(TAG, "TextInputDiag activity.dispatchKeyEvent before ${describeKeyEvent(event)} ${describeImeState()}") + logTextInputDiag { "activity.dispatchKeyEvent before ${describeKeyEvent(event)} ${describeImeState()}" } } val handled = super.dispatchKeyEvent(event) if (isDpadKeyCode(event.keyCode)) { - Log.i(TAG, "TextInputDiag activity.dispatchKeyEvent after handled=$handled ${describeKeyEvent(event)} ${describeImeState()}") + logTextInputDiag { + "activity.dispatchKeyEvent after handled=$handled ${describeKeyEvent(event)} ${describeImeState()}" + } } return handled } @@ -339,10 +348,9 @@ class MainActivity : FlutterActivity() { "setNativeTextInputFocused" -> { val oldValue = nativeTextInputFocused nativeTextInputFocused = call.arguments as? Boolean ?: false - Log.i( - TAG, - "TextInputDiag methodChannel setNativeTextInputFocused old=$oldValue new=$nativeTextInputFocused ${describeImeState()}" - ) + logTextInputDiag { + "methodChannel setNativeTextInputFocused old=$oldValue new=$nativeTextInputFocused ${describeImeState()}" + } result.success(null) } else -> result.notImplemented() diff --git a/lib/focus/focusable_text_field.dart b/lib/focus/focusable_text_field.dart index 48e9fc6e..a3f60bdd 100644 --- a/lib/focus/focusable_text_field.dart +++ b/lib/focus/focusable_text_field.dart @@ -4,8 +4,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../services/gamepad_service.dart'; -import '../utils/app_logger.dart'; import '../utils/platform_detector.dart'; +import '../utils/text_input_diagnostics.dart'; import '../widgets/tv_virtual_keyboard.dart'; import 'dpad_navigator.dart'; @@ -19,8 +19,7 @@ String _describeTextInputKey(KeyEvent event) { } void _logTvTextInput(String message) { - if (!PlatformDetector.isTV()) return; - appLogger.i('TextInputDiag FlutterTextField: $message'); + TextInputDiagnostics.log('FlutterTextField', message); } class _NativeTvTextInputFocusBridge { diff --git a/lib/focus/focusable_wrapper.dart b/lib/focus/focusable_wrapper.dart index 7a6180dd..47f16aef 100644 --- a/lib/focus/focusable_wrapper.dart +++ b/lib/focus/focusable_wrapper.dart @@ -4,8 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../widgets/clickable_cursor.dart'; -import '../utils/app_logger.dart'; -import '../utils/platform_detector.dart'; +import '../utils/text_input_diagnostics.dart'; import 'dpad_navigator.dart'; import 'focus_theme.dart'; import 'input_mode_tracker.dart'; @@ -17,8 +16,7 @@ String _describeFocusableKey(KeyEvent event) { } void _logFocusableWrapper(String message) { - if (!PlatformDetector.isTV()) return; - appLogger.i('TextInputDiag FocusableWrapper: $message'); + TextInputDiagnostics.log('FocusableWrapper', message); } /// A wrapper widget that makes its child focusable with D-pad navigation support. diff --git a/lib/services/gamepad_service.dart b/lib/services/gamepad_service.dart index 9d67c099..c34f17a5 100644 --- a/lib/services/gamepad_service.dart +++ b/lib/services/gamepad_service.dart @@ -12,6 +12,7 @@ import 'package:window_manager/window_manager.dart'; import '../utils/app_logger.dart'; import '../utils/key_event_simulator.dart' as key_sim; import '../utils/platform_detector.dart'; +import '../utils/text_input_diagnostics.dart'; String _describeGamepadKeyEvent(KeyEvent event) { return 'type=${event.runtimeType} logical=${event.logicalKey.keyLabel}/${event.logicalKey.keyId} ' @@ -27,8 +28,7 @@ String _describeGamepadAxis(GamepadAxisEvent event) { } void _logGamepadDiag(String message) { - if (!PlatformDetector.isTV()) return; - appLogger.i('TextInputDiag GamepadService: $message'); + TextInputDiagnostics.log('GamepadService', message); } /// Suppresses synthetic gamepad key events when the OS has just delivered an diff --git a/lib/utils/key_event_simulator.dart b/lib/utils/key_event_simulator.dart index 72b1d162..3a3e2a2d 100644 --- a/lib/utils/key_event_simulator.dart +++ b/lib/utils/key_event_simulator.dart @@ -4,8 +4,7 @@ import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; -import 'app_logger.dart'; -import 'platform_detector.dart'; +import 'text_input_diagnostics.dart'; String _describeSimulatedKey(KeyEvent event) { return 'type=${event.runtimeType} logical=${event.logicalKey.keyLabel}/${event.logicalKey.keyId} ' @@ -13,8 +12,7 @@ String _describeSimulatedKey(KeyEvent event) { } void _logKeySimulator(String message) { - if (!PlatformDetector.isTV()) return; - appLogger.i('TextInputDiag KeySimulator: $message'); + TextInputDiagnostics.log('KeySimulator', message); } /// Shared utility for simulating key press events through the focus tree. diff --git a/lib/utils/text_input_diagnostics.dart b/lib/utils/text_input_diagnostics.dart new file mode 100644 index 00000000..a2cb4e5f --- /dev/null +++ b/lib/utils/text_input_diagnostics.dart @@ -0,0 +1,11 @@ +import 'app_logger.dart'; +import 'platform_detector.dart'; + +class TextInputDiagnostics { + static bool enabled = false; + + static void log(String source, String message) { + if (!enabled || !PlatformDetector.isTV()) return; + appLogger.i('TextInputDiag $source: $message'); + } +}