CallsManager


@RequiresApi(value = 26)
class CallsManager : CallsManagerExtensions


CallsManager allows VoIP applications to add their calls to the Android system service Telecom. By doing this, other services are aware of your VoIP application calls which leads to a more stable environment. For example, a wearable may be able to answer an incoming call from your application if the call is added to the Telecom system. VoIP applications that manage calls and do not inform the Telecom system may experience issues with resources (ex. microphone access).

Note that access to some telecom information is permission-protected. Your app cannot access the protected information or gain access to protected functionality unless it has the appropriate permissions declared in its manifest file. Where permissions apply, they are noted in the method descriptions.

Summary

Constants

const Int

If your VoIP application does not want support any of the capabilities below, then your application can register with CAPABILITY_BASELINE.

const Int

Flag indicating that this VoIP application supports call streaming.

const Int

Flag indicating that your VoIP application supports video calling.

Public constructors

Public functions

suspend Unit
@RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
addCall(
    callAttributes: CallAttributesCompat,
    onAnswer: suspend (callType: Int) -> Unit,
    onDisconnect: suspend (disconnectCause: DisconnectCause) -> Unit,
    onSetActive: suspend () -> Unit,
    onSetInactive: suspend () -> Unit,
    block: CallControlScope.() -> Unit
)

Adds a new call with the specified CallAttributesCompat to the telecom service.

open suspend Unit
@ExperimentalAppActions
addCallWithExtensions(
    callAttributes: CallAttributesCompat,
    onAnswer: suspend (callType: Int) -> Unit,
    onDisconnect: suspend (disconnectCause: DisconnectCause) -> Unit,
    onSetActive: suspend () -> Unit,
    onSetInactive: suspend () -> Unit,
    init: suspend ExtensionInitializationScope.() -> Unit
)

Adds a call with extensions support, which allows an app to implement optional additional actions that go beyond the scope of a call, such as information about meeting participants and icons.

Flow<List<CallEndpointCompat>>

Continuously stream the available call audio endpoints that can be used for a new call session.

Unit
@RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
registerAppWithTelecom(capabilities: Int)

VoIP applications should look at each Capability annotated above and call this API in order to start adding calls via addCall.

Constants

CAPABILITY_BASELINE

const val CAPABILITY_BASELINEInt

If your VoIP application does not want support any of the capabilities below, then your application can register with CAPABILITY_BASELINE.

Note: Calls can still be added and to the Telecom system but if other services request to perform a capability that is not supported by your application, Telecom will notify the service of the inability to perform the action instead of hitting an error.

CAPABILITY_SUPPORTS_CALL_STREAMING

const val CAPABILITY_SUPPORTS_CALL_STREAMINGInt

Flag indicating that this VoIP application supports call streaming. Call streaming means a call can be streamed from a root device to another device to continue the call without completely transferring it. The call continues to take place on the source device, however media and control are streamed to another device. androidx.core.telecom.CallAttributesCompat.CallType#CAPABILITY_SUPPORTS_CALL_STREAMING must also be set on per call basis in the event an application wants to gate this capability on a stricter basis.

CAPABILITY_SUPPORTS_VIDEO_CALLING

const val CAPABILITY_SUPPORTS_VIDEO_CALLINGInt

Flag indicating that your VoIP application supports video calling. This is not an indication that your application is currently able to make a video call, but rather that it has the ability to make video calls (but not necessarily at this time).

Whether a call can make a video call is ultimately controlled by androidx.core.telecom.CallAttributesCompats capability androidx.core.telecom.CallAttributesCompat.CallType#CALL_TYPE_VIDEO_CALL, which indicates that particular call is currently capable of making a video call.

Public constructors

CallsManager

Added in 1.0.0-beta01
CallsManager(context: Context)

Public functions

addCall

Added in 1.0.0-beta01
@RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
suspend fun addCall(
    callAttributes: CallAttributesCompat,
    onAnswer: suspend (callType: Int) -> Unit,
    onDisconnect: suspend (disconnectCause: DisconnectCause) -> Unit,
    onSetActive: suspend () -> Unit,
    onSetInactive: suspend () -> Unit,
    block: CallControlScope.() -> Unit
): Unit

Adds a new call with the specified CallAttributesCompat to the telecom service. This method can be used to add both incoming and outgoing calls. Once the call is ready to be disconnected, use the CallControlScope.disconnect.

Call Lifecycle: Your app is given foreground execution priority as long as you have an ongoing call and are posting a android.app.Notification.CallStyle notification within 5 seconds of adding the call via this method. When your application is given foreground execution priority, your app is treated as a foreground service. Foreground execution priority will prevent the android.app.ActivityManager from killing your application when it is placed the background. Foreground execution priority is removed from your app when all of your app's calls terminate or your app no longer posts a valid notification.

  • Other things that should be noted:

    • For outgoing calls, your application should either immediately post a android.app.Notification.CallStyle notification or delay adding the call via this addCall method until the remote side is ready.

    • addCall will NOT complete until the call session has ended. Instead, the addCall block, which is called the CallControlScope, will run once the call has been added. Do not put addCall in a function expecting it to return or add logic after the addCall request that is important for the call session.

    • Each lambda function (onAnswer, onDisconnect, onSetActive, onSetInactive) will be invoked by Telecom whenever the system needs your VoIP application to change the call state. For example, if there is an ongoing VoIP call in your application and the system receives a sim call, Telecom will invoke onSetInactive to place your call on hold/inactive if the user answers the incoming sim call. These events may not occur during most calls but should still be implemented in the event Telecom needs to manipulate your applications call state.

    • Each lambda function (onAnswer, onDisconnect, onSetActive, onSetInactive) has a timeout of 5000 milliseconds. Failing to complete the suspend fun before the timeout will result in a failed transaction.

    • Telecom assumes each callback (onAnswer, onDisconnect, onSetActive, onSetInactive) is handled successfully on the client side. If the callback cannot be completed, an Exception should be thrown. Telecom will rethrow the Exception and tear down the call session.

Parameters
callAttributes: CallAttributesCompat

attributes of the new call (incoming or outgoing, address, etc. )

onAnswer: suspend (callType: Int) -> Unit

where callType is the audio/video state the call should be answered as. Telecom is informing your VoIP application to answer an incoming call and set it to active. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).

onDisconnect: suspend (disconnectCause: DisconnectCause) -> Unit

where disconnectCause represents the cause for disconnecting the call. Telecom is informing your VoIP application to disconnect the incoming call. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).

onSetActive: suspend () -> Unit

Telecom is informing your VoIP application to set the call active. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).

onSetInactive: suspend () -> Unit

Telecom is informing your VoIP application to set the call inactive. This is the same as holding a call for two endpoints but can be extended to setting a meeting inactive. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g.Wearable). Note: Your app must stop using the microphone and playing incoming media when returning.

block: CallControlScope.() -> Unit

DSL interface block that will run when the call is ready

Throws
kotlin.UnsupportedOperationException

if the device is on an invalid build

android.telecom.CallException

if the platform cannot add the call (e.g. reached max # of calls) or failed with an exception (e.g. call was already removed)

androidx.core.telecom.CallException.Companion.ERROR_OPERATION_TIMED_OUT

if the call failed to be added within 5000 milliseconds

addCallWithExtensions

Added in 1.0.0-beta01
@ExperimentalAppActions
open suspend fun addCallWithExtensions(
    callAttributes: CallAttributesCompat,
    onAnswer: suspend (callType: Int) -> Unit,
    onDisconnect: suspend (disconnectCause: DisconnectCause) -> Unit,
    onSetActive: suspend () -> Unit,
    onSetInactive: suspend () -> Unit,
    init: suspend ExtensionInitializationScope.() -> Unit
): Unit

Adds a call with extensions support, which allows an app to implement optional additional actions that go beyond the scope of a call, such as information about meeting participants and icons.

Parameters
callAttributes: CallAttributesCompat

attributes of the new call (incoming or outgoing, address, etc. )

onAnswer: suspend (callType: Int) -> Unit

where callType is the audio/video state the call should be answered as. Telecom is informing your VoIP application to answer an incoming call and set it to active. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).

onDisconnect: suspend (disconnectCause: DisconnectCause) -> Unit

where disconnectCause represents the cause for disconnecting the call. Telecom is informing your VoIP application to disconnect the incoming call. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).

onSetActive: suspend () -> Unit

Telecom is informing your VoIP application to set the call active. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).

onSetInactive: suspend () -> Unit

Telecom is informing your VoIP application to set the call inactive. This is the same as holding a call for two endpoints but can be extended to setting a meeting inactive. Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g.Wearable). Note: Your app must stop using the microphone and playing incoming media when returning.

init: suspend ExtensionInitializationScope.() -> Unit

The scope used to first initialize Extensions that will be used when the call is first notified to the platform and UX surfaces. Once the call is set up, the user's implementation of ExtensionInitializationScope.onCall will be called.

getAvailableStartingCallEndpoints

Added in 1.0.0-beta01
fun getAvailableStartingCallEndpoints(): Flow<List<CallEndpointCompat>>

Continuously stream the available call audio endpoints that can be used for a new call session. The callbackFlow should be cleaned up client-side by calling cancel() from the same kotlinx.coroutines.CoroutineScope the callbackFlow is collecting in.

Note: The endpoints emitted will be sorted by the CallEndpointCompat.type . See CallEndpointCompat.compareTo for the ordering. The first element in the list will be the recommended call endpoint to default to for the user.

Returns
Flow<List<CallEndpointCompat>>

a flow of CallEndpointCompats that can be used for a new call session

registerAppWithTelecom

Added in 1.0.0-beta01
@RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
fun registerAppWithTelecom(capabilities: Int): Unit

VoIP applications should look at each Capability annotated above and call this API in order to start adding calls via addCall. Registering capabilities must be done before calling addCall or an exception will be thrown by addCall. The capabilities can be updated by re-registering.

Note: There is no need to unregister at any point. Telecom will handle unregistering once the application using core-telecom has been removed from the device.

Throws
kotlin.UnsupportedOperationException

if the device is on an invalid build