# CallControlScope

Artifact: [androidx.core:core-telecom](https://developer.android.com/jetpack/androidx/releases/core) [View Source](https://cs.android.com/search?q=file:androidx/core/telecom/CallControlScope.kt+class:androidx.core.telecom.CallControlScope) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/core#1.0.0)

*** ** * ** ***


```
public interface CallControlScope extends CoroutineScope
```

<br />

*** ** * ** ***

DSL interface to provide and receive updates about a call session. The CallControlScope should be used to provide updates (via the CallControlScope suspend functions) and receive updates (via the lambda functions) about the call. The CallControlScope will run for the duration of the call. To see an example implementation of the CallControlScope, please refer to the sample app on [github.](https://github.com/android/platform-samples/blob/3856087f7f0fa4901e521f1dc79a30ddfd108f4e/samples/connectivity/telecom/src/main/java/com/example/platform/connectivity/telecom/model/TelecomCallRepository.kt#L122)

Example usage:

// initiate a call and control via the CallControlScope mCallsManager.addCall( callAttributes, onAnswerLambda, onDisconnectLambda, onSetActiveLambda, onSetInActiveLambda ) { // This block represents the CallControlScope. Once Telecom has added the call to the // system, your application can start changing the call state (via setActive(), etc.), // collect the flows.

```
    // Your application should gate ALL CallControlScope suspend functions with UI logic or
    // logic that signals the call state is ready to be changed
    launch {
           when (val res = setActive() ) {
             is CallControlResult.Success -> {
               // Telecom can place the active
               // update your call state and handle UI
             }
             is CallControlResult.Error -> {
               // Telecom cannot set your VoIP call active. Maybe there is an ongoing
               // active call that cannot be held. Check the failure code to determine the
               // recommended next action
               handleErrorCode( res.errorCode )
             }
            }
          }
     }
    // Collect updates
    launch {
       currentCallEndpoint.collect { // access the new [CallEndpoint] here }
    }
    launch {
       availableEndpoints.collect { // access the available [CallEndpoint]s here }
    }
    launch {
       isMuted.collect { // access to the mute state }
    }
}
```

**Note:** Each `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html` must be wrapped in an individual launch block or the `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html` will not be collected.

## Summary

| ### Public methods |
|---|---|
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#answer(kotlin.Int)(int callType)` Inform Telecom that your app wants to make this incoming call active. |
| `default @https://developer.android.com/reference/androidx/annotation/NonNull https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html<@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/java/lang/Integer.html>` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#callTypeFlow()()` Returns a `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html` that emits the current call type state and subsequent updates. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#disconnect(android.telecom.DisconnectCause)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/android/telecom/DisconnectCause.html disconnectCause)` Inform Telecom that your app wishes to disconnect the call and remove the call from telecom tracking. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html<@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/java/util/List.html<@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat>>` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#getAvailableEndpoints()()` Collect the set of available `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat`s reported by Telecom. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/android/os/ParcelUuid.html` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#getCallId()()` |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html<@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat>` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#getCurrentCallEndpoint()()` Collect the new `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat` through which call media flows (i.e. speaker, bluetooth, etc.). |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html<@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/java/lang/Boolean.html>` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#isMuted()()` Collect the current mute state of the call. |
| `default @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#requestCallType(kotlin.Int)(int callType)` Requests a change to the call type for the current call. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#requestEndpointChange(androidx.core.telecom.CallEndpointCompat)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat endpoint)` Request a `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat` change. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#setActive()()` Inform Telecom that your app wants to make this call active. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#setInactive()()` Inform Telecom that your app wants to make this call inactive. |

### Inherited methods

From [kotlinx.coroutines.CoroutineScope](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/index.html) `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.coroutines/-coroutine-context/index.html` `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/get-coroutine-context.html()`

## Public methods

### answer

```
abstract @NonNull CallControlResult answer(int callType)
```

Inform Telecom that your app wants to make this incoming call active. For outgoing calls and calls that have been placed on hold, use `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#setActive()`.

| Parameters |
|---|---|
| `int callType` | that call is to be answered as. Value is one of the following: - `1` - `2` <br /> |

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | Telecom will return `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Success` if your app is able to answer the call. Otherwise `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Error` will be returned with an error code indicating why answer failed (ex. another call is active and telecom cannot set this call active until the other call is held or disconnected). This means that your app cannot answer this call at this time. |

### callTypeFlow

Added in [1.1.0](https://developer.android.com/jetpack/androidx/releases/core#1.1.0)

```
default @NonNull Flow<@NonNull Integer> callTypeFlow()
```

Returns a `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html` that emits the current call type state and subsequent updates.

The emitted values are integers corresponding to the constants defined in `https://developer.android.com/reference/androidx/core/telecom/CallAttributesCompat.Companion.CallType`, such as `https://developer.android.com/reference/androidx/core/telecom/CallAttributesCompat#CALL_TYPE_AUDIO_CALL()` or `https://developer.android.com/reference/androidx/core/telecom/CallAttributesCompat#CALL_TYPE_VIDEO_CALL()`.

Upon collection, the `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html` will emit the current call type state immediately, and then emit new values whenever the call type changes (e.g., from audio to video). This is a cold Flow; emissions start only when the Flow is collected.

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html<@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/java/lang/Integer.html>` | A `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html` of `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` representing the current call type state. Collectors will receive the latest state and any changes thereafter. |

### disconnect

```
abstract @NonNull CallControlResult disconnect(@NonNull DisconnectCause disconnectCause)
```

Inform Telecom that your app wishes to disconnect the call and remove the call from telecom tracking.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/android/telecom/DisconnectCause.html disconnectCause` | represents the cause for disconnecting the call. The only valid codes for the `https://developer.android.com/reference/android/telecom/DisconnectCause.html` passed in are: - DisconnectCause#LOCAL - DisconnectCause#REMOTE - DisconnectCause#REJECTED - DisconnectCause#MISSED - DisconnectCause#ERROR (Starting in SDK 38, you can report this new ERROR option. You should report DisconnectCause#ERROR if the call terminated unexpectedly due to an error in your app (for example bad network connection, server error or a media error). On devices running SDK versions less than 38, DisconnectCause#ERROR will be automatically remapped to DisconnectCause#LOCAL.) <br /> |

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Success` will be returned if Telecom is able to disconnect the call successfully. Otherwise `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Error` will be returned with an error code indicating why disconnect failed. |

### getAvailableEndpoints

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/core#1.0.0)

```
abstract @NonNull Flow<@NonNull List<@NonNull CallEndpointCompat>> getAvailableEndpoints()
```

Collect the set of available `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat`s reported by Telecom.

### getCallId

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/core#1.0.0)

```
abstract @NonNull ParcelUuid getCallId()
```

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/android/os/ParcelUuid.html` | the 128-bit universally unique identifier Telecom assigned to this CallControlScope. This id can be helpful for debugging when dumping the telecom system. |

### getCurrentCallEndpoint

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/core#1.0.0)

```
abstract @NonNull Flow<@NonNull CallEndpointCompat> getCurrentCallEndpoint()
```

Collect the new `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat` through which call media flows (i.e. speaker, bluetooth, etc.).

### isMuted

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/core#1.0.0)

```
abstract @NonNull Flow<@NonNull Boolean> isMuted()
```

Collect the current mute state of the call. This Flow is updated every time the mute state changes.

### requestCallType

```
default @NonNull CallControlResult requestCallType(int callType)
```

Requests a change to the call type for the current call.

Use this method to transition the call between different states, for example, to upgrade an audio-only call to a video call, or downgrade a video call to audio-only.

| Parameters |
|---|---|
| `int callType` | The desired call type for the call. This must be one of the integer constants defined in `https://developer.android.com/reference/androidx/core/telecom/CallAttributesCompat.Companion.CallType`, such as `https://developer.android.com/reference/androidx/core/telecom/CallAttributesCompat#CALL_TYPE_AUDIO_CALL()` or `https://developer.android.com/reference/androidx/core/telecom/CallAttributesCompat#CALL_TYPE_VIDEO_CALL()`. |

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | A `https://developer.android.com/reference/androidx/core/telecom/CallControlResult` indicating the outcome of the request: - `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Success`: The request to change the call type was successfully processed by the Telecom framework. - `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Error`: The request failed. The specific reason for the failure can be determined by the error code within the `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Error` |

### requestEndpointChange

```
abstract @NonNull CallControlResult requestEndpointChange(@NonNull CallEndpointCompat endpoint)
```

Request a `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat` change. Clients should not define their own `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat` when requesting a change. Instead, the new `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#requestEndpointChange(androidx.core.telecom.CallEndpointCompat)` should be one of the valid `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat`s provided by `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#availableEndpoints()`.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat endpoint` | The `https://developer.android.com/reference/androidx/core/telecom/CallEndpointCompat` to change to. |

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Success` will be returned if Telecom is able to switch to the requested endpoint successfully. Otherwise, `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Error` will be returned with an error code indicating why disconnect failed. |

### setActive

```
abstract @NonNull CallControlResult setActive()
```

Inform Telecom that your app wants to make this call active. This method should be called when either an outgoing call is ready to go active or a held call is ready to go active again. For incoming calls that are ready to be answered, use `https://developer.android.com/reference/androidx/core/telecom/CallControlScope#answer(kotlin.Int)`.

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | Telecom will return `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Success` if your app is able to set the call active. Otherwise `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Error` will be returned (ex. another call is active and telecom cannot set this call active until the other call is held or disconnected) with an error code indicating why setActive failed. |

### setInactive

```
abstract @NonNull CallControlResult setInactive()
```

Inform Telecom that your app wants to make this call inactive. This the same as hold for two call endpoints but can be extended to setting a meeting to inactive.

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/core/telecom/CallControlResult` | Telecom will return `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Success` if your app is able to set the call inactive. Otherwise, `https://developer.android.com/reference/androidx/core/telecom/CallControlResult.Error` will be returned with an error code indicating why setInActive failed. |