import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import '../utils/app_logger.dart'; import '../utils/platform_detector.dart'; class TvosSystemNavigationService { static const BasicMessageChannel _channel = BasicMessageChannel( 'flutter/tvos_system_navigation', JSONMessageCodec(), ); static bool? _latestDesiredValue; static bool? _lastAcknowledgedValue; static Future? _inFlightUpdate; static bool _trailingUpdateRequested = false; static Future setMenuPassthroughEnabled(bool enabled) { if (!PlatformDetector.isAppleTV()) return Future.value(); _latestDesiredValue = enabled; final activeUpdate = _inFlightUpdate; if (activeUpdate != null) { _trailingUpdateRequested = true; return activeUpdate; } if (_lastAcknowledgedValue == enabled) return Future.value(); final update = _runUpdateLoopAndClear(); _inFlightUpdate = update; return update; } static Future _runUpdateLoopAndClear() async { try { await _runUpdateLoop(); } finally { _inFlightUpdate = null; } } static Future _runUpdateLoop() async { do { _trailingUpdateRequested = false; final desired = _latestDesiredValue; if (desired == null || desired == _lastAcknowledgedValue) continue; try { final reply = await _channel.send({'menuPassthroughEnabled': desired}); if (reply == true) { _lastAcknowledgedValue = desired; } } on PlatformException catch (error, stackTrace) { appLogger.w('Failed to update tvOS Menu passthrough state', error: error, stackTrace: stackTrace); } } while (_trailingUpdateRequested); } @visibleForTesting static void resetForTesting() { assert(_inFlightUpdate == null, 'Await the active tvOS navigation update before resetting'); _latestDesiredValue = null; _lastAcknowledgedValue = null; _trailingUpdateRequested = false; _inFlightUpdate = null; } }