Merge pull request #2148 from famedly/karthi/grp-call-state-stream-refactor
unify group call stream stuff into matrixRTCEventStream
This commit is contained in:
commit
5a59ba4cf4
|
|
@ -2753,6 +2753,14 @@ class FakeMatrixApi extends BaseClient {
|
|||
(var reqI) => {
|
||||
'event_id': '42',
|
||||
},
|
||||
'/client/v3/rooms/!calls%3Aexample.com/state/com.famedly.call.member/%40test%3AfakeServer.notExisting':
|
||||
(var reqI) => {
|
||||
'event_id': 'call_member_42',
|
||||
},
|
||||
'/client/v3/rooms/!calls%3Aexample.com/state/com.famedly.call.member/%40remoteuser%3Aexample.com':
|
||||
(var reqI) => {
|
||||
'event_id': 'call_member_remote_42',
|
||||
},
|
||||
'/client/v3/directory/list/room/!localpart%3Aexample.com': (var req) =>
|
||||
{},
|
||||
'/client/v3/room_keys/version/5': (var req) => {},
|
||||
|
|
|
|||
|
|
@ -133,7 +133,9 @@ class MeshBackend extends CallBackend {
|
|||
Future<void> _addCall(GroupCallSession groupCall, CallSession call) async {
|
||||
_callSessions.add(call);
|
||||
_initCall(groupCall, call);
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged);
|
||||
groupCall.matrixRTCEventStream.add(CallAddedEvent(call));
|
||||
}
|
||||
|
||||
/// init a peer call from group calls.
|
||||
|
|
@ -183,7 +185,10 @@ class MeshBackend extends CallBackend {
|
|||
_registerListenersBeforeCallAdd(replacementCall);
|
||||
_initCall(groupCall, replacementCall);
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(CallReplacedEvent(existingCall, replacementCall));
|
||||
}
|
||||
|
||||
/// Removes a peer call from group calls.
|
||||
|
|
@ -196,7 +201,9 @@ class MeshBackend extends CallBackend {
|
|||
|
||||
_callSessions.removeWhere((element) => call.callId == element.callId);
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged);
|
||||
groupCall.matrixRTCEventStream.add(CallRemovedEvent(call));
|
||||
}
|
||||
|
||||
Future<void> _disposeCall(
|
||||
|
|
@ -375,7 +382,10 @@ class MeshBackend extends CallBackend {
|
|||
|
||||
if (nextActiveSpeaker != null && _activeSpeaker != nextActiveSpeaker) {
|
||||
_activeSpeaker = nextActiveSpeaker;
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent.add(GroupCallStateChange.activeSpeakerChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallActiveSpeakerChanged(_activeSpeaker!));
|
||||
}
|
||||
_activeSpeakerLoopTimeout?.cancel();
|
||||
_activeSpeakerLoopTimeout = Timer(
|
||||
|
|
@ -401,8 +411,12 @@ class MeshBackend extends CallBackend {
|
|||
) {
|
||||
_screenshareStreams.add(stream);
|
||||
onStreamAdd.add(stream);
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.screenshareStreamsChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallStreamAdded(GroupCallStreamType.screenshare));
|
||||
}
|
||||
|
||||
Future<void> _replaceScreenshareStream(
|
||||
|
|
@ -423,8 +437,12 @@ class MeshBackend extends CallBackend {
|
|||
_screenshareStreams.replaceRange(streamIndex, 1, [replacementStream]);
|
||||
|
||||
await existingStream.dispose();
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.screenshareStreamsChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallStreamReplaced(GroupCallStreamType.screenshare));
|
||||
}
|
||||
|
||||
Future<void> _removeScreenshareStream(
|
||||
|
|
@ -450,8 +468,12 @@ class MeshBackend extends CallBackend {
|
|||
await stopMediaStream(stream.stream);
|
||||
}
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.screenshareStreamsChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallStreamRemoved(GroupCallStreamType.screenshare));
|
||||
}
|
||||
|
||||
Future<void> _onCallStateChanged(CallSession call, CallState state) async {
|
||||
|
|
@ -486,8 +508,12 @@ class MeshBackend extends CallBackend {
|
|||
) async {
|
||||
_userMediaStreams.add(stream);
|
||||
onStreamAdd.add(stream);
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.userMediaStreamsChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallStreamAdded(GroupCallStreamType.userMedia));
|
||||
}
|
||||
|
||||
Future<void> _replaceUserMediaStream(
|
||||
|
|
@ -508,8 +534,12 @@ class MeshBackend extends CallBackend {
|
|||
_userMediaStreams.replaceRange(streamIndex, 1, [replacementStream]);
|
||||
|
||||
await existingStream.dispose();
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.userMediaStreamsChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallStreamReplaced(GroupCallStreamType.userMedia));
|
||||
}
|
||||
|
||||
Future<void> _removeUserMediaStream(
|
||||
|
|
@ -536,12 +566,19 @@ class MeshBackend extends CallBackend {
|
|||
await stopMediaStream(stream.stream);
|
||||
}
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.userMediaStreamsChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallStreamRemoved(GroupCallStreamType.userMedia));
|
||||
|
||||
if (_activeSpeaker == stream.participant && _userMediaStreams.isNotEmpty) {
|
||||
_activeSpeaker = _userMediaStreams[0].participant;
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent.add(GroupCallStateChange.activeSpeakerChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallActiveSpeakerChanged(_activeSpeaker!));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -663,7 +700,9 @@ class MeshBackend extends CallBackend {
|
|||
}
|
||||
}
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent.add(GroupCallStateChange.localMuteStateChanged);
|
||||
groupCall.matrixRTCEventStream.add(GroupCallLocalMutedChanged(muted, kind));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -799,8 +838,12 @@ class MeshBackend extends CallBackend {
|
|||
|
||||
_addScreenshareStream(groupCall, localScreenshareStream!);
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.localScreenshareStateChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallLocalScreenshareStateChanged(true));
|
||||
for (final call in _callSessions) {
|
||||
await call.addLocalStream(
|
||||
await localScreenshareStream!.stream!.clone(),
|
||||
|
|
@ -813,7 +856,10 @@ class MeshBackend extends CallBackend {
|
|||
return;
|
||||
} catch (e, s) {
|
||||
Logs().e('[VOIP] Enabling screensharing error', e, s);
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent.add(GroupCallStateChange.error);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallStateError(e.toString(), s));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -826,8 +872,12 @@ class MeshBackend extends CallBackend {
|
|||
|
||||
await groupCall.sendMemberStateEvent();
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
groupCall.onGroupCallEvent
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.add(GroupCallStateChange.localMuteStateChanged);
|
||||
groupCall.matrixRTCEventStream
|
||||
.add(GroupCallLocalScreenshareStateChanged(false));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,9 +54,11 @@ class GroupCallSession {
|
|||
|
||||
String groupCallId;
|
||||
|
||||
@Deprecated('Use matrixRTCEventStream instead')
|
||||
final CachedStreamController<GroupCallState> onGroupCallState =
|
||||
CachedStreamController();
|
||||
|
||||
@Deprecated('Use matrixRTCEventStream instead')
|
||||
final CachedStreamController<GroupCallStateChange> onGroupCallEvent =
|
||||
CachedStreamController();
|
||||
|
||||
|
|
@ -105,8 +107,11 @@ class GroupCallSession {
|
|||
|
||||
void setState(GroupCallState newState) {
|
||||
state = newState;
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
onGroupCallState.add(newState);
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
onGroupCallEvent.add(GroupCallStateChange.groupCallStateChanged);
|
||||
matrixRTCEventStream.add(GroupCallStateChanged(newState));
|
||||
}
|
||||
|
||||
bool hasLocalParticipant() {
|
||||
|
|
@ -313,6 +318,7 @@ class GroupCallSession {
|
|||
.add(ParticipantsLeftEvent(participants: anyLeft.toList()));
|
||||
}
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
onGroupCallEvent.add(GroupCallStateChange.participantsChanged);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,18 @@ import 'package:matrix/matrix.dart';
|
|||
/// often.
|
||||
sealed class MatrixRTCCallEvent {}
|
||||
|
||||
/// Event type for participants change
|
||||
sealed class ParticipantsChangeEvent implements MatrixRTCCallEvent {}
|
||||
|
||||
final class ParticipantsJoinEvent implements ParticipantsChangeEvent {
|
||||
/// The participants who joined the call
|
||||
final List<CallParticipant> participants;
|
||||
|
||||
ParticipantsJoinEvent({required this.participants});
|
||||
}
|
||||
|
||||
final class ParticipantsLeftEvent implements ParticipantsChangeEvent {
|
||||
/// The participants who left the call
|
||||
final List<CallParticipant> participants;
|
||||
|
||||
ParticipantsLeftEvent({required this.participants});
|
||||
|
|
@ -46,3 +49,89 @@ final class CallReactionRemovedEvent implements CallReactionEvent {
|
|||
required this.redactedEventId,
|
||||
});
|
||||
}
|
||||
|
||||
/// Group call active speaker changed event
|
||||
final class GroupCallActiveSpeakerChanged implements MatrixRTCCallEvent {
|
||||
final CallParticipant participant;
|
||||
GroupCallActiveSpeakerChanged(this.participant);
|
||||
}
|
||||
|
||||
/// Group calls changed event type
|
||||
sealed class GroupCallChanged implements MatrixRTCCallEvent {}
|
||||
|
||||
/// Group call, call added event
|
||||
final class CallAddedEvent implements GroupCallChanged {
|
||||
final CallSession call;
|
||||
CallAddedEvent(this.call);
|
||||
}
|
||||
|
||||
/// Group call, call removed event
|
||||
final class CallRemovedEvent implements GroupCallChanged {
|
||||
final CallSession call;
|
||||
CallRemovedEvent(this.call);
|
||||
}
|
||||
|
||||
/// Group call, call replaced event
|
||||
final class CallReplacedEvent extends GroupCallChanged {
|
||||
final CallSession existingCall, replacementCall;
|
||||
CallReplacedEvent(this.existingCall, this.replacementCall);
|
||||
}
|
||||
|
||||
enum GroupCallStreamType {
|
||||
userMedia,
|
||||
screenshare,
|
||||
}
|
||||
|
||||
/// Group call stream added event
|
||||
final class GroupCallStreamAdded implements MatrixRTCCallEvent {
|
||||
final GroupCallStreamType type;
|
||||
GroupCallStreamAdded(this.type);
|
||||
}
|
||||
|
||||
/// Group call stream removed event
|
||||
final class GroupCallStreamRemoved implements MatrixRTCCallEvent {
|
||||
final GroupCallStreamType type;
|
||||
GroupCallStreamRemoved(this.type);
|
||||
}
|
||||
|
||||
/// Group call stream replaced event
|
||||
final class GroupCallStreamReplaced implements MatrixRTCCallEvent {
|
||||
final GroupCallStreamType type;
|
||||
GroupCallStreamReplaced(this.type);
|
||||
}
|
||||
|
||||
/// Group call local screenshare state changed event
|
||||
final class GroupCallLocalScreenshareStateChanged
|
||||
implements MatrixRTCCallEvent {
|
||||
final bool screensharing;
|
||||
GroupCallLocalScreenshareStateChanged(this.screensharing);
|
||||
}
|
||||
|
||||
/// Group call local muted changed event
|
||||
final class GroupCallLocalMutedChanged implements MatrixRTCCallEvent {
|
||||
final bool muted;
|
||||
final MediaInputKind kind;
|
||||
GroupCallLocalMutedChanged(this.muted, this.kind);
|
||||
}
|
||||
|
||||
enum GroupCallState {
|
||||
localCallFeedUninitialized,
|
||||
initializingLocalCallFeed,
|
||||
localCallFeedInitialized,
|
||||
entering,
|
||||
entered,
|
||||
ended
|
||||
}
|
||||
|
||||
/// Group call state changed event
|
||||
final class GroupCallStateChanged implements MatrixRTCCallEvent {
|
||||
final GroupCallState state;
|
||||
GroupCallStateChanged(this.state);
|
||||
}
|
||||
|
||||
/// Group call error event
|
||||
final class GroupCallStateError implements MatrixRTCCallEvent {
|
||||
final String msg;
|
||||
final dynamic err;
|
||||
GroupCallStateError(this.msg, this.err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ class GroupCallError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated('Use the events implementing MatrixRTCCallEvent instead')
|
||||
enum GroupCallStateChange {
|
||||
groupCallStateChanged,
|
||||
activeSpeakerChanged,
|
||||
|
|
@ -176,12 +177,3 @@ enum GroupCallStateChange {
|
|||
participantsChanged,
|
||||
error
|
||||
}
|
||||
|
||||
enum GroupCallState {
|
||||
localCallFeedUninitialized,
|
||||
initializingLocalCallFeed,
|
||||
localCallFeedInitialized,
|
||||
entering,
|
||||
entered,
|
||||
ended
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -86,18 +86,49 @@ class MockEncryptionKeyProvider implements EncryptionKeyProvider {
|
|||
}
|
||||
}
|
||||
|
||||
class MockMediaDeviceInfo implements MediaDeviceInfo {
|
||||
@override
|
||||
final String deviceId;
|
||||
@override
|
||||
final String kind;
|
||||
@override
|
||||
final String label;
|
||||
@override
|
||||
final String? groupId;
|
||||
|
||||
MockMediaDeviceInfo({
|
||||
required this.deviceId,
|
||||
required this.kind,
|
||||
required this.label,
|
||||
this.groupId,
|
||||
});
|
||||
}
|
||||
|
||||
class MockMediaDevices implements MediaDevices {
|
||||
@override
|
||||
Function(dynamic event)? ondevicechange;
|
||||
|
||||
@override
|
||||
Future<List<MediaDeviceInfo>> enumerateDevices() {
|
||||
throw UnimplementedError();
|
||||
Future<List<MediaDeviceInfo>> enumerateDevices() async {
|
||||
return [
|
||||
MockMediaDeviceInfo(
|
||||
deviceId: 'default_audio_input',
|
||||
kind: 'audioinput',
|
||||
label: 'Default Audio Input',
|
||||
),
|
||||
MockMediaDeviceInfo(
|
||||
deviceId: 'default_video_input',
|
||||
kind: 'videoinput',
|
||||
label: 'Default Video Input',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MediaStream> getDisplayMedia(Map<String, dynamic> mediaConstraints) {
|
||||
throw UnimplementedError();
|
||||
Future<MediaStream> getDisplayMedia(
|
||||
Map<String, dynamic> mediaConstraints,
|
||||
) async {
|
||||
return MockMediaStream('', '');
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -160,6 +191,9 @@ class MockRTCPeerConnection implements RTCPeerConnection {
|
|||
@override
|
||||
Function(RTCTrackEvent event)? onTrack;
|
||||
|
||||
// Mock stats to simulate audio levels
|
||||
double mockAudioLevel = 0.0;
|
||||
|
||||
@override
|
||||
RTCSignalingState? get signalingState => throw UnimplementedError();
|
||||
|
||||
|
|
@ -276,8 +310,23 @@ class MockRTCPeerConnection implements RTCPeerConnection {
|
|||
@override
|
||||
Future<List<StatsReport>> getStats([MediaStreamTrack? track]) async {
|
||||
// Mock implementation for getting stats
|
||||
Logs().i('Mock: Getting stats');
|
||||
return [];
|
||||
Logs().i('Mock: Getting stats with audioLevel: $mockAudioLevel');
|
||||
return [
|
||||
MockStatsReport(
|
||||
type: 'inbound-rtp',
|
||||
values: {
|
||||
'kind': 'audio',
|
||||
'audioLevel': mockAudioLevel,
|
||||
},
|
||||
),
|
||||
MockStatsReport(
|
||||
type: 'media-source',
|
||||
values: {
|
||||
'kind': 'audio',
|
||||
'audioLevel': mockAudioLevel,
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -850,3 +899,45 @@ class MockVideoRenderer implements VideoRenderer {
|
|||
Logs().i('Mock: Disposing VideoRenderer');
|
||||
}
|
||||
}
|
||||
|
||||
class MockStatsReport implements StatsReport {
|
||||
@override
|
||||
final String type;
|
||||
|
||||
@override
|
||||
final Map<String, dynamic> values;
|
||||
|
||||
@override
|
||||
final String id;
|
||||
|
||||
@override
|
||||
final double timestamp;
|
||||
|
||||
MockStatsReport({
|
||||
required this.type,
|
||||
required this.values,
|
||||
this.id = 'mock-stats-id',
|
||||
this.timestamp = 0.0,
|
||||
});
|
||||
}
|
||||
|
||||
class MockRTCTrackEvent implements RTCTrackEvent {
|
||||
@override
|
||||
final MediaStreamTrack track;
|
||||
|
||||
@override
|
||||
final RTCRtpReceiver? receiver;
|
||||
|
||||
@override
|
||||
final List<MediaStream> streams;
|
||||
|
||||
@override
|
||||
final RTCRtpTransceiver? transceiver;
|
||||
|
||||
MockRTCTrackEvent({
|
||||
required this.track,
|
||||
this.receiver,
|
||||
required this.streams,
|
||||
this.transceiver,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue