Package com.tomtom.ivi.platform.telecom.api.service.telecom

The telecom service API package.

Telecom service

The telecom service is an IVI service and is the service used for managing the incoming and outgoing TelecomService.currentCalls from connected phones. The TelecomService can manage multiple ongoing calls at the same time, but only one call is active at a time while the others are put on hold. A call can be answered, rejected, put on hold, ended, initiated, muted or a DTMF (Dual Tone Multi Frequency) tone can be sent to it. The telecom service also provides the TelecomService.isMuted state of the microphone. Clients (frontend's) can use these actions to handle calls in a telecom application on the IVI system, including notifications and ongoing calls shown in the main process panel.

Overview of the telecom service

The communications frontend communicates with the TelecomService and through it the frontend is able to accept or reject incoming calls and end active calls. The TelecomService.currentCalls property provides all the currently ongoing calls. The TelecomService.isMuted property provides the muted state.

The TelecomManagementService creates a link between the TelecomService and the IviInCallService, which is a system service to handle incoming and outgoing calls for all registered ConnectionServices.

TelecomServiceImage

The telecom service API documentation

The telecom service provides the following functionality:

  1. #using-telecom-service-api.

  2. MicrophoneMutedStateRef.

  3. CallsListRef.

  4. #managing-incoming-calls.

  5. #initiating-calls.

  6. #managing-ongoing-calls.

Using telecom service API

To use the telecom service, add a dependency to the TelecomService to your gradle file:

dependencies {
implementation("com.tomtom.ivi.platform:platform_telecom_api_service_telecom")
}

To get access to the TelecomService API, you need to first get a TelecomServiceApi instance by calling the companion function TelecomService.createApi(...).

val telecomService = TelecomService.createApi(lifecycleOwner, iviServiceProvider)

Once you have a TelecomServiceApi instance, you can use it to call any API, and observe any property provided by the service.

Note: The service may not be ready when a client calls the service API and could return a SERVICE_UNAVAILABLE result. It is possible to check the service availability by observing the serviceAvailable property:

telecomService.serviceAvailable.observe(lifecycleOwner) {
if (it) {
// Service is available
} else {
// Service is not available
}
}

Microphone muted state

It is possible to get the actual muted state of the microphone as indicated by the system with the TelecomService.isMuted property. In the following example, a different icon is retrieved depending on the state of the muted state:

val microphoneMutedIcon = telecomService.isMuted.map {
// Returns the icon according to the microphone muted state
}

Calls list

It is possible to get an updated list of current calls by observing the TelecomService.currentCalls property. In the following example, the calls are filtered to get a list of calls in a specific state:

val activeCalls = telecomService.currentCalls.map {
// Filter the list of calls to get the calls that are in the ACTIVE state.
}

The list activeCalls is updated continuously with the calls whose state is set to ACTIVE.

Note:Calls that are in the CallState.DISCONNECTED state will be removed imminently. These only reside in the list long enough to update the frontend with the Call.disconnectedCause.

Managing incoming calls

Answering a call

You can answer a call by calling answerCallAsync (asynchronous) or coAnswerCall (synchronous) function with the specified CallId. A CallId is provided for each call in the TelecomService.currentCalls property. In the following example, a call is answered asynchronously:

val incomingCalls = calls.map { it.filter { CallState.RINGING == call.state } }

incomingCalls.firstOrNull()?.let { telecomServiceApi.answerCallAsync(it) }

Note: A call needs to be in the CallState.RINGING state to be answered. When answering a call its state will be immediately changed to CallState.ANSWERING after which it will either go to CallState.ACTIVE or CallState.DISCONNECTED.

Rejecting a call

You can reject a call by calling rejectCallAsync (asynchronous) or coRejectCall (synchronous) function with the specified CallId. A CallId is provided for each call in the TelecomService.currentCalls property. In the following example, a call is rejected asynchronously:

call.value?.id?.let { telecomServiceApi.rejectCallAsync(it) }

Note: When rejecting a call its state will change to CallState.DISCONNECTED and Call.disconnectedCause will reflect the reason for disconnection to be DisconnectCause.REJECTED.

Initiating calls

You can initiate a call by calling initiateCallAsync (asynchronous) or coInitiateCall (synchronous) function with the specified Uri. Then a new call will be added to the TelecomService.currentCalls property. When the call starts it will use the default phone provided by Android. In the following example, a call is initiated asynchronously where the phone number is given as part of the URI:

val uri = 'tel://+123456789'

telecomServiceApi.initiateCallAsync(uri)

Note: If placing the call fails, the Call.disconnectedCause on the call will be set to the appropriate value.

Managing ongoing calls

Setting a call on hold

You can set an active call on hold by calling setCallOnHoldAsync (asynchronous) or coSetCallOnHold (synchronous) function with the specified CallId and onHold value. A CallId is provided for each call in the TelecomService.currentCalls property. The onHold is set to 'true' to put the call on hold, 'false' to take out of hold. In the following example, a call is set on hold asynchronously:

val activeCalls = calls.map { it.filter { CallState.ACTIVE == call.state } }

activeCalls.firstOrNull()?.let { telecomServiceApi.setCallOnHoldAsync(it, true) }

Note: If onHold is 'true' and the call is in the CallState.ACTIVE state it will be changed to the CallState.HOLDING state. If onHold is 'false' and the call is in the CallState.HOLDING state it will be changed to the CallState.ACTIVE state. Otherwise this call is ignored.

Ending a call

You can end a call by calling endCallAsync (asynchronous) or coEndCall (synchronous) function with the specified CallId. A CallId is provided for each call in the TelecomService.currentCalls property. In the following example, a call is ended asynchronously:

call.value?.id?.let { telecomServiceApi.endCallAsync(it) }

Note: Ending a call will change its state to CallState.DISCONNECTING after which it will go to CallState.DISCONNECTED and Call.disconnectedCause will reflect the reason it was disconnected to be DisconnectCause.LOCAL.

Playing DTMF tones

You can send a DTMF (Dual Tone Multi Frequency) code to a call by calling playDtmfToneAsync (asynchronous) or coPlayDtmfTone (synchronous) function with the specified CallId and dtmfCode. A CallId is provided for each call in the TelecomService.currentCalls property. The dtmfCode is an ASCII code. In the following example, a dtmf is sent asynchronously with a numeric code:

call.value?.id?.let { telecomServiceApi.playDtmfToneAsync(it, '3') }

Note: If no call exists with the specified callId or dtmfCode is something else than the specified possible values, this call has no effect.

Setting the microphone muted state

You can set the muted state of the microphone by calling setMutedAsync (asynchronous) or coSetMuted (synchronous) function with the specified muted value. muted can be set to 'true' to mute the microphone or to false to unmute it. In the following example, the microphone is muted asynchronously:

telecomService.setMutedAsync(true)

External links

Types

Link copied to clipboard
interface TelecomService

Service responsible for making and receiving calls.