Add API for cross device calling.
Test: CTS test
Change-Id: I1a3aa6c1ae6d445a2f3b55e5f0d11918da5bed33
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 6279bf8..0bb40a7 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -54,8 +54,10 @@
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -586,6 +588,14 @@
"android.telecom.extra.START_CALL_WITH_RTT";
/**
+ * A parcelable extra, which when set on the bundle passed into {@link #placeCall(Uri, Bundle)},
+ * indicates that the call should be initiated with an active {@link CallEndpoint} to stream
+ * the call as a tethered call.
+ */
+ public static final String EXTRA_START_CALL_ON_ENDPOINT =
+ "android.telecom.extra.START_CALL_ON_ENDPOINT";
+
+ /**
* Start an activity indicating that the completion of an outgoing call or an incoming call
* which was not blocked by the {@link CallScreeningService}, and which was NOT terminated
* while the call was in {@link Call#STATE_AUDIO_PROCESSING}.
@@ -745,6 +755,23 @@
"android.telecom.INCLUDE_SELF_MANAGED_CALLS";
/**
+ * A boolean meta-data value indicating this {@link InCallService} implementation is aimed at
+ * working as a streaming app for a tethered call. When there's a tethered call
+ * requesting to a {@link CallEndpoint} registered with this app, Telecom will bind to this
+ * streaming app and let the app streaming the call to the requested endpoint.
+ * <p>
+ * This meta-data can only be set for an {@link InCallService} which doesn't set neither
+ * {@link #METADATA_IN_CALL_SERVICE_UI} nor {@link #METADATA_IN_CALL_SERVICE_CAR_MODE_UI}.
+ * Otherwise, the app will be treated as a phone/dialer app or a car-mode app.
+ * <p>
+ * The {@link InCallService} declared this meta-data must implement
+ * {@link InCallService#onCallEndpointActivationRequested(CallEndpoint, CallEndpointSession)}.
+ * See this method for more information.
+ */
+ public static final String METADATA_STREAMING_TETHERED_CALLS =
+ "android.telecom.STREAMING_TETHERED_CALLS";
+
+ /**
* The dual tone multi-frequency signaling character sent to indicate the dialing system should
* pause for a predefined period.
*/
@@ -2250,6 +2277,7 @@
* <li>{@link #EXTRA_PHONE_ACCOUNT_HANDLE}</li>
* <li>{@link #EXTRA_START_CALL_WITH_SPEAKERPHONE}</li>
* <li>{@link #EXTRA_START_CALL_WITH_VIDEO_STATE}</li>
+ * <li>{@link #EXTRA_START_CALL_ON_ENDPOINT}</li>
* </ul>
* <p>
* An app which implements the self-managed {@link ConnectionService} API uses
@@ -2579,6 +2607,79 @@
}
}
+ /**
+ * Register a set of {@link CallEndpoint} to telecom. All registered {@link CallEndpoint} can
+ * be provided as options for push, place or answer call externally.
+ *
+ * @param endpoints Endpoints to be registered.
+ */
+ // TODO: add permission requirements
+ // @RequiresPermission{}
+ public void registerCallEndpoints(@NonNull Set<CallEndpoint> endpoints) {
+ ITelecomService service = getTelecomService();
+ List<CallEndpoint> endpointList = new ArrayList<>(endpoints);
+ if (service != null) {
+ try {
+ service.registerCallEndpoints(endpointList, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException registerCallEndpoints: " + e);
+ e.rethrowAsRuntimeException();
+ }
+ } else {
+ throw new IllegalStateException("Telecom service is null.");
+ }
+ }
+
+ /**
+ * Unregister all {@link CallEndpoint} from telecom in the set provided. After un-registration,
+ * telecom will stop tracking and maintaining these {@link CallEndpoint}, user can no longer
+ * carry a call on them.
+ *
+ * @param endpoints
+ */
+ // TODO: add permission requirements
+ // @RequiresPermission{}
+ public void unregisterCallEndpoints(@NonNull Set<CallEndpoint> endpoints) {
+ ITelecomService service = getTelecomService();
+ List<CallEndpoint> endpointList = new ArrayList<>(endpoints);
+ if (service != null) {
+ try {
+ service.unregisterCallEndpoints(endpointList, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException unregisterCallEndpoints: " + e);
+ e.rethrowAsRuntimeException();
+ }
+ } else {
+ throw new IllegalStateException("Telecom service is null.");
+ }
+ }
+
+ /**
+ * Return a set all registered {@link CallEndpoint} that can be used to stream and carry an
+ * external call.
+ *
+ * @return A set of all available {@link CallEndpoint}.
+ */
+ // TODO: add permission requirements
+ // @RequiresPermission{}
+ public @NonNull Set<CallEndpoint> getCallEndpoints() {
+ Set<CallEndpoint> endpoints = new HashSet<>();
+ List<CallEndpoint> endpointList;
+ ITelecomService service = getTelecomService();
+ if (service != null) {
+ try {
+ endpointList = service.getCallEndpoints(mContext.getOpPackageName());
+ return new HashSet<>(endpointList);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException registerCallEndpoints: " + e);
+ e.rethrowAsRuntimeException();
+ }
+ } else {
+ throw new IllegalStateException("Telecom service is null.");
+ }
+ return endpoints;
+ }
+
private boolean isSystemProcess() {
return Process.myUid() == Process.SYSTEM_UID;
}