add transactional video state APIs
Bug: 311265260
Test: CTS coverage
Change-Id: I4c76e414056c90643d65e72dcb51da7d81bf36b9
diff --git a/telecomm/java/android/telecom/CallAttributes.java b/telecomm/java/android/telecom/CallAttributes.java
index 8c6e101..afd34fc 100644
--- a/telecomm/java/android/telecom/CallAttributes.java
+++ b/telecomm/java/android/telecom/CallAttributes.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -24,6 +25,8 @@
import android.os.Parcelable;
import android.text.TextUtils;
+import com.android.server.telecom.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
@@ -113,7 +116,8 @@
public static final int VIDEO_CALL = 2;
/** @hide */
- @IntDef(value = {SUPPORTS_SET_INACTIVE, SUPPORTS_STREAM, SUPPORTS_TRANSFER}, flag = true)
+ @IntDef(value = {SUPPORTS_SET_INACTIVE, SUPPORTS_STREAM, SUPPORTS_TRANSFER,
+ SUPPORTS_VIDEO_CALLING}, flag = true)
@Retention(RetentionPolicy.SOURCE)
public @interface CallCapability {
}
@@ -133,6 +137,12 @@
* The call can be completely transferred from one endpoint to another.
*/
public static final int SUPPORTS_TRANSFER = 1 << 3;
+ /**
+ * The call supports video calling. This allows clients to gate video calling on a per call
+ * basis as opposed to re-registering the phone account.
+ */
+ @FlaggedApi(Flags.FLAG_TRANSACTIONAL_VIDEO_STATE)
+ public static final int SUPPORTS_VIDEO_CALLING = 1 << 4;
/**
* Build an instance of {@link CallAttributes}. In order to build a valid instance, a
diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java
index a1407869..808a575 100644
--- a/telecomm/java/android/telecom/CallControl.java
+++ b/telecomm/java/android/telecom/CallControl.java
@@ -293,12 +293,50 @@
try {
mServerInterface.setMuteState(isMuted,
new CallControlResultReceiver("requestMuteState", executor, callback));
-
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
+ /**
+ * Request a new video state for the ongoing call. This can only be changed if the application
+ * has registered a {@link PhoneAccount} with the
+ * {@link PhoneAccount#CAPABILITY_SUPPORTS_VIDEO_CALLING} and set the
+ * {@link CallAttributes#SUPPORTS_VIDEO_CALLING} when adding the call via
+ * {@link TelecomManager#addCall(CallAttributes, Executor, OutcomeReceiver,
+ * CallControlCallback, CallEventCallback)}
+ *
+ * @param videoState to report to Telecom. To see the valid argument to pass,
+ * see {@link CallAttributes.CallType}.
+ * @param executor The {@link Executor} on which the {@link OutcomeReceiver} callback
+ * will be called on.
+ * @param callback that will be completed on the Telecom side that details success or failure
+ * of the requested operation.
+ *
+ * {@link OutcomeReceiver#onResult} will be called if Telecom has successfully
+ * switched the video state.
+ *
+ * {@link OutcomeReceiver#onError} will be called if Telecom has failed to set
+ * the new video state. A {@link CallException} will be passed
+ * that details why the operation failed.
+ * @throws IllegalArgumentException if the argument passed for videoState is invalid. To see a
+ * list of valid states, see {@link CallAttributes.CallType}.
+ */
+ @FlaggedApi(Flags.FLAG_TRANSACTIONAL_VIDEO_STATE)
+ public void requestVideoState(@CallAttributes.CallType int videoState,
+ @CallbackExecutor @NonNull Executor executor,
+ @NonNull OutcomeReceiver<Void, CallException> callback) {
+ validateVideoState(videoState);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ try {
+ mServerInterface.requestVideoState(videoState, mCallId,
+ new CallControlResultReceiver("requestVideoState", executor, callback));
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
/**
* Raises an event to the {@link android.telecom.InCallService} implementations tracking this
* call via {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)}.
diff --git a/telecomm/java/android/telecom/CallEventCallback.java b/telecomm/java/android/telecom/CallEventCallback.java
index a41c011..b0438bf 100644
--- a/telecomm/java/android/telecom/CallEventCallback.java
+++ b/telecomm/java/android/telecom/CallEventCallback.java
@@ -16,9 +16,12 @@
package android.telecom;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.os.Bundle;
+import com.android.server.telecom.flags.Flags;
+
import java.util.List;
/**
@@ -51,6 +54,14 @@
void onMuteStateChanged(boolean isMuted);
/**
+ * Called when the video state changes.
+ *
+ * @param videoState The current video state.
+ */
+ @FlaggedApi(Flags.FLAG_TRANSACTIONAL_VIDEO_STATE)
+ default void onVideoStateChanged(@CallAttributes.CallType int videoState) {}
+
+ /**
* Telecom is informing the client user requested call streaming but the stream can't be
* started.
*
diff --git a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
index 467e89c..a2c6086 100644
--- a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
+++ b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
@@ -33,6 +33,8 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.server.telecom.flags.Flags;
+
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@@ -148,6 +150,7 @@
private static final String ON_REQ_ENDPOINT_CHANGE = "onRequestEndpointChange";
private static final String ON_AVAILABLE_CALL_ENDPOINTS = "onAvailableCallEndpointsChanged";
private static final String ON_MUTE_STATE_CHANGED = "onMuteStateChanged";
+ private static final String ON_VIDEO_STATE_CHANGED = "onVideoStateChanged";
private static final String ON_CALL_STREAMING_FAILED = "onCallStreamingFailed";
private static final String ON_EVENT = "onEvent";
@@ -261,6 +264,11 @@
handleEventCallback(callId, ON_MUTE_STATE_CHANGED, isMuted);
}
+ @Override
+ public void onVideoStateChanged(String callId, int videoState) {
+ handleEventCallback(callId, ON_VIDEO_STATE_CHANGED, videoState);
+ }
+
public void handleEventCallback(String callId, String action, Object arg) {
Log.d(TAG, TextUtils.formatSimple("hEC: [%s], callId=[%s]", action, callId));
// lookup the callEventCallback associated with the particular call
@@ -281,6 +289,11 @@
case ON_MUTE_STATE_CHANGED:
callback.onMuteStateChanged((boolean) arg);
break;
+ case ON_VIDEO_STATE_CHANGED:
+ if (Flags.transactionalVideoState()) {
+ callback.onVideoStateChanged((int) arg);
+ }
+ break;
case ON_CALL_STREAMING_FAILED:
callback.onCallStreamingFailed((int) arg /* reason */);
break;
diff --git a/telecomm/java/com/android/internal/telecom/ICallControl.aidl b/telecomm/java/com/android/internal/telecom/ICallControl.aidl
index 372e4a12..ac49660 100644
--- a/telecomm/java/com/android/internal/telecom/ICallControl.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallControl.aidl
@@ -34,4 +34,5 @@
void requestCallEndpointChange(in CallEndpoint callEndpoint, in ResultReceiver callback);
void setMuteState(boolean isMuted, in ResultReceiver callback);
void sendEvent(String callId, String event, in Bundle extras);
+ void requestVideoState(int videoState, String callId, in ResultReceiver callback);
}
\ No newline at end of file
diff --git a/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl b/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl
index 213cafb..e4d6b0c 100644
--- a/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl
@@ -45,6 +45,8 @@
void onCallEndpointChanged(String callId, in CallEndpoint endpoint);
void onAvailableCallEndpointsChanged(String callId, in List<CallEndpoint> endpoint);
void onMuteStateChanged(String callId, boolean isMuted);
+ // -- Video Related
+ void onVideoStateChanged(String callId, int videoState);
// -- Events
void onEvent(String callId, String event, in Bundle extras);
// hidden methods that help with cleanup