import 'dart:typed_data'; import 'package:webrtc_interface/webrtc_interface.dart'; import 'package:matrix/matrix.dart'; class MockWebRTCDelegate implements WebRTCDelegate { @override bool get canHandleNewCall => true; @override Future createPeerConnection( Map configuration, [ Map constraints = const {}, ]) async => MockRTCPeerConnection(); @override Future registerListeners(CallSession session) async { Logs().i('registerListeners called in MockWebRTCDelegate'); } @override Future handleCallEnded(CallSession session) async { Logs().i('handleCallEnded called in MockWebRTCDelegate'); } @override Future handleGroupCallEnded(GroupCallSession groupCall) async { Logs().i('handleGroupCallEnded called in MockWebRTCDelegate'); } @override Future handleMissedCall(CallSession session) async { Logs().i('handleMissedCall called in MockWebRTCDelegate'); } @override Future handleNewCall(CallSession session) async { Logs().i('handleNewCall called in MockWebRTCDelegate'); } @override Future handleNewGroupCall(GroupCallSession groupCall) async { Logs().i('handleNewGroupCall called in MockWebRTCDelegate'); } @override bool get isWeb => false; @override MediaDevices get mediaDevices => MockMediaDevices(); @override Future playRingtone() async { Logs().i('playRingtone called in MockWebRTCDelegate'); } @override Future stopRingtone() async { Logs().i('stopRingtone called in MockWebRTCDelegate'); } @override EncryptionKeyProvider? get keyProvider => MockEncryptionKeyProvider(); } class MockEncryptionKeyProvider implements EncryptionKeyProvider { @override Future onSetEncryptionKey( CallParticipant participant, Uint8List key, int index, ) async { Logs().i('Mock onSetEncryptionKey called for ${participant.id} '); } @override Future onExportKey(CallParticipant participant, int index) { throw UnimplementedError(); } @override Future onRatchetKey(CallParticipant participant, int index) { throw UnimplementedError(); } } class MockMediaDevices implements MediaDevices { @override Function(dynamic event)? ondevicechange; @override Future> enumerateDevices() { throw UnimplementedError(); } @override Future getDisplayMedia(Map mediaConstraints) { throw UnimplementedError(); } @override Future getSources() { throw UnimplementedError(); } @override MediaTrackSupportedConstraints getSupportedConstraints() { throw UnimplementedError(); } @override Future getUserMedia( Map mediaConstraints, ) async { return MockMediaStream('', ''); } @override Future selectAudioOutput([AudioOutputOptions? options]) { throw UnimplementedError(); } } class MockRTCPeerConnection implements RTCPeerConnection { @override Function(RTCSignalingState state)? onSignalingState; @override Function(RTCPeerConnectionState state)? onConnectionState; @override Function(RTCIceGatheringState state)? onIceGatheringState; @override Function(RTCIceConnectionState state)? onIceConnectionState; @override Function(RTCIceCandidate candidate)? onIceCandidate; @override Function(MediaStream stream)? onAddStream; @override Function(MediaStream stream)? onRemoveStream; @override Function(MediaStream stream, MediaStreamTrack track)? onAddTrack; @override Function(MediaStream stream, MediaStreamTrack track)? onRemoveTrack; @override Function(RTCDataChannel channel)? onDataChannel; @override Function()? onRenegotiationNeeded; @override Function(RTCTrackEvent event)? onTrack; @override RTCSignalingState? get signalingState => throw UnimplementedError(); @override Future getSignalingState() async { return signalingState; } @override // value doesn't matter we do onIceConnectionState.call manually RTCIceGatheringState? get iceGatheringState => RTCIceGatheringState.RTCIceGatheringStateComplete; @override Future getIceGatheringState() async { return iceGatheringState; } @override // value doesn't matter we do onIceConnectionState.call manually RTCIceConnectionState? get iceConnectionState => RTCIceConnectionState.RTCIceConnectionStateNew; @override Future getIceConnectionState() async { return iceConnectionState; } @override RTCPeerConnectionState? get connectionState => throw UnimplementedError(); @override Future getConnectionState() async { return connectionState; } @override Future dispose() async { // Mock implementation for disposing the connection Logs().i('Mock: Disposing RTCPeerConnection'); } @override Map get getConfiguration => throw UnimplementedError(); @override Future setConfiguration(Map configuration) async { // Mock implementation for setting configuration Logs().i('Mock: Setting RTCPeerConnection configuration'); } @override Future createOffer([ Map? constraints, ]) { // Mock implementation for creating an offer Logs().i('Mock: Creating offer'); return Future.value(RTCSessionDescription('', '')); } @override Future createAnswer([ Map? constraints, ]) { // Mock implementation for creating an answer Logs().i('Mock: Creating answer'); return Future.value(RTCSessionDescription('', '')); } @override Future addStream(MediaStream stream) async { // Mock implementation for adding a stream Logs().i('Mock: Adding stream'); } @override Future removeStream(MediaStream stream) async { // Mock implementation for removing a stream Logs().i('Mock: Removing stream'); } @override Future getLocalDescription() async { // Mock implementation for getting local description Logs().i('Mock: Getting local description'); return RTCSessionDescription('', ''); } @override Future setLocalDescription(RTCSessionDescription description) async { // Mock implementation for setting local description Logs().i('Mock: Setting local description'); } @override Future getRemoteDescription() async { // Mock implementation for getting remote description Logs().i('Mock: Getting remote description'); return RTCSessionDescription('', ''); } @override Future setRemoteDescription(RTCSessionDescription description) async { // Mock implementation for setting remote description Logs().i('Mock: Setting remote description'); } @override Future addCandidate(RTCIceCandidate candidate) async { // Mock implementation for adding a candidate Logs().i('Mock: Adding ICE candidate'); } @override Future> getStats([MediaStreamTrack? track]) async { // Mock implementation for getting stats Logs().i('Mock: Getting stats'); return []; } @override List getLocalStreams() { // Mock implementation for getting local streams Logs().i('Mock: Getting local streams'); return []; } @override List getRemoteStreams() { // Mock implementation for getting remote streams Logs().i('Mock: Getting remote streams'); return []; } @override Future createDataChannel( String label, RTCDataChannelInit dataChannelDict, ) async { // Mock implementation for creating a data channel Logs().i('Mock: Creating data channel'); return MockRTCDataChannel(); } @override Future restartIce() async { // Mock implementation for restarting ICE Logs().i('Mock: Restarting ICE'); } @override Future close() async { // Mock implementation for closing the connection Logs().i('Mock: Closing RTCPeerConnection'); } @override RTCDTMFSender createDtmfSender(MediaStreamTrack track) { // Mock implementation for creating a DTMF sender Logs().i('Mock: Creating DTMF sender'); return MockRTCDTMFSender(); } @override Future> getSenders() async { // Mock implementation for getting senders Logs().i('Mock: Getting senders'); return []; } @override Future> getReceivers() async { // Mock implementation for getting receivers Logs().i('Mock: Getting receivers'); return []; } @override Future> getTransceivers() async { // Mock implementation for getting transceivers Logs().i('Mock: Getting transceivers'); return []; } @override Future addTrack( MediaStreamTrack track, [ MediaStream? stream, ]) async { // Mock implementation for adding a track Logs().i('Mock: Adding track'); return MockRTCRtpSender(); } @override Future removeTrack(RTCRtpSender sender) async { // Mock implementation for removing a track Logs().i('Mock: Removing track'); return true; } @override Future addTransceiver({ MediaStreamTrack? track, RTCRtpMediaType? kind, RTCRtpTransceiverInit? init, }) async { // Mock implementation for adding a transceiver Logs().i('Mock: Adding transceiver'); return MockRTCRtpTransceiver(); } @override Future> get receivers => throw UnimplementedError(); @override Future> get senders => throw UnimplementedError(); @override Future> get transceivers => throw UnimplementedError(); } class MockRTCRtpTransceiver implements RTCRtpTransceiver { @override Future getCurrentDirection() async { // Mock implementation for getting current direction Logs().i('Mock: Getting current direction'); return TransceiverDirection.SendRecv; } @override Future setDirection(TransceiverDirection direction) async { // Mock implementation for setting direction Logs().i('Mock: Setting direction'); } @override Future getDirection() async { // Mock implementation for getting direction Logs().i('Mock: Getting direction'); return TransceiverDirection.SendRecv; } @override Future setCodecPreferences(List codecs) async { // Mock implementation for setting codec preferences Logs().i('Mock: Setting codec preferences'); } @override String get mid => 'mock_mid'; @override RTCRtpSender get sender => MockRTCRtpSender(); @override RTCRtpReceiver get receiver => MockRTCRtpReceiver(); bool get stopped => false; @override String get transceiverId => 'mock_transceiver_id'; @override Future stop() async { // Mock implementation for stopping transceiver Logs().i('Mock: Stopping transceiver'); } @override TransceiverDirection get currentDirection { // Deprecated method, should be replaced with `await getCurrentDirection` throw UnimplementedError( 'Need to be call asynchronously from native SDK, so the method is deprecated', ); } @override bool get stoped => throw UnimplementedError(); } class MockRTCRtpSender implements RTCRtpSender { @override Future dispose() { throw UnimplementedError(); } @override RTCDTMFSender get dtmfSender => throw UnimplementedError(); @override Future> getStats() { throw UnimplementedError(); } @override bool get ownsTrack => throw UnimplementedError(); @override RTCRtpParameters get parameters => throw UnimplementedError(); @override Future replaceTrack(MediaStreamTrack? track) { throw UnimplementedError(); } @override String get senderId => throw UnimplementedError(); @override Future setParameters(RTCRtpParameters parameters) { throw UnimplementedError(); } @override Future setStreams(List streams) { throw UnimplementedError(); } @override Future setTrack(MediaStreamTrack? track, {bool takeOwnership = true}) { throw UnimplementedError(); } @override MediaStreamTrack? get track => throw UnimplementedError(); // Mock implementation for RTCRtpSender } class MockRTCRtpReceiver implements RTCRtpReceiver { @override Function(RTCRtpReceiver rtpReceiver, RTCRtpMediaType mediaType)? onFirstPacketReceived; @override Future> getStats() { throw UnimplementedError(); } @override RTCRtpParameters get parameters => throw UnimplementedError(); @override String get receiverId => throw UnimplementedError(); @override MediaStreamTrack? get track => throw UnimplementedError(); // Mock implementation for RTCRtpReceiver } typedef StreamTrackCallback = void Function(); class MockMediaStreamTrack implements MediaStreamTrack { @override String? get id => 'mock_id'; @override String? get label => 'mock_label'; @override String? get kind => 'mock_kind'; @override StreamTrackCallback? onMute; @override StreamTrackCallback? onUnMute; @override StreamTrackCallback? onEnded; @override bool get enabled => true; @override set enabled(bool b) { // Mock implementation for setting enable state Logs().i('Mock: Setting MediaStreamTrack enable state'); } @override bool? get muted => false; @override Map getConstraints() { throw UnimplementedError(); } @override Future applyConstraints([Map? constraints]) async { throw UnimplementedError(); } @override Future clone() async { throw UnimplementedError(); } @override Future stop() async { // Mock implementation for stopping the track Logs().i('Mock: Stopping MediaStreamTrack'); } @override Map getSettings() { throw UnimplementedError(); } @override Future switchCamera() async { throw UnimplementedError(); } @override Future adaptRes(int width, int height) async { throw UnimplementedError(); } @override void enableSpeakerphone(bool enable) { throw UnimplementedError(); } @override Future captureFrame() async { throw UnimplementedError(); } @override Future hasTorch() async { throw UnimplementedError(); } @override Future setTorch(bool torch) async { throw UnimplementedError(); } @override @Deprecated('use stop() instead') Future dispose() async { // Mock implementation for disposing the track Logs().i('Mock: Disposing MediaStreamTrack'); } @override String toString() { return 'Track(id: $id, kind: $kind, label: $label, enabled: $enabled, muted: $muted)'; } } class MockRTCDTMFSender implements RTCDTMFSender { @override Future insertDTMF( String tones, { int duration = 100, int interToneGap = 70, }) async { // Mock implementation for inserting DTMF tones Logs().i( 'Mock: Inserting DTMF tones: $tones, Duration: $duration, InterToneGap: $interToneGap', ); } @override @Deprecated('Use method insertDTMF instead') Future sendDtmf( String tones, { int duration = 100, int interToneGap = 70, }) async { return insertDTMF(tones, duration: duration, interToneGap: interToneGap); } @override Future canInsertDtmf() async { // Mock implementation for checking if DTMF can be inserted Logs().i('Mock: Checking if DTMF can be inserted'); return true; } } class MockRTCDataChannel implements RTCDataChannel { @override Function(RTCDataChannelState state)? onDataChannelState; @override Function(RTCDataChannelMessage data)? onMessage; @override Function(int currentAmount, int changedAmount)? onBufferedAmountChange; @override Function(int currentAmount)? onBufferedAmountLow; @override RTCDataChannelState? get state => RTCDataChannelState.RTCDataChannelOpen; @override int? get id => 1; @override String? get label => 'mock_label'; @override int? get bufferedAmount => 0; @override int? bufferedAmountLowThreshold; @override late Stream stateChangeStream; @override late Stream messageStream; @override Future send(RTCDataChannelMessage message) async { // Mock implementation for sending a message Logs().i('Mock: Sending RTCDataChannelMessage: $message'); } @override Future close() async { // Mock implementation for closing the data channel Logs().i('Mock: Closing RTCDataChannel'); } @override Future getBufferedAmount() async { return 0; } } class MockMediaStream implements MediaStream { final String _id; final String _ownerTag; bool _isActive = true; // Initially set as active MockMediaStream(this._id, this._ownerTag); @override Function(MediaStreamTrack track)? onAddTrack; @override Function(MediaStreamTrack track)? onRemoveTrack; @override String get id => _id; @override String get ownerTag => _ownerTag; @override bool? get active => _isActive; @override Future getMediaTracks() async { // Mock implementation for getting media tracks Logs().i('Mock: Getting media tracks'); } @override Future addTrack( MediaStreamTrack track, { bool addToNative = true, }) async { // Mock implementation for adding a track Logs().i('Mock: Adding track to MediaStream: $track'); onAddTrack?.call(track); } @override Future removeTrack( MediaStreamTrack track, { bool removeFromNative = true, }) async { // Mock implementation for removing a track Logs().i('Mock: Removing track from MediaStream: $track'); onRemoveTrack?.call(track); } @override List getTracks() { // Mock implementation for getting all tracks Logs().i('Mock: Getting all tracks'); return []; } @override List getAudioTracks() { // Mock implementation for getting audio tracks Logs().i('Mock: Getting audio tracks'); return []; } @override List getVideoTracks() { // Mock implementation for getting video tracks Logs().i('Mock: Getting video tracks'); return []; } @override MediaStreamTrack? getTrackById(String trackId) { // Mock implementation for getting a track by ID Logs().i('Mock: Getting track by ID: $trackId'); return null; } @override Future clone() async { // Mock implementation for cloning the media stream Logs().i('Mock: Cloning MediaStream'); return MockMediaStream('${_id}_clone', _ownerTag); } @override Future dispose() async { // Mock implementation for disposing the media stream Logs().i('Mock: Disposing MediaStream'); _isActive = false; } } class MockVideoRenderer implements VideoRenderer { @override Function? onResize; @override Function? onFirstFrameRendered; final int _videoWidth = 0; final int _videoHeight = 0; bool _muted = false; final bool _renderVideo = true; int? _textureId; MediaStream? _srcObject; @override int get videoWidth => _videoWidth; @override int get videoHeight => _videoHeight; @override bool get muted => _muted; @override set muted(bool mute) { _muted = mute; // Mock implementation for muting/unmuting Logs().i('Mock: Setting mute state: $_muted'); } @override Future audioOutput(String deviceId) async { // Mock implementation for changing audio output Logs().i('Mock: Changing audio output to device ID: $deviceId'); return true; // Mocking successful audio output change } @override bool get renderVideo => _renderVideo; @override int? get textureId => _textureId; @override Future initialize() async { // Mock implementation for initialization Logs().i('Mock: Initializing VideoRenderer'); } @override MediaStream? get srcObject => _srcObject; @override set srcObject(MediaStream? stream) { _srcObject = stream; // Mock implementation for setting source object Logs().i('Mock: Setting source object for VideoRenderer'); } @override Future dispose() async { // Mock implementation for disposing VideoRenderer Logs().i('Mock: Disposing VideoRenderer'); } }