Bernds Anruftest Handy↔PC (2026-10-07): - Teilen am Handy: App "verkleinerte sich", Anruf danach weg. Ursache: Android 14+ verlangt vor MediaProjection einen Vordergrunddienst vom Typ mediaProjection; flutter_webrtc startet keinen, der Manifest-Eintrag verwies auf eine nicht mehr existierende Klasse. Neu: CallService (microphone|mediaProjection) + CallForeground: Zustimmung → Dienst (wartet auf echten startForeground) → Mitschnitt. Emulator-Test (Android 16): mit Fix 1080x2400@30 läuft; Gegenprobe ohne Dienst wirft genau 'Media projections require a foreground service ...'. - Dienst läuft während jedes Anrufs: Mikrofon bleibt im Hintergrund aktiv, Benachrichtigung "Anruf läuft" führt zurück. Mikrofon-Typ nur mit Berechtigung, sonst schmalere Variante statt Dienst-Abbruch. - Handy hörte nichts: SDK schaltet Sprachanrufe auf die Hörmuschel. Jetzt Lautsprecher als Standard (wie Discord) + Umschalter in der Anrufleiste. - LiveKit-Teilen am Handy öffnete den PC-Quellen-Auswähler → System-Dialog. - Im offenen Chat (Handy) Leiste "Anruf läuft · Zurück". - Einstellungen → Sprache & Video: Mikrofontest mit Pegel (PC-Diagnose: das Standardgerät lieferte nur Stille – Voicemeeter/virtuelle Geräte). Co-Authored-By: Claude Opus 5.5 <[email protected]>
73 lines
3.0 KiB
Dart
73 lines
3.0 KiB
Dart
import 'package:flutter/widgets.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||
import 'package:matrix/matrix.dart';
|
||
import 'package:pyramid/features/call_signaling/voip_manager.dart';
|
||
|
||
/// Öffentliche Schnittstelle des Moduls `call_signaling` – natives
|
||
/// Matrix-1:1-VoIP (`m.call.*`-Events, direkte WebRTC-Peer-Connection,
|
||
/// kein SFU). Schnitt nach `docs/M2_MODULE_SCHNITT.md`.
|
||
///
|
||
/// Andere Module (UI, Settings, Shell) konsumieren AUSSCHLIESSLICH diese
|
||
/// Schnittstelle über [callSignalingProvider] – nie `voip_manager.dart`
|
||
/// direkt. Einzige Ausnahme ist der Kompositions-Punkt in
|
||
/// `matrix_client.dart`, der die Implementierung konstruiert.
|
||
///
|
||
/// Bewusste Abweichungen vom Entwurf im Doc (Verhaltensgleichheit vor
|
||
/// Schönheit, heiliger Call-Pfad):
|
||
/// * ChangeNotifier statt Streams – die gesamte UI hängt heute an
|
||
/// `ref.watch(...)` mit notifyListeners; ein Stream-Umbau wäre eine
|
||
/// Verhaltensänderung ohne Not.
|
||
/// * [currentCall] bleibt als matrix-SDK-`CallSession` sichtbar (die UI
|
||
/// braucht state/room/answer/reject), ebenso die WebRTC-Renderer –
|
||
/// das Doc sieht Letzteres ausdrücklich vor.
|
||
abstract class CallSignalingService extends ChangeNotifier {
|
||
/// Der laufende 1:1-Call (null = keiner). UI liest state/room und
|
||
/// beantwortet eingehende Calls über [safeAction] + answer()/reject().
|
||
CallSession? get currentCall;
|
||
|
||
rtc.RTCVideoRenderer get localRenderer;
|
||
rtc.RTCVideoRenderer get remoteRenderer;
|
||
|
||
bool get isMicMuted;
|
||
bool get isCameraMuted;
|
||
bool get isScreensharing;
|
||
bool get isRemoteScreensharing;
|
||
bool get isDeafened;
|
||
|
||
/// Sende-Qualität ('sd' | 'hd' | 'fhd' | '4k').
|
||
String get currentQualityKey;
|
||
|
||
Future<void> startCall(String roomId, {bool video});
|
||
Future<void> hangup();
|
||
Future<void> toggleMic();
|
||
Future<void> toggleCamera();
|
||
Future<void> toggleDeafen();
|
||
|
||
/// Auf Windows öffnet ein [context] den Quellen-Picker fürs Screensharing.
|
||
Future<void> toggleScreenSharing([BuildContext? context]);
|
||
|
||
Future<void> changeQuality(String key);
|
||
|
||
/// Handy: Ton über den Lautsprecher (true) oder die Hörmuschel (false).
|
||
/// Auf dem PC ohne Bedeutung.
|
||
bool get isSpeakerOn => true;
|
||
Future<void> toggleSpeaker() async {}
|
||
|
||
/// Wendet die in den Einstellungen gewählte Ausgabelautstärke auf den
|
||
/// Remote-Stream an. Ohne [value] wird der Pref-Wert gelesen.
|
||
Future<void> applyOutputVolume([double? value]);
|
||
|
||
/// Führt eine Call-Aktion (answer/reject/…) fehlertolerant aus und stößt
|
||
/// danach die interne Zustands-/Renderer-Aktualisierung an.
|
||
Future<void> safeAction(Future<dynamic> Function() action);
|
||
}
|
||
|
||
/// Einziger Zugriffsweg der UI auf das 1:1-VoIP-Modul. Die Instanz wird beim
|
||
/// Client-Aufbau in `matrix_client.dart` erzeugt (existiert also, sobald die
|
||
/// eingeloggte Shell steht).
|
||
final callSignalingProvider =
|
||
ChangeNotifierProvider<CallSignalingService>((ref) {
|
||
return PyramidVoipManager.instance;
|
||
});
|