Self-Managed ConnectionServices

The self-managed ConnectionService
API is ideal for developers of standalone calling apps which wish
to use their own custom user interface for their calls rather than relying
on the default Phone app. Using a self-managed ConnectionService helps you ensure that your app will
interoperate not only with native telephony calling on the device, but also
other standalone calling apps implementing this API. It also manages audio
routing and focus for you.

Calling Constraints

To ensure a consistent and simple calling experience for the user, the
Telecom framework enforces some constraints for calling on the device. For
example purposes, suppose the user has installed two calling apps which
implement the self-managed ConnectionService API,
FooTalk and BarTalk.

There can only be ongoing calls in any one calling app. This constraint
means the user may only be in calls in either FooTalk or BarTalk at any
one time. This does not mean the user cannot be in multiple FooTalk
calls, but that the user cannot be in both a FooTalk and BarTalk call at
the same time.

If the user is engaged in regular managed calls (for example, via the
built in Phone or Dialer app), the user may not be in calls originating
from self-managed apps. This means if the user is in a regular call
using their mobile carrier, they cannot also be in a FooTalk or BarTalk
call concurrently.

Your app's calls will be disconnected by Telecom if the user dials an
emergency call.

Your app may not receive or place calls while the user is in an
emergency call.

If there is an ongoing call in another calling app when your app
receives an incoming call, answering the incoming call will end any
ongoing calls in the other app. You app should not display its usual
incoming call user interface; the Telecom framework will display the
incoming call user interface and inform the user that answering the new
call will end their ongoing call(s). This means if the user is in a
FooTalk call and the BarTalk app receives an incoming call, the Telecom
framework will inform the user that they have a new incoming BarTalk
call and that answering the BarTalk call will end their FooTalk call.

Making use of the self-managed ConnectionService API
in your call flow involves interacting with the Telecom APIs. The following
sections describe common scenarios you will encounter, and how your app
should interact with and respond to the Telecom APIs.

Incoming Calls When There are No Calls in Other
Apps

This section describes how to handle an incoming call where none of the
constraints mentioned in Calling Constraints
apply. This means that there are no ongoing calls, or the only ongoing calls
are in your app.

Note: This is the first edition of the Self-Managed ConnectionService API.
Future enhancements are planned to remove some of these restrictions and to
add additional functionality such as the ability to write calls to the
system call log.

Incoming Call When There are Calls in Other Apps

This section describes how to handle an incoming call where there are ongoing
calls in another calling app. As mentioned in the calling
constraints, Telecom will display the incoming call UI for your
incoming call in this case.

Outgoing Calls

This section describes how your app should handle placing outgoing calls. As
mentioned in calling constraints, your app may or
may not be permitted to place an outgoing call at the current time. The
Telecom APIs will inform your app whether it can place an outgoing call.

onHold() - Telecom calls this method
when it wants to hold a call. In response to this, your app should hold
the call and then invoke setOnHold()
to inform Telecom that the call is held. Telecom may call this method
when a InCallService showing your call (Android
Auto, for example) wants to relay a user request to hold the call.

onUnhold() - Telecom calls this
method when it wants to unhold a call. Once your app has unheld the
call, it should invoke setActive() to
inform Telecom that the call is no longer held. Telecom may call this
method when a InCallService showing your call
(Android Auto, for example) wants to relay a user request to unhold the
call.

onAnswer(int) and onAnswer() - Telecom calls this method to
inform your app that an incoming call should be answered. Once your app
has answered the call, it should invoke setActive() to inform Telecom that the call
has been answered. Telecom may call this method when your app adds a new
incoming call and there is already an ongoing call in another app. As
discussed previously, Telecom will display the incoming call UI on
behalf of your app in these instances.

onDisconnect() - Telecom calls this
method when it wants to disconnect a call. Once the call has ended, your
app should call setDisconnected(android.telecom.DisconnectCause)
and specify LOCAL to indicate
that a user request caused the call to be disconected. Your app should
then call destroy() to inform Telecom
you are done with the call. Telecom may call this method when the user
has disconnected a call through another InCallService such as Android Auto.