Files
Qlyra/lib/core/calls/call_bridge.dart
T

148 lines
3.6 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:io' show Platform;
import 'package:flutter/services.dart';
import '../utils/logger.dart';
import 'call_controller.dart';
class CallBridge {
CallBridge._();
static final CallBridge instance = CallBridge._();
static const _method = MethodChannel('ru.komet.app/calls');
static const _events = EventChannel('ru.komet.app/calls_events');
bool _started = false;
bool get _android {
try {
return Platform.isAndroid;
} catch (_) {
return false;
}
}
void init() {
if (_started || !_android) return;
_started = true;
_events.receiveBroadcastStream().listen(
_handle,
onError: (e) => logger.w('CallBridge.init: events stream error: $e'),
);
}
Future<void> checkInitialCall() async {
if (!_android) return;
try {
_handle(await _method.invokeMethod<dynamic>('consumeInitialCall'));
} catch (e) {
logger.w('CallBridge.checkInitialCall: $e');
}
}
void _handle(Object? event) {
if (event is! Map) return;
final action = event['action']?.toString();
if (action == 'hangup') {
unawaited(CallController.instance.endActive());
return;
}
if (action == 'ended') {
CallController.instance.dismissIncoming();
return;
}
final dataStr = event['data'];
if (dataStr is! String) return;
Object? decoded;
try {
decoded = jsonDecode(dataStr);
} catch (e) {
logger.w('CallBridge._handle: action=$action jsonDecode failed: $e');
return;
}
if (decoded is! Map) return;
CallController.instance.injectFromNative(
decoded,
autoAccept: action == 'answer',
);
}
Future<void> notifyAccepted({String? caller}) async {
if (!_android) return;
try {
await _method.invokeMethod<void>('notifyAccepted', {'caller': caller});
} catch (e) {
logger.w('CallBridge.notifyAccepted: caller=$caller $e');
}
}
Future<void> ensureOngoing({String? caller}) async {
if (!_android) return;
try {
await _method.invokeMethod<void>('ensureOngoing', {'caller': caller});
} catch (e) {
logger.w('CallBridge.ensureOngoing: $e');
}
}
Future<void> setScreenShare(bool enabled, {String? caller}) async {
if (!_android) return;
try {
await _method.invokeMethod<void>('setScreenShare', {
'enabled': enabled,
'caller': caller,
});
} catch (e) {
logger.w('CallBridge.setScreenShare: enabled=$enabled $e');
}
}
Future<void> dropOngoing() async {
if (!_android) return;
try {
await _method.invokeMethod<void>('dropOngoing');
} catch (e) {
logger.w('CallBridge.dropOngoing: $e');
}
}
Future<void> notifyEnded() async {
if (!_android) return;
try {
await _method.invokeMethod<void>('notifyEnded');
} catch (e) {
logger.w('CallBridge.notifyEnded: $e');
}
}
Future<void> cancelIncoming() async {
if (!_android) return;
try {
await _method.invokeMethod<void>('cancelIncoming');
} catch (e) {
logger.w('CallBridge.cancelIncoming: $e');
}
}
Future<bool> canUseFullScreenIntent() async {
if (!_android) return true;
try {
return await _method.invokeMethod<bool>('canUseFullScreenIntent') ?? true;
} catch (e) {
logger.w('CallBridge.canUseFullScreenIntent: $e');
return true;
}
}
Future<void> openFullScreenIntentSettings() async {
if (!_android) return;
try {
await _method.invokeMethod<void>('openFullScreenIntentSettings');
} catch (e) {
logger.w('CallBridge.openFullScreenIntentSettings: $e');
}
}
}