Skip to main content
Handle call session events to build responsive UIs. The SDK provides five event listener interfaces to monitor session status, participant activities, media changes, button clicks, and layout changes. Unlike Android, Flutter listeners are not lifecycle-aware and must be manually removed in dispose() to prevent memory leaks.

Get CallSession Instance

The CallSession is a singleton that manages the active call. All event listener registrations and session control methods are accessed through this instance.
CallSession? callSession = CallSession.getInstance();
Flutter listeners are not lifecycle-aware. You must manually remove all listeners in your widget’s dispose() method to prevent memory leaks. Failing to do so may cause callbacks to fire on disposed widgets.

Session Events

Monitor the call session lifecycle including join/leave events and connection status.
final sessionStatusListener = SessionStatusListener(
  onSessionJoined: () {
    // Successfully connected to the session
  },
  onSessionLeft: () {
    // Navigate away
  },
  onSessionTimedOut: () {
    // Session ended due to inactivity
  },
  onConnectionLost: () {
    // Network interrupted, attempting reconnection
  },
  onConnectionRestored: () {
    // Connection restored after being lost
  },
  onConnectionClosed: () {
    // Connection permanently closed
  },
);

CallSession.getInstance()?.addSessionStatusListener(sessionStatusListener);
EventDescription
onSessionJoinedSuccessfully connected and joined the session
onSessionLeftLeft the session via leaveSession() or was removed
onSessionTimedOutSession ended due to inactivity timeout
onConnectionLostNetwork interrupted, SDK attempting reconnection
onConnectionRestoredConnection restored after being lost
onConnectionClosedConnection permanently closed, cannot reconnect
Remove the listener when no longer needed:
@override
void dispose() {
  CallSession.getInstance()?.removeSessionStatusListener(sessionStatusListener);
  super.dispose();
}

Participant Events

Monitor participant activities including join/leave, audio/video state, hand raise, screen sharing, and recording.
final participantEventListener = ParticipantEventListener(
  onParticipantJoined: (Participant participant) {
    // A participant joined the call
  },
  onParticipantLeft: (Participant participant) {
    // A participant left the call
  },
  onParticipantListChanged: (List<Participant> participants) {
    // Participant list updated
  },
  onParticipantAudioMuted: (Participant participant) {},
  onParticipantAudioUnmuted: (Participant participant) {},
  onParticipantVideoPaused: (Participant participant) {},
  onParticipantVideoResumed: (Participant participant) {},
  onParticipantHandRaised: (Participant participant) {},
  onParticipantHandLowered: (Participant participant) {},
  onParticipantStartedScreenShare: (Participant participant) {},
  onParticipantStoppedScreenShare: (Participant participant) {},
  onParticipantStartedRecording: (Participant participant) {},
  onParticipantStoppedRecording: (Participant participant) {},
  onDominantSpeakerChanged: (Participant participant) {},
);

CallSession.getInstance()?.addParticipantEventListener(participantEventListener);
EventParameterDescription
onParticipantJoinedParticipantA participant connected to the call
onParticipantLeftParticipantA participant disconnected from the call
onParticipantListChangedList<Participant>Participant list updated
onParticipantAudioMutedParticipantA participant muted their microphone
onParticipantAudioUnmutedParticipantA participant unmuted their microphone
onParticipantVideoPausedParticipantA participant turned off their camera
onParticipantVideoResumedParticipantA participant turned on their camera
onParticipantHandRaisedParticipantA participant raised their hand
onParticipantHandLoweredParticipantA participant lowered their hand
onParticipantStartedScreenShareParticipantA participant started screen sharing
onParticipantStoppedScreenShareParticipantA participant stopped screen sharing
onParticipantStartedRecordingParticipantA participant started recording
onParticipantStoppedRecordingParticipantA participant stopped recording
onDominantSpeakerChangedParticipantThe active speaker changed
Remove the listener when no longer needed:
@override
void dispose() {
  CallSession.getInstance()?.removeParticipantEventListener(participantEventListener);
  super.dispose();
}

Media Events

Monitor your local media state changes including audio/video status, recording, and device changes.
final mediaEventsListener = MediaEventsListener(
  onAudioMuted: () {
    // Your microphone was muted
  },
  onAudioUnMuted: () {
    // Your microphone was unmuted
  },
  onVideoPaused: () {
    // Your camera was turned off
  },
  onVideoResumed: () {
    // Your camera was turned on
  },
  onRecordingStarted: () {
    // Call recording started
  },
  onRecordingStopped: () {
    // Call recording stopped
  },
  onScreenShareStarted: () {
    // You started screen sharing
  },
  onScreenShareStopped: () {
    // You stopped screen sharing
  },
  onAudioModeChanged: (AudioMode audioMode) {
    // Audio output device changed
  },
  onCameraFacingChanged: (CameraFacing facing) {
    // Camera switched between front and rear
  },
);

CallSession.getInstance()?.addMediaEventsListener(mediaEventsListener);
EventParameterDescription
onAudioMuted-Your microphone was muted
onAudioUnMuted-Your microphone was unmuted
onVideoPaused-Your camera was turned off
onVideoResumed-Your camera was turned on
onRecordingStarted-Call recording started
onRecordingStopped-Call recording stopped
onScreenShareStarted-You started screen sharing
onScreenShareStopped-You stopped screen sharing
onAudioModeChangedAudioModeAudio output device changed
onCameraFacingChangedCameraFacingCamera switched between front and rear
ValueDescription
AudioMode.speakerAudio routed through device loudspeaker
AudioMode.earpieceAudio routed through phone earpiece
AudioMode.bluetoothAudio routed through connected Bluetooth device
ValueDescription
CameraFacing.frontFront-facing (selfie) camera is active
CameraFacing.rearRear-facing (main) camera is active
Remove the listener when no longer needed:
@override
void dispose() {
  CallSession.getInstance()?.removeMediaEventsListener(mediaEventsListener);
  super.dispose();
}

Button Click Events

Intercept UI button clicks from the default call interface to add custom behavior or analytics.
final buttonClickListener = ButtonClickListener(
  onLeaveSessionButtonClicked: () {
    // Leave button tapped
  },
  onToggleAudioButtonClicked: () {
    // Mute/unmute button tapped
  },
  onToggleVideoButtonClicked: () {
    // Video on/off button tapped
  },
  onSwitchCameraButtonClicked: () {},
  onRaiseHandButtonClicked: () {},
  onShareInviteButtonClicked: () {},
  onChangeLayoutButtonClicked: () {},
  onParticipantListButtonClicked: () {},
  onChatButtonClicked: () {},
  onRecordingToggleButtonClicked: () {},
);

CallSession.getInstance()?.addButtonClickListener(buttonClickListener);
EventDescription
onLeaveSessionButtonClickedLeave/end call button was tapped
onToggleAudioButtonClickedMute/unmute button was tapped
onToggleVideoButtonClickedVideo on/off button was tapped
onSwitchCameraButtonClickedCamera switch button was tapped
onRaiseHandButtonClickedRaise hand button was tapped
onShareInviteButtonClickedShare/invite button was tapped
onChangeLayoutButtonClickedLayout change button was tapped
onParticipantListButtonClickedParticipant list button was tapped
onChatButtonClickedIn-call chat button was tapped
onRecordingToggleButtonClickedRecording toggle button was tapped
Button click events fire before the SDK’s default action executes. Use these to add custom logic alongside default behavior.
Remove the listener when no longer needed:
@override
void dispose() {
  CallSession.getInstance()?.removeButtonClickListener(buttonClickListener);
  super.dispose();
}

Layout Events

Monitor layout changes including layout type switches and Picture-in-Picture mode transitions.
final layoutListener = LayoutListener(
  onCallLayoutChanged: (LayoutType layoutType) {
    // Layout changed (tile, spotlight)
  },
  onParticipantListVisible: () {
    // Participant list panel opened
  },
  onParticipantListHidden: () {
    // Participant list panel closed
  },
  onPictureInPictureLayoutEnabled: () {
    // Entered PiP mode
  },
  onPictureInPictureLayoutDisabled: () {
    // Exited PiP mode
  },
);

CallSession.getInstance()?.addLayoutListener(layoutListener);
EventParameterDescription
onCallLayoutChangedLayoutTypeCall layout changed
onParticipantListVisible-Participant list panel was opened
onParticipantListHidden-Participant list panel was closed
onPictureInPictureLayoutEnabled-Call entered Picture-in-Picture mode
onPictureInPictureLayoutDisabled-Call exited Picture-in-Picture mode
ValueDescriptionBest For
LayoutType.tileGrid layout with equally-sized tilesGroup discussions, team meetings
LayoutType.spotlightLarge view for active speaker, small tiles for othersPresentations, one-on-one calls
Remove the listener when no longer needed:
@override
void dispose() {
  CallSession.getInstance()?.removeLayoutListener(layoutListener);
  super.dispose();
}