Skip to content

Commit 1d2cb70

Browse files
committed
refactor: extract renegotiation logic into RenegotiationHandler
1 parent b5e9702 commit 1d2cb70

File tree

3 files changed

+61
-35
lines changed

3 files changed

+61
-35
lines changed

lib/features/call/bloc/call_bloc.dart

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class CallBloc extends Bloc<CallEvent, CallState> with WidgetsBindingObserver im
9595
Timer? _presenceInfoSyncTimer;
9696

9797
late final PeerConnectionManager _peerConnectionManager;
98+
late final RenegotiationHandler _renegotiationHandler;
9899

99100
final _callkeepSound = WebtritCallkeepSound();
100101

@@ -129,6 +130,7 @@ class CallBloc extends Bloc<CallEvent, CallState> with WidgetsBindingObserver im
129130
}) : super(const CallState()) {
130131
_signalingClientFactory = signalingClientFactory;
131132
_peerConnectionManager = peerConnectionManager;
133+
_renegotiationHandler = RenegotiationHandler(callErrorReporter: callErrorReporter, sdpMunger: sdpMunger);
132134

133135
on<CallStarted>(_onCallStarted, transformer: sequential());
134136
on<_AppLifecycleStateChanged>(_onAppLifecycleStateChanged, transformer: sequential());
@@ -2782,45 +2784,19 @@ class CallBloc extends Bloc<CallEvent, CallState> with WidgetsBindingObserver im
27822784
onIceCandidate: (candidate) => add(_PeerConnectionEvent.iceCandidateIdentified(callId, candidate)),
27832785
onAddStream: (stream) => add(_PeerConnectionEvent.streamAdded(callId, stream)),
27842786
onRemoveStream: (stream) => add(_PeerConnectionEvent.streamRemoved(callId, stream)),
2785-
onRenegotiationNeeded: (pc) => _handleRenegotiationNeeded(callId, lineId, pc),
2787+
onRenegotiationNeeded: (pc) => _renegotiationHandler.handle(callId, lineId, pc, (callId, lineId, jsep) async {
2788+
final updateRequest = UpdateRequest(
2789+
transaction: WebtritSignalingClient.generateTransactionId(),
2790+
line: lineId,
2791+
callId: callId,
2792+
jsep: jsep.toMap(),
2793+
);
2794+
await _signalingClient?.execute(updateRequest);
2795+
}),
27862796
),
27872797
);
27882798
}
27892799

2790-
Future<void> _handleRenegotiationNeeded(String callId, int? lineId, RTCPeerConnection peerConnection) async {
2791-
final stateBeforeOffer = peerConnection.signalingState;
2792-
_logger.fine(() => 'onRenegotiationNeeded signalingState: $stateBeforeOffer');
2793-
if (stateBeforeOffer == RTCSignalingState.RTCSignalingStateStable) {
2794-
final localDescription = await peerConnection.createOffer({});
2795-
sdpMunger?.apply(localDescription);
2796-
2797-
final stateAfterOffer = peerConnection.signalingState;
2798-
if (stateAfterOffer != RTCSignalingState.RTCSignalingStateStable) {
2799-
_logger.fine(
2800-
() =>
2801-
'onRenegotiationNeeded: state changed to $stateAfterOffer after createOffer, skipping setLocalDescription',
2802-
);
2803-
return;
2804-
}
2805-
2806-
// According to RFC 8829 5.6 (https://datatracker.ietf.org/doc/html/rfc8829#section-5.6),
2807-
// localDescription should be set before sending the offer to transition into have-local-offer state.
2808-
await peerConnection.setLocalDescription(localDescription);
2809-
2810-
try {
2811-
final updateRequest = UpdateRequest(
2812-
transaction: WebtritSignalingClient.generateTransactionId(),
2813-
line: lineId,
2814-
callId: callId,
2815-
jsep: localDescription.toMap(),
2816-
);
2817-
await _signalingClient?.execute(updateRequest);
2818-
} catch (e, s) {
2819-
callErrorReporter.handle(e, s, '_createPeerConnection:onRenegotiationNeeded error');
2820-
}
2821-
}
2822-
}
2823-
28242800
void _addToRecents(ActiveCall activeCall) {
28252801
final number = activeCall.handle.value;
28262802
final username = activeCall.displayName;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import 'package:flutter_webrtc/flutter_webrtc.dart';
2+
import 'package:logging/logging.dart';
3+
4+
import 'call_error_reporter.dart';
5+
import 'sdp_munger.dart';
6+
7+
final _logger = Logger('RenegotiationHandler');
8+
9+
typedef RenegotiationExecutor = Future<void> Function(String callId, int? lineId, RTCSessionDescription jsep);
10+
11+
class RenegotiationHandler {
12+
RenegotiationHandler({required this.callErrorReporter, this.sdpMunger});
13+
14+
final CallErrorReporter callErrorReporter;
15+
final SDPMunger? sdpMunger;
16+
17+
Future<void> handle(
18+
String callId,
19+
int? lineId,
20+
RTCPeerConnection peerConnection,
21+
RenegotiationExecutor execute,
22+
) async {
23+
final stateBeforeOffer = peerConnection.signalingState;
24+
_logger.fine(() => 'onRenegotiationNeeded signalingState: $stateBeforeOffer');
25+
if (stateBeforeOffer == RTCSignalingState.RTCSignalingStateStable) {
26+
final localDescription = await peerConnection.createOffer({});
27+
sdpMunger?.apply(localDescription);
28+
29+
final stateAfterOffer = peerConnection.signalingState;
30+
if (stateAfterOffer != RTCSignalingState.RTCSignalingStateStable) {
31+
_logger.fine(
32+
() =>
33+
'onRenegotiationNeeded: state changed to $stateAfterOffer after createOffer, skipping setLocalDescription',
34+
);
35+
return;
36+
}
37+
38+
// According to RFC 8829 5.6 (https://datatracker.ietf.org/doc/html/rfc8829#section-5.6),
39+
// localDescription should be set before sending the offer to transition into have-local-offer state.
40+
await peerConnection.setLocalDescription(localDescription);
41+
42+
try {
43+
await execute(callId, lineId, localDescription);
44+
} catch (e, s) {
45+
callErrorReporter.handle(e, s, '_createPeerConnection:onRenegotiationNeeded error');
46+
}
47+
}
48+
}
49+
}

lib/features/call/utils/utils.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export 'ice_filter.dart';
77
export 'logging_rtp_traffic_monitor_delegate.dart';
88
export 'peer_connection_factory.dart';
99
export 'peer_connection_manager.dart';
10+
export 'renegotiation_handler.dart';
1011
export 'peer_connection_policy_applier.dart';
1112
export 'rtp_traffic_monitor.dart';
1213
export 'sdp_mod_builder.dart';

0 commit comments

Comments
 (0)