> ## Documentation Index
> Fetch the complete documentation index at: https://www.cometchat.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Call Session

> CometChat Calling SDK v4 - Stable Release - Call Session for Android

## Overview

This section demonstrates how to start a call session in an Android application. Previously known as **Direct Calling**.

Before you begin, we strongly recommend you read the [calling setup guide](/calls/v4/android/setup).

<Note>
  If you want to implement a complete calling experience with ringing functionality (incoming/outgoing call UI), follow the [Ringing](/calls/v4/android/ringing) guide first. Once the call is accepted, return here to start the call session.
</Note>

## Generate Call Token

A call token is required for secure access to a call session. Each token is unique to a specific session and user combination, ensuring that only authorized users can join the call.

You can generate the token just before starting the call, or generate and store it ahead of time based on your use case.

Use the `generateToken()` method to create a call token:

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    String sessionId = "" //Random or available in call obecjt in case of default calling
    String userAuthToken = CometChat.getUserAuthToken() //Logged in user auth token

    CometChatCalls.generateToken(sessionId, userAuthToken, new CometChatCalls.CallbackListener<GenerateToken>() {
        @Override
        public void onSuccess(GenerateToken generateToken) {

        }

        @Override
        public void onError(com.cometchat.pro.rtc.exceptions.CometChatException e) {

        }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val sessionId = "" //Random or available in call obecjt in case of default calling
    val userAuthToken = CometChat.getUserAuthToken() //Logged in user auth token

    CometChatCalls.generateToken(
        sessionId,
        userAuthToken,
        object : CometChatCalls.CallbackListener<GenerateToken>() {
            override fun onSuccess(generateToken: GenerateToken) {
                
            }

            override fun onError(e: CometChatException) {
              
            }
        }
    )
    ```
  </Tab>
</Tabs>

| Parameter       | Description                                                                                                                                |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `sessionId`     | The unique random session ID. In case you are using the ringing flow, the session ID is available in the `Call` object.                    |
| `userAuthToken` | The user auth token is the logged-in user auth token which you can get by calling CometChat Chat SDK method `CometChat.getUserAuthToken()` |

## Start Call Session

Use the `startSession()` method to join a call session. This method requires a call token (generated in the previous step) and a `CallSettings` object that configures the call UI and behavior.

The `CallSettings` class configures the call UI and behavior. Use `CallSettingsBuilder` to create a `CallSettings` instance with the following required parameters:

| Parameter         | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| `activityContext` | The activity context where the call UI will be displayed             |
| `videoContainer`  | A `RelativeLayout` where the calling UI will be rendered             |
| `callToken`       | The `GenerateToken` object received from `generateToken()` onSuccess |

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    RelativeLayout videoContainer = findViewById(R.id.video_container);
    Context activityContext = this;
    GenerateToken callToken; // Received from generateToken() onSuccess

    CallSettings callSettings = new CometChatCalls.CallSettingsBuilder(activityContext, videoContainer)
        .setDefaultLayoutEnable(true)
        .setIsAudioOnly(false)
        .build();

    CometChatCalls.startSession(callToken, callSettings, new CometChatCalls.CallbackListener<String>() {
        @Override
        public void onSuccess(String s) {
            // Call session started successfully
        }

        @Override
        public void onError(CometChatException e) {
            // Handle error
        }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val videoContainer: RelativeLayout = findViewById(R.id.video_container)
    val activityContext: Context = this
    val callToken: GenerateToken // Received from generateToken() onSuccess

    val callSettings = CometChatCalls.CallSettingsBuilder(activityContext, videoContainer)
        .setDefaultLayoutEnable(true)
        .setIsAudioOnly(false)
        .build()

    CometChatCalls.startSession(callToken, callSettings, object : CometChatCalls.CallbackListener<String> {
        override fun onSuccess(s: String) {
            // Call session started successfully
        }

        override fun onError(e: CometChatException) {
            // Handle error
        }
    })
    ```
  </Tab>
</Tabs>

### Call Settings

Configure the call experience using the following `CallSettingsBuilder` methods:

| Method                                                    | Description                                                                                                                                                                                        |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setDefaultLayoutEnable(boolean)`                         | Enables or disables the default call UI layout with built-in controls. `true` shows the default layout with end call, mute, video toggle buttons. `false` hides the button layout. Default: `true` |
| `setIsAudioOnly(boolean)`                                 | Sets whether the call is audio-only or audio-video. `true` for audio-only, `false` for audio-video. Default: `false`                                                                               |
| `setEventListener(CometChatCallsEventsListener)`          | Sets the listener to receive call events. See [Call Listeners](#call-listeners) for available callbacks.                                                                                           |
| `setMode(String)`                                         | Sets the call UI layout mode. Available: `MODE_DEFAULT` (grid), `MODE_SPOTLIGHT` (active speaker), `MODE_SINGLE` (one participant). Default: `MODE_DEFAULT`                                        |
| `setAvatarMode(String)`                                   | Sets how avatars are displayed when video is off. Available: `AVATAR_MODE_CIRCLE`, `AVATAR_MODE_SQUARE`, `AVATAR_MODE_FULLSCREEN`. Default: `AVATAR_MODE_CIRCLE`                                   |
| `setDefaultAudioMode(String)`                             | Sets the initial audio output device. Available: `AUDIO_MODE_SPEAKER`, `AUDIO_MODE_EARPIECE`, `AUDIO_MODE_BLUETOOTH`, `AUDIO_MODE_HEADPHONES`                                                      |
| `startWithAudioMuted(boolean)`                            | Starts the call with the microphone muted. Default: `false`                                                                                                                                        |
| `startWithVideoMuted(boolean)`                            | Starts the call with the camera turned off. Default: `false`                                                                                                                                       |
| `showEndCallButton(boolean)`                              | Shows or hides the end call button in the default layout. Default: `true`                                                                                                                          |
| `showSwitchCameraButton(boolean)`                         | Shows or hides the switch camera button (front/back). Default: `true`                                                                                                                              |
| `showMuteAudioButton(boolean)`                            | Shows or hides the mute audio button. Default: `true`                                                                                                                                              |
| `showPauseVideoButton(boolean)`                           | Shows or hides the pause video button. Default: `true`                                                                                                                                             |
| `showAudioModeButton(boolean)`                            | Shows or hides the audio mode selection button. Default: `true`                                                                                                                                    |
| `showSwitchToVideoCallButton(boolean)`                    | Shows or hides the button to upgrade an audio call to video. Default: `true`                                                                                                                       |
| `showRecordingButton(boolean)`                            | Shows or hides the recording button. Default: `false`                                                                                                                                              |
| `autoRecordOnCallStart(boolean)`                          | Automatically starts recording when the call begins. Default: `false`                                                                                                                              |
| `enableVideoTileClick(boolean)`                           | Enables or disables click interactions on video tiles in Spotlight mode. Default: `true`                                                                                                           |
| `enableVideoTileDrag(boolean)`                            | Enables or disables drag functionality for video tiles in Spotlight mode. Default: `true`                                                                                                          |
| `setMainVideoContainerSetting(MainVideoContainerSetting)` | Customizes the main video container. See [Video View Customization](/calls/v4/android/video-view-customisation).                                                                                   |
| `setIdleTimeoutPeriod(int)`                               | Sets idle timeout in seconds. Warning appears 60 seconds before auto-termination. Default: `180` seconds. *v4.1.0+*                                                                                |

## Call Listeners

The `CometChatCallsEventsListener` interface provides real-time callbacks for call session events, including participant changes, call state updates, and error conditions. Register this listener in any activity or fragment where you need to respond to call events.

Each listener requires a unique `listenerId` string. This ID is used to:

* **Prevent duplicate registrations** — Re-registering with the same ID replaces the existing listener
* **Enable targeted removal** — Remove specific listeners without affecting others

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    private String listenerId = "UNIQUE_LISTENER_ID";

    // Register listener (e.g., in onCreate or onResume)
    CometChatCalls.addCallsEventListeners(listenerId, new CometChatCallsEventsListener() {
        @Override
        public void onCallEnded() {

        }

        @Override
        public void onSessionTimeout() {

        }

        @Override
        public void onCallEndButtonPressed() {

        }

        @Override
        public void onUserJoined(RTCUser user) {

        }

        @Override
        public void onUserLeft(RTCUser user) {

        }

        @Override
        public void onUserListChanged(ArrayList<RTCUser> users) {

        }

        @Override
        public void onAudioModeChanged(ArrayList<AudioMode> devices) {

        }

        @Override
        public void onCallSwitchedToVideo(CallSwitchRequestInfo info) {

        }

        @Override
        public void onUserMuted(RTCMutedUser muteObj) {

        }

        @Override
        public void onRecordingToggled(RTCRecordingInfo info) {

        }

        @Override
        public void onError(CometChatException ce) {

        }
    });

    // Unregister listener (e.g., in onDestroy or onPause)
    CometChatCalls.removeCallsEventListeners(listenerId);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val listenerId = "UNIQUE_LISTENER_ID"

    // Register listener (e.g., in onCreate or onResume)
    CometChatCalls.addCallsEventListeners(listenerId, object: CometChatCallsEventsListener {
        override fun onCallEnded() {

        }

        override fun onSessionTimeout() {

        }

        override fun onCallEndButtonPressed() {

        }

        override fun onUserJoined(user: RTCUser) {

        }

        override fun onUserLeft(user: RTCUser) {

        }

        override fun onUserListChanged(users: ArrayList<RTCUser>) {

        }

        override fun onAudioModeChanged(devices: ArrayList<AudioMode?>?) {

        }

        override fun onCallSwitchedToVideo(info: CallSwitchRequestInfo) {

        }

        override fun onUserMuted(muteObj: RTCMutedUser) {

        }

        override fun onRecordingToggled(info: RTCRecordingInfo) {

        }

        override fun onError(ce: CometChatException?) {

        }
    })

    ```
  </Tab>
</Tabs>

### Events

| Event                                                | Description                                                                                                                                             |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onCallEnded()`                                      | Invoked when the call session terminates for a 1:1 call. Both participants receive this callback. Only fires for calls with exactly 2 participants.     |
| `onSessionTimeout()`                                 | Invoked when the call is auto-terminated due to inactivity (default: 180 seconds). Warning appears 60 seconds before. *v4.1.0+*                         |
| `onCallEndButtonPressed()`                           | Invoked when the local user taps the end call button. For ringing flow, call `CometChat.endCall()`. For standalone, call `CometChatCalls.endSession()`. |
| `onUserJoined(user: RTCUser)`                        | Invoked when a remote participant joins. The `user` contains UID, name, and avatar.                                                                     |
| `onUserLeft(user: RTCUser)`                          | Invoked when a remote participant leaves the call session.                                                                                              |
| `onUserListChanged(users: ArrayList<RTCUser>)`       | Invoked whenever the participant list changes (join or leave events).                                                                                   |
| `onAudioModeChanged(devices: ArrayList<AudioMode>)`  | Invoked when available audio devices change (e.g., Bluetooth connected).                                                                                |
| `onCallSwitchedToVideo(info: CallSwitchRequestInfo)` | Invoked when an audio call is upgraded to a video call.                                                                                                 |
| `onUserMuted(muteObj: RTCMutedUser)`                 | Invoked when a participant's mute state changes.                                                                                                        |
| `onRecordingToggled(info: RTCRecordingInfo)`         | Invoked when call recording starts or stops.                                                                                                            |
| `onError(e: CometChatException)`                     | Invoked when an error occurs during the call session.                                                                                                   |

## End Call Session

Ending a call session properly is essential to release media resources (camera, microphone, network connections) and update call state across all participants. The termination process differs based on whether you're using the Ringing flow or Session Only flow.

### Ringing Flow

When using the [Ringing](/calls/v4/android/ringing) flow, you must coordinate between the CometChat Chat SDK and the Calls SDK to properly terminate the call and notify all participants.

<Note>
  The Ringing flow requires calling methods from both the Chat SDK (`CometChat.endCall()`) and the Calls SDK (`CometChatCalls.endSession()`) to ensure proper call termination and participant notification.
</Note>

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/nUllIo1r4Bhce7kY/images/32c472fd-8kwm94f9vrtxx4kwytx9888yert62oyiy46r2bvkjqiopi2mxtmwihvlqia4pjng-b6de74bdd2156a31ce9bb1ed89ddfaa2.png?fit=max&auto=format&n=nUllIo1r4Bhce7kY&q=85&s=0e965973c4dfdd379cde6a1aad3d72a9" width="403" height="361" data-path="images/32c472fd-8kwm94f9vrtxx4kwytx9888yert62oyiy46r2bvkjqiopi2mxtmwihvlqia4pjng-b6de74bdd2156a31ce9bb1ed89ddfaa2.png" />
</Frame>

**User who initiates the end call:**

When the user presses the end call button in the UI, the `onCallEndButtonPressed()` callback is triggered. You must call `CometChat.endCall()` inside this callback to properly terminate the call and notify other participants. This triggers the `onCallEnded()` callback for the remote participant.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onCallEndButtonPressed() {
        CometChat.endCall(sessionId, new CometChat.CallbackListener<Call>() {
            @Override
            public void onSuccess(Call call) {
                // Call ended successfully, close the calling screen
            }

            @Override
            public void onError(CometChatException e) {
                Log.e(TAG, "Error ending call: " + e.getMessage());
            }
        });
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onCallEndButtonPressed() {
        CometChat.endCall(sessionId, object : CallbackListener<Call?>() {
            override fun onSuccess(call: Call?) {
                // Call ended successfully, close the calling screen
            }

            override fun onError(e: CometChatException) {
                Log.e(TAG, "Error ending call: ${e.message}")
            }
        })
    }
    ```
  </Tab>
</Tabs>

**Remote participant** (receives the `onCallEnded()` callback):

Call `CometChat.clearActiveCall()` to clear the local call state, then call `CometChatCalls.endSession()` to release media resources.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    // In onCallEnded() callback
    CometChat.clearActiveCall();
    CometChatCalls.endSession();
    // Close the calling screen
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // In onCallEnded() callback
    CometChat.clearActiveCall()
    CometChatCalls.endSession()
    // Close the calling screen
    ```
  </Tab>
</Tabs>

### Session Only Flow

When using the Session Only flow (direct call without ringing), you only need to call the Calls SDK method to end the session. There's no need to notify the Chat SDK since no call signaling was involved.

Call `CometChatCalls.endSession()` in the `onCallEndButtonPressed()` callback to release all media resources and disconnect from the call session.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    // In onCallEndButtonPressed() callback
    CometChatCalls.endSession();
    // Close the calling screen
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // In onCallEndButtonPressed() callback
    CometChatCalls.endSession()
    // Close the calling screen
    ```
  </Tab>
</Tabs>

## Methods

These methods are available for performing custom actions during an active call session. Use them to build custom UI controls or implement specific behaviors based on your use case.

<Note>
  These methods can only be called when a call session is active.
</Note>

### Switch Camera

Toggles between the front and rear camera during a video call. Useful for allowing users to switch their camera view without leaving the call.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.switchCamera();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.switchCamera()
    ```
  </Tab>
</Tabs>

### Mute Audio

Controls the local audio stream transmission. When muted, other participants cannot hear the local user.

* `true` — Mutes the microphone, stops transmitting audio
* `false` — Unmutes the microphone, resumes audio transmission

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.muteAudio(true);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.muteAudio(true)
    ```
  </Tab>
</Tabs>

### Pause Video

Controls the local video stream transmission. When paused, other participants see a frozen frame or avatar instead of live video.

* `true` — Pauses the camera, stops transmitting video
* `false` — Resumes the camera, continues video transmission

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.pauseVideo(true);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.pauseVideo(true)
    ```
  </Tab>
</Tabs>

### Set Audio Mode

Routes the audio output to a specific device. Use this to let users choose between speaker, earpiece, or connected audio devices.

**Available modes:**

* `CometChatCallsConstants.AUDIO_MODE_SPEAKER` — Device speaker (loudspeaker)
* `CometChatCallsConstants.AUDIO_MODE_EARPIECE` — Phone earpiece
* `CometChatCallsConstants.AUDIO_MODE_BLUETOOTH` — Connected Bluetooth device
* `CometChatCallsConstants.AUDIO_MODE_HEADPHONES` — Wired headphones

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    String audioMode = CometChatCallsConstants.AUDIO_MODE_EARPIECE;
    CometChatCalls.setAudioMode(audioMode);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val audioMode = CometChatCallsConstants.AUDIO_MODE_EARPIECE
    CometChatCalls.setAudioMode(audioMode)
    ```
  </Tab>
</Tabs>

### Enter PIP Mode

Enters Picture-in-Picture mode, rendering the call view in a small floating window. This allows users to multitask while staying on the call. Ensure your app has PIP support enabled in the manifest.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.enterPIPMode();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.enterPIPMode()
    ```
  </Tab>
</Tabs>

### Exit PIP Mode

Exits Picture-in-Picture mode and returns the call view to its original full-screen or embedded layout.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.exitPIPMode();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.exitPIPMode()
    ```
  </Tab>
</Tabs>

### Switch To Video Call

Upgrades an ongoing audio call to a video call. This enables the camera and starts transmitting video to other participants. The remote participant receives the `onCallSwitchedToVideo()` callback.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.switchToVideoCall();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.switchToVideoCall()
    ```
  </Tab>
</Tabs>

### Start Recording

Starts recording the call session. The recording is saved to the CometChat server and can be accessed later. All participants receive the `onRecordingToggled()` callback when recording starts.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.startRecording();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.startRecording()
    ```
  </Tab>
</Tabs>

### Stop Recording

Stops an ongoing call recording. All participants receive the `onRecordingToggled()` callback when recording stops.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.stopRecording();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.stopRecording()
    ```
  </Tab>
</Tabs>

### End Call

Terminates the current call session and releases all media resources (camera, microphone, network connections). After calling this method, the call view should be closed.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChatCalls.endSession();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChatCalls.endSession()
    ```
  </Tab>
</Tabs>
