Improve Self-Managed ConnectionService API docs.

Provide a basic outline of what an app needs to do in order to implement
a self-managed ConnectionService in the class API docs.

Bug: 233932114
Fixes: 235651290
Test: Viewed generated javadoc.
Change-Id: Ibc42d6b75e843c6eb5385bb318d45af58cf8d08a
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 4d6caf8..9e4e5fa 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -79,19 +79,240 @@
  * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
  * <p>
  * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
- * before Telecom will bind to them.  Self-managed {@link ConnectionService}s must be granted the
- * appropriate permission before Telecom will bind to them.
+ * before Telecom will bind to them.  Self-managed {@link ConnectionService}s must declare the
+ * {@link android.Manifest.permission#MANAGE_OWN_CALLS} permission in their manifest before Telecom
+ * will bind to them.
  * <p>
  * Once registered and enabled by the user in the phone app settings or granted permission, telecom
  * will bind to a {@link ConnectionService} implementation when it wants that
  * {@link ConnectionService} to place a call or the service has indicated that is has an incoming
- * call through {@link TelecomManager#addNewIncomingCall}. The {@link ConnectionService} can then
- * expect a call to {@link #onCreateIncomingConnection} or {@link #onCreateOutgoingConnection}
+ * call through {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}. The
+ * {@link ConnectionService} can then expect a call to
+ * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)} or
+ * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
  * wherein it should provide a new instance of a {@link Connection} object.  It is through this
  * {@link Connection} object that telecom receives state updates and the {@link ConnectionService}
  * receives call-commands such as answer, reject, hold and disconnect.
  * <p>
  * When there are no more live calls, telecom will unbind from the {@link ConnectionService}.
+ * <p>
+ * <h1>Self-Managed Connection Services</h1>
+ * A VoIP app can implement a {@link ConnectionService} to ensure that its calls are integrated
+ * into the Android platform.  There are numerous benefits to using the Telecom APIs for a VoIP app:
+ * <ul>
+ *     <li>Call concurrency is handled - the user is able to swap between calls in different
+ *     apps and on the mobile network.</li>
+ *     <li>Simplified audio routing - the platform provides your app with a unified list of the
+ *     audio routes which are available
+ *     (e.g. {@link android.telecom.Connection#onAvailableCallEndpointsChanged(List)}) and a
+ *     standardized way to switch audio routes
+ *     (e.g. {@link android.telecom.Connection#requestCallEndpointChange(CallEndpoint, Executor,
+ *     OutcomeReceiver)} ).</li>
+ *     <li>Bluetooth integration - your calls will be visible on and controllable via
+ *     bluetooth devices (e.g. car head units and headsets).</li>
+ *     <li>Companion device integration - wearable devices such as watches which implement an
+ *     {@link InCallService} can optionally subscribe to see self-managed calls.  Similar to a
+ *     bluetooth headunit, wearables will typically render your call using a generic call UX and
+ *     provide the user with basic call controls such as hangup, answer, reject.</li>
+ *     <li>Automotive calling experiences - Android supports automotive optimized experiences which
+ *     provides a means for calls to be controlled and viewed in an automobile; these experiences
+ *     are capable of leveraging call metadata provided by your app.</li>
+ * </ul>
+ * <h2>Registering a Phone Account</h2>
+ * Before your app can handle incoming or outgoing calls through Telecom it needs to register a
+ * {@link PhoneAccount} with Telecom indicating to the platform that your app is capable of calling.
+ * <p>
+ * Your app should create a new instance of {@link PhoneAccount} which meets the following
+ * requirements:
+ * <ul>
+ *     <li>Has {@link PhoneAccount#CAPABILITY_SELF_MANAGED} (set using
+ *     {@link PhoneAccount.Builder#setCapabilities(int)}).  This indicates to Telecom that your
+ *     app will report calls but that it provides a primary UI for the calls by itself.</li>
+ *     <li>Provide a unique identifier for the {@link PhoneAccount} via the
+ *     {@link PhoneAccountHandle#getId()} attribute.  As per the {@link PhoneAccountHandle}
+ *     documentation, you should NOT use an identifier which contains PII or other sensitive
+ *     information.  A typical choice is a UUID.</li>
+ * </ul>
+ * Your app should register the new {@link PhoneAccount} with Telecom using
+ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}.  {@link PhoneAccount}s persist across
+ * reboot.  You can use {@link TelecomManager#getOwnSelfManagedPhoneAccounts()} to confirm the
+ * {@link PhoneAccount} you registered.  Your app should generally only register a single
+ * {@link PhoneAccount}.
+ *
+ * <h2>Implementing ConnectionService</h2>
+ * Your app uses {@link TelecomManager#placeCall(Uri, Bundle)} to start new outgoing calls and
+ * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)} to report new incoming
+ * calls.  Calling these APIs causes the Telecom stack to bind to your app's
+ * {@link ConnectionService} implementation.  Telecom will either inform your app that it cannot
+ * handle a call request at the current time (i.e. there could be an ongoing emergency call, which
+ * means your app is not allowed to handle calls at the current time), or it will ask your app to
+ * create a new instance of {@link Connection} to represent a call in your app.
+ *
+ * Your app should implement the following {@link ConnectionService} methods:
+ * <ul>
+ *     <li>{@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to ask your app to make a new {@link Connection}
+ *     to represent an outgoing call your app requested via
+ *     {@link TelecomManager#placeCall(Uri, Bundle)}.</li>
+ *     <li><{@link ConnectionService#onCreateOutgoingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to inform your app that a call it reported via
+ *     {@link TelecomManager#placeCall(Uri, Bundle)} cannot be handled at this time.  Your app
+ *     should NOT place a call at the current time.</li>
+ *     <li>{@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to ask your app to make a new {@link Connection}
+ *     to represent an incoming call your app reported via
+ *     {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}.</li>
+ *     <li>{@link ConnectionService#onCreateIncomingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to inform your app that an incoming call it reported
+ *     via {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)} cannot be handled
+ *     at this time.  Your app should NOT post a new incoming call notification and should silently
+ *     reject the call.</li>
+ * </ul>
+ *
+ * <h2>Implementing a Connection</h2>
+ * Your app should extend the {@link Connection} class to represent calls in your app.  When you
+ * create new instances of your {@link Connection}, you should ensure the following properties are
+ * set on the new {@link Connection} instance returned by your {@link ConnectionService}:
+ * <ul>
+ *     <li>{@link Connection#setAddress(Uri, int)} - the identifier for the other party.  For
+ *     apps that user phone numbers the {@link Uri} can be a {@link PhoneAccount#SCHEME_TEL} URI
+ *     representing the phone number.</li>
+ *     <li>{@link Connection#setCallerDisplayName(String, int)} - the display name of the other
+ *     party.  This is what will be shown on Bluetooth devices and other calling surfaces such
+ *     as wearable devices.  This is particularly important for calls that do not use a phone
+ *     number to identify the caller or called party.</li>
+ *     <li>{@link Connection#setConnectionProperties(int)} - ensure you set
+ *     {@link Connection#PROPERTY_SELF_MANAGED} to identify to the platform that the call is
+ *     handled by your app.</li>
+ *     <li>{@link Connection#setConnectionCapabilities(int)} - if your app supports making calls
+ *     inactive (i.e. holding calls) you should get {@link Connection#CAPABILITY_SUPPORT_HOLD} and
+ *     {@link Connection#CAPABILITY_HOLD} to indicate to the platform that you calls can potentially
+ *     be held for concurrent calling scenarios.</li>
+ *     <li>{@link Connection#setAudioModeIsVoip(boolean)} - set to {@code true} to ensure that the
+ *     platform knows your call is a VoIP call.</li>
+ *     <li>For newly created {@link Connection} instances, do NOT change the state of your call
+ *     using {@link Connection#setActive()}, {@link Connection#setOnHold()} until the call is added
+ *     to Telecom (ie you have returned it via
+ *     {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+ *     or
+ *     {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}).
+ *     </li>
+ * </ul>
+ *
+ * <h2>How to Place Outgoing Calls</h2>
+ * When your app wants to place an outgoing call it calls
+ * {@link TelecomManager#placeCall(Uri, Bundle)}.  You should specify a {@link Uri} to identify
+ * who the call is being placed to, and specify the {@link PhoneAccountHandle} associated with the
+ * {@link PhoneAccount} you registered for your app using
+ * {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} in the {@link Bundle} parameter.
+ * <p>
+ * Telecom will bind to your app's {@link ConnectionService} implementation and call either:
+ * <ul>
+ *     <li>{@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - the {@link ConnectionRequest#getAddress()} will match the address
+ *     you specified when placing the call.  You should return a new instance of your app's
+ *     {@link Connection} class to represent the outgoing call.</li>
+ *     <li>{@link ConnectionService#onCreateOutgoingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - your app should not place the call at this time; the call should be
+ *     cancelled and the user informed that the call cannot be placed.</li>
+ * </ul>
+ * <p>
+ * New outgoing calls will start in a {@link Connection#STATE_DIALING} state.  This state indicates
+ * that your app is in the process of connecting the call to the other party.
+ * <p>
+ * Once the other party answers the call (or it is set up successfully), your app should call
+ * {@link Connection#setActive()} to inform Telecom that the call is now active.
+ *
+ * <h2>How to Add Incoming Calls</h2>
+ * When your app receives an incoming call, it should call
+ * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}.  Set the
+ * {@link PhoneAccountHandle} parameter to the {@link PhoneAccountHandle} associated with your
+ * app's {@link PhoneAccount}.
+ * <p>
+ * Telecom will bind to your app's {@link ConnectionService} implementation and call either:
+ * <ul>
+ *     <li>{@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - You should return a new instance of your app's
+ *     {@link Connection} class to represent the incoming call.</li>
+ *     <li>{@link ConnectionService#onCreateIncomingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - your app should not receive the call at this time; the call should be
+ *     rejected silently; the user may be informed of a missed call.</li>
+ * </ul>
+ * <p>
+ * New incoming calls will start with a {@link Connection#STATE_RINGING} state.  This state
+ * indicates that your app has a new incoming call pending.  Telecom will NOT play a ringtone or
+ * post a notification for your app.  It is up to your app to post an incoming call notification
+ * with an associated ringtone.  Telecom will call {@link Connection#onShowIncomingCallUi()} on the
+ * {@link Connection} when your app can post its incoming call notification.  See
+ * {@link Connection#onShowIncomingCallUi() the docs} for more information on how to post the
+ * notification.
+ * <p>
+ * Your incoming call notification (or full screen UI) will typically have an "answer" and "decline"
+ * action which the user chooses.  When your app receives the "answer" or "decline"
+ * {@link android.app.PendingIntent}, you should must call either {@link Connection#setActive()} to
+ * inform Telecom that the call was answered, or
+ * {@link Connection#setDisconnected(DisconnectCause)} to inform Telecom that the call was rejected.
+ * If the call was rejected, supply an instance of {@link DisconnectCause} with
+ * {@link DisconnectCause#REJECTED}, and then call {@link Connection#destroy()}.
+ * <p>
+ * In addition to handling requests to answer or decline the call via notification actions, your
+ * app should also be implement the {@link Connection#onAnswer(int)} and
+ * {@link Connection#onAnswer()} methods on the {@link Connection}.  These will be raised if the
+ * user answers your call via a Bluetooth device or another device like a wearable or automotive
+ * calling UX.  In response, your app should call {@link Connection#setActive()} to inform Telecom
+ * that the call was answered.
+ * <p>
+ * Additionally, your app should implement {@link Connection#onReject()} to handle requests to
+ * reject the call which are raised via Bluetooth or other calling surfaces.  Your app should call
+ * {@link Connection#setDisconnected(DisconnectCause)} and supply an instance of
+ * {@link DisconnectCause} with {@link DisconnectCause#REJECTED} in this case.
+ *
+ * <h2>Ending Calls</h2>
+ * When an ongoing active call (incoming or outgoing) has ended, your app is responsible for
+ * informing Telecom that the call ended.
+ * <p>
+ * Your app calls:
+ * <ul>
+ *     <li>{@link Connection#setDisconnected(DisconnectCause)} - this informs Telecom that the
+ *     call has terminated.  You should provide a new instance of {@link DisconnectCause} with
+ *     either {@link DisconnectCause#LOCAL} or {@link DisconnectCause#REMOTE} to indicate where the
+ *     call disconnection took place.  {@link DisconnectCause#LOCAL} indicates that the call
+ *     terminated in your app on the current device (i.e. via user action), where
+ *     {@link DisconnectCause#REMOTE} indicates that the call terminates on the remote device.</li>
+ *     <li>{@link Connection#destroy()} - this informs Telecom that your call instance can be
+ *     cleaned up.  You should always call this when you are finished with a call.</li>
+ * </ul>
+ * <p>
+ * Similar to answering incoming calls, requests to disconnect your call may originate from outside
+ * your app.  You can handle these by implementing {@link Connection#onDisconnect()}.  Your app
+ * should call {@link Connection#setDisconnected(DisconnectCause)} with an instance of
+ * {@link DisconnectCause} and reason {@link DisconnectCause#LOCAL} to indicate to Telecom that your
+ * app has disconnected the call as requested based on the user's request.
+ *
+ * <h2>Holding and Unholding Calls</h2>
+ * When your app specifies {@link Connection#CAPABILITY_SUPPORT_HOLD} and
+ * {@link Connection#CAPABILITY_HOLD} on your {@link Connection} instance, it is telling Telecom
+ * that your calls can be placed into a suspended, or "held" state if required.  If your app
+ * supports holding its calls, it will be possible for the user to switch between calls in your app
+ * and holdable calls in another app or on the mobile network.  If your app does not support
+ * holding its calls, you may receive a request to disconnect the call from Telecom if the user
+ * opts to answer an incoming call in another app or on the mobile network; this ensures that the
+ * user can only be in one call at a time.
+ * <p>
+ * Your app is free to change a call between the held and active state using
+ * {@link Connection#setOnHold()} and {@link Connection#setActive()}.
+ * <p>
+ * Your app may receive a request from Telecom to hold or unhold a call via
+ * {@link Connection#onHold()} and {@link Connection#onUnhold()}.  Telecom can ask your app to
+ * hold or unhold its {@link Connection} either if the user requests this action through another
+ * calling surface such as Bluetooth, or if the user answers or switches to a call in a different
+ * app or on the mobile network.
+ * <p>
+ * When your app receives an {@link Connection#onHold()} it must call {@link Connection#setOnHold()}
+ * to inform Telecom that the call has been held successfully.
+ * <p>
+ * When your app receives an {@link Connection#onUnhold()} it must call
+ * {@link Connection#setActive()} to inform Telecom that the call has been resumed successfully.
  */
 public abstract class ConnectionService extends Service {
     /**