Add docs/superpowers/README.md as index for plans and specs. Add docs/references/flutter-upstream-bugs.md tracking 4 known Flutter framework workarounds.
80 lines
5.0 KiB
Markdown
80 lines
5.0 KiB
Markdown
# 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](https://github.com/flutter/flutter/issues/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](../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.
|