Files
chanora/docs/references/flutter-upstream-bugs.md
T
Edison Jwa 13c7648a65 docs: link orphaned superpowers docs and track Flutter bugs (TODO-033,087)
Add docs/superpowers/README.md as index for plans and specs.
Add docs/references/flutter-upstream-bugs.md tracking 4 known
Flutter framework workarounds.
2026-06-11 09:40:08 +09:00

5.0 KiB

Flutter Framework Upstream Bugs and Workarounds

Tracking document for Flutter framework issues that require Chanora-specific workarounds.


1. Flutter AdaptiveScaffold Discontinued

Flutter issue: flutter/flutter#162965

Impact: Chanora's adaptive 3-panel layout cannot use the built-in AdaptiveScaffold widget because it has been discontinued by the Flutter team. A custom breakpoint-based layout system was required.

Workaround: Chanora implements its own centralized breakpoint system with three layout classes (compact, medium, expanded) using a custom LayoutBuilder approach. The breakpoint constants and layout policy are documented in docs/ui-ux/adaptive-layout-platform-guide.md.

Relevant code:

  • Design spec: docs/superpowers/specs/2026-06-05-adaptive-3-panel-layout-design.md
  • Breakpoint thresholds follow Material 3 canonical breakpoints (600dp compact, 840dp medium, ≥1024dp expanded).

Status: Workaround in place. No Flutter fix expected; this is a permanent design divergence.


2. Flutter Lacks Native Audio Session Management

Flutter issue: No unified Flutter issue; this is a fundamental platform abstraction gap. Flutter's audioplayers and similar packages do not expose per-platform audio session lifecycle (iOS AVAudioSession, Android AudioFocus, macOS Core Audio).

Impact: Chanora must manage audio focus, interruption handling, and route changes natively on each platform and bridge them to Dart via MethodChannel.

Workaround: Chanora implements platform-specific audio lifecycle management:

Platform Native Implementation Dart Bridge
iOS AppDelegate.swift — AVAudioSession category/route/interruption observers chanora/ios_audio_lifecycle MethodChannel
Android AndroidAudioFocusController.kt — AudioFocus request/abandon with OnAudioFocusChangeListener chanora/android_audio_lifecycle MethodChannel
macOS MacOSAudioLifecycle — Core Audio HAL default-device and stream-format change observers chanora/macos_audio_lifecycle MethodChannel

Relevant code:

  • Dart dispatcher: apps/chanora_flutter/lib/services/audio_lifecycle_service.dart
  • iOS native: apps/chanora_flutter/ios/Runner/AppDelegate.swift
  • Android native: apps/chanora_flutter/android/app/src/main/kotlin/app/chanora/chanora_flutter/AndroidAudioFocusController.kt
  • macOS native: apps/chanora_flutter/macos/

Status: Ongoing. Each platform's MethodChannel handler catches and swallows errors from the Rust side to prevent exception propagation back through the platform framework (a Flutter restriction on MethodChannel handlers).


3. macOS Default-Device Change Not Exposed to Flutter

Flutter issue: No Flutter issue filed. Flutter's desktop audio support does not expose Core Audio HAL default-input/output device change notifications.

Impact: When the user changes the default audio device on macOS (e.g., plugging in headphones), the Chanora audio engine does not automatically rebind to the new device.

Workaround: The macOS MethodChannel (chanora/macos_audio_lifecycle) receives handleDefaultDeviceChange and handleConfigurationChange events from native Swift code, but the corresponding Rust-side FRB bridge function (macosDefaultDeviceChanged) is not yet exposed via flutter_rust_bridge. Events are captured and logged for observability only.

Relevant code:

  • apps/chanora_flutter/lib/services/audio_lifecycle_service.dart:150-157 — macOS handler with TODO markers
  • apps/chanora_flutter/lib/services/audio_lifecycle_service.dart:151// TODO: call rust.macosDefaultDeviceChanged() once exposed

Status: Partial workaround. Requires flutter_rust_bridge update to expose the Rust function.


4. iOS Audio Session Activation Ordering

Flutter issue: No Flutter issue filed. Flutter does not provide a mechanism to coordinate audio session activation with network connection establishment.

Impact: On iOS, the AVAudioSession must be activated before the voice channel join RPC, and deactivated on failure. Without careful ordering, audio may be left in an active state after a failed join, or the session may not be active when the audio engine starts.

Workaround: Chanora implements an explicit ordering function joinVoiceChannelWithIosAudioSession that activates the iOS audio session, attempts the voice join, and deactivates on failure. A VoiceJoinSuccessPredicate allows callers to treat certain errors (e.g., "already in channel") as successful joins, keeping the audio session active.

Relevant code:

  • apps/chanora_flutter/lib/services/voice_join_ordering.dart — Full implementation
  • The activateIosAudioSession/deactivateIosAudioSession callbacks are provided by the iOS native side via AppDelegate.swift.

Status: Workaround in place. This is an inherent platform design requirement rather than a Flutter bug.