onCallInvite method
Implementation
Future<void> onCallInvite(
String roomId, String senderId, Map<String, dynamic> content) async {
if (senderId == client.userID) {
// Ignore messages to yourself.
return;
}
Logs().v(
'[VOIP] onCallInvite $senderId => ${client.userID}, \ncontent => ${content.toString()}');
final String callId = content['call_id'];
final String partyId = content['party_id'];
final int lifetime = content['lifetime'];
final String? confId = content['conf_id'];
final String? deviceId = content['device_id'];
final call = calls[callId];
Logs().d(
'[glare] got new call ${content.tryGet('call_id')} and currently room id is mapped to ${incomingCallRoomId.tryGet(roomId)}');
if (call != null && call.state == CallState.kEnded) {
// Session already exist.
Logs().v('[VOIP] onCallInvite: Session [$callId] already exist.');
return;
}
if (content['invitee'] != null && content['invitee'] != client.userID) {
return; // This invite was meant for another user in the room
}
if (content['capabilities'] != null) {
final capabilities = CallCapabilities.fromJson(content['capabilities']);
Logs().v(
'[VOIP] CallCapabilities: dtmf => ${capabilities.dtmf}, transferee => ${capabilities.transferee}');
}
var callType = CallType.kVoice;
SDPStreamMetadata? sdpStreamMetadata;
if (content[sdpStreamMetadataKey] != null) {
sdpStreamMetadata =
SDPStreamMetadata.fromJson(content[sdpStreamMetadataKey]);
sdpStreamMetadata.sdpStreamMetadatas
.forEach((streamId, SDPStreamPurpose purpose) {
Logs().v(
'[VOIP] [$streamId] => purpose: ${purpose.purpose}, audioMuted: ${purpose.audio_muted}, videoMuted: ${purpose.video_muted}');
if (!purpose.video_muted) {
callType = CallType.kVideo;
}
});
} else {
callType = getCallType(content['offer']['sdp']);
}
final room = client.getRoomById(roomId);
final opts = CallOptions()
..voip = this
..callId = callId
..groupCallId = confId
..dir = CallDirection.kIncoming
..type = callType
..room = room!
..localPartyId = localPartyId!
..iceServers = await getIceSevers();
final newCall = createNewCall(opts);
newCall.remotePartyId = partyId;
newCall.remoteUser = await room.requestUser(senderId);
newCall.opponentDeviceId = deviceId;
newCall.opponentSessionId = content['sender_session_id'];
if (!delegate.canHandleNewCall &&
(confId == null || confId != currentGroupCID)) {
Logs().v(
'[VOIP] onCallInvite: Unable to handle new calls, maybe user is busy.');
await newCall.reject(reason: CallErrorCode.UserBusy, shouldEmit: false);
await delegate.handleMissedCall(newCall);
return;
}
final offer = RTCSessionDescription(
content['offer']['sdp'],
content['offer']['type'],
);
/// play ringtone. We decided to play the ringtone before adding the call to
/// the incoming call stream because getUserMedia from initWithInvite fails
/// on firefox unless the tab is in focus. We should atleast be able to notify
/// the user about an incoming call
///
/// Autoplay on firefox still needs interaction, without which all notifications
/// could be blocked.
if (confId == null) {
await delegate.playRingtone();
}
await newCall.initWithInvite(
callType, offer, sdpStreamMetadata, lifetime, confId != null);
currentCID = callId;
// Popup CallingPage for incoming call.
if (confId == null && !newCall.callHasEnded) {
await delegate.handleNewCall(newCall);
}
onIncomingCall.add(newCall);
}