diff options
author | 2022-12-21 14:47:21 -0800 | |
---|---|---|
committer | 2023-01-09 14:14:49 -0800 | |
commit | 7aeccde860be7bb551353e9e435ff3e97c8d8809 (patch) | |
tree | db8f4121a1cea42566bbc4dcb163b6297f5297c9 | |
parent | 188c7870661022750cf5a0f101c3c20fed62be7f (diff) |
CallControl & CallEventCallback should use CallEndpoint routing
CallControl
- add requestCallEndpointChange API call
CallEventCallback
- remove onCallAudioStateChanged
- add onCallEndpointChanged
- add onAvailableCallEndpointsChanged
- add onMuteStateChanged
bug: 262912490
Test: cts
Change-Id: Ia6231ee02d8b09c3e0384abf45072023a0a76a48
6 files changed, 114 insertions, 14 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 878a63ec200b..a4435bbccf98 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -41226,6 +41226,7 @@ package android.telecom { method public void disconnect(@NonNull android.telecom.DisconnectCause, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); method @NonNull public android.os.ParcelUuid getCallId(); method public void rejectCall(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); + method public void requestCallEndpointChange(@NonNull android.telecom.CallEndpoint, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); method public void setActive(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); method public void setInactive(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); method public void startCallStreaming(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); @@ -41263,10 +41264,12 @@ package android.telecom { public interface CallEventCallback { method public void onAnswer(int, @NonNull java.util.function.Consumer<java.lang.Boolean>); - method public void onCallAudioStateChanged(@NonNull android.telecom.CallAudioState); + method public void onAvailableCallEndpointsChanged(@NonNull java.util.List<android.telecom.CallEndpoint>); + method public void onCallEndpointChanged(@NonNull android.telecom.CallEndpoint); method public void onCallStreamingFailed(int); method public void onCallStreamingStarted(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public void onDisconnect(@NonNull java.util.function.Consumer<java.lang.Boolean>); + method public void onMuteStateChanged(boolean); method public void onReject(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public void onSetActive(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public void onSetInactive(@NonNull java.util.function.Consumer<java.lang.Boolean>); diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java index 867bcc7f1e5a..770a3741b867 100644 --- a/telecomm/java/android/telecom/CallControl.java +++ b/telecomm/java/android/telecom/CallControl.java @@ -31,6 +31,8 @@ import android.os.ResultReceiver; import com.android.internal.telecom.ClientTransactionalServiceRepository; import com.android.internal.telecom.ICallControl; +import java.util.List; +import java.util.Objects; import java.util.concurrent.Executor; /** @@ -223,6 +225,42 @@ public final class CallControl implements AutoCloseable { } /** + * Request a CallEndpoint change. Clients should not define their own CallEndpoint when + * requesting a change. Instead, the new endpoint should be one of the valid endpoints provided + * by {@link CallEventCallback#onAvailableCallEndpointsChanged(List)}. + * + * @param callEndpoint ; The {@link CallEndpoint} to change to. + * @param executor ; The {@link Executor} on which the {@link OutcomeReceiver} callback + * will be called on. + * @param callback ; The {@link OutcomeReceiver} 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 changed the CallEndpoint that was requested. + * + * {@link OutcomeReceiver#onError} will be called if Telecom has failed to + * switch to the requested CallEndpoint. A {@link CallException} will be + * passed that details why the operation failed. + */ + public void requestCallEndpointChange(@NonNull CallEndpoint callEndpoint, + @CallbackExecutor @NonNull Executor executor, + @NonNull OutcomeReceiver<Void, CallException> callback) { + Objects.requireNonNull(callEndpoint); + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + if (mServerInterface != null) { + try { + mServerInterface.requestCallEndpointChange(callEndpoint, + new CallControlResultReceiver("endpointChange", executor, callback)); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } else { + throw new IllegalStateException(INTERFACE_ERROR_MSG); + } + } + + /** * This method should be called after * {@link CallControl#disconnect(DisconnectCause, Executor, OutcomeReceiver)} or * {@link CallControl#rejectCall(Executor, OutcomeReceiver)} diff --git a/telecomm/java/android/telecom/CallEventCallback.java b/telecomm/java/android/telecom/CallEventCallback.java index fd7e10104dd6..806febd1de56 100644 --- a/telecomm/java/android/telecom/CallEventCallback.java +++ b/telecomm/java/android/telecom/CallEventCallback.java @@ -19,6 +19,7 @@ package android.telecom; import android.annotation.NonNull; +import java.util.List; import java.util.function.Consumer; /** @@ -95,13 +96,6 @@ public interface CallEventCallback { void onDisconnect(@NonNull Consumer<Boolean> wasCompleted); /** - * update the client on the new {@link CallAudioState} - * - * @param callAudioState that is currently being used - */ - void onCallAudioStateChanged(@NonNull CallAudioState callAudioState); - - /** * Telecom is informing the client to set the call in streaming. * * @param wasCompleted The {@link Consumer} to be completed. If the client can stream the @@ -118,4 +112,26 @@ public interface CallEventCallback { * @param reason Code to indicate the reason of this failure */ void onCallStreamingFailed(@CallStreamingService.StreamingFailedReason int reason); + + /** + * Telecom is informing the client the current {@link CallEndpoint} changed. + * + * @param newCallEndpoint The new {@link CallEndpoint} through which call media flows + * (i.e. speaker, bluetooth, etc.). + */ + void onCallEndpointChanged(@NonNull CallEndpoint newCallEndpoint); + + /** + * Telecom is informing the client that the available {@link CallEndpoint}s have changed. + * + * @param availableEndpoints The set of available {@link CallEndpoint}s reported by Telecom. + */ + void onAvailableCallEndpointsChanged(@NonNull List<CallEndpoint> availableEndpoints); + + /** + * Called when the mute state changes. + * + * @param isMuted The current mute state. + */ + void onMuteStateChanged(boolean isMuted); } diff --git a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java index 16816ff0950b..b2e921b41159 100644 --- a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java +++ b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java @@ -22,14 +22,15 @@ import android.os.Binder; import android.os.OutcomeReceiver; import android.os.ResultReceiver; import android.telecom.CallAttributes; -import android.telecom.CallAudioState; import android.telecom.CallControl; +import android.telecom.CallEndpoint; import android.telecom.CallEventCallback; import android.telecom.CallException; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.util.Log; +import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; @@ -140,6 +141,9 @@ public class ClientTransactionalServiceWrapper { private static final String ON_REJECT = "onReject"; private static final String ON_DISCONNECT = "onDisconnect"; private static final String ON_STREAMING_STARTED = "onStreamingStarted"; + 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 void handleCallEventCallback(String action, String callId, int code, ResultReceiver ackResultReceiver) { @@ -246,14 +250,45 @@ public class ClientTransactionalServiceWrapper { } @Override - public void onCallAudioStateChanged(String callId, CallAudioState callAudioState) { - Log.i(TAG, TextUtils.formatSimple("onCallAudioStateChanged: callId=[%s]", callId)); + public void onCallEndpointChanged(String callId, CallEndpoint endpoint) { + handleEndpointUpdate(callId, ON_REQ_ENDPOINT_CHANGE, endpoint); + } + + @Override + public void onAvailableCallEndpointsChanged(String callId, List<CallEndpoint> endpoints) { + handleEndpointUpdate(callId, ON_AVAILABLE_CALL_ENDPOINTS, endpoints); + } + + @Override + public void onMuteStateChanged(String callId, boolean isMuted) { + handleEndpointUpdate(callId, ON_MUTE_STATE_CHANGED, isMuted); + } + + public void handleEndpointUpdate(String callId, String action, Object arg) { + Log.d(TAG, TextUtils.formatSimple("[%s], callId=[%s]", action, callId)); // lookup the callEventCallback associated with the particular call TransactionalCall call = mCallIdToTransactionalCall.get(callId); if (call != null) { CallEventCallback callback = call.getCallEventCallback(); Executor executor = call.getExecutor(); - executor.execute(() -> callback.onCallAudioStateChanged(callAudioState)); + final long identity = Binder.clearCallingIdentity(); + try { + executor.execute(() -> { + switch (action) { + case ON_REQ_ENDPOINT_CHANGE: + callback.onCallEndpointChanged((CallEndpoint) arg); + break; + case ON_AVAILABLE_CALL_ENDPOINTS: + callback.onAvailableCallEndpointsChanged((List<CallEndpoint>) arg); + break; + case ON_MUTE_STATE_CHANGED: + callback.onMuteStateChanged((boolean) arg); + break; + } + }); + } finally { + Binder.restoreCallingIdentity(identity); + } } } diff --git a/telecomm/java/com/android/internal/telecom/ICallControl.aidl b/telecomm/java/com/android/internal/telecom/ICallControl.aidl index dc0aeace0655..a5c6e44b5c73 100644 --- a/telecomm/java/com/android/internal/telecom/ICallControl.aidl +++ b/telecomm/java/com/android/internal/telecom/ICallControl.aidl @@ -17,6 +17,7 @@ package com.android.internal.telecom; import android.telecom.CallControl; +import android.telecom.CallEndpoint; import android.telecom.DisconnectCause; import android.os.ResultReceiver; @@ -29,4 +30,5 @@ oneway interface ICallControl { void disconnect(String callId, in DisconnectCause disconnectCause, in ResultReceiver callback); void rejectCall(String callId, in ResultReceiver callback); void startCallStreaming(String callId, in ResultReceiver callback); + void requestCallEndpointChange(in CallEndpoint callEndpoint, 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 c45ef97fa004..fef5e9e47dc5 100644 --- a/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl +++ b/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl @@ -17,10 +17,12 @@ package com.android.internal.telecom; import android.telecom.CallControl; +import android.telecom.CallEndpoint; import com.android.internal.telecom.ICallControl; import android.os.ResultReceiver; import android.telecom.CallAudioState; import android.telecom.CallException; +import java.util.List; /** * {@hide} @@ -29,15 +31,19 @@ oneway interface ICallEventCallback { // publicly exposed. Client should override void onAddCallControl(String callId, int resultCode, in ICallControl callControl, in CallException exception); + // -- Call Event Actions / Call State Transitions void onSetActive(String callId, in ResultReceiver callback); void onSetInactive(String callId, in ResultReceiver callback); void onAnswer(String callId, int videoState, in ResultReceiver callback); void onReject(String callId, in ResultReceiver callback); void onDisconnect(String callId, in ResultReceiver callback); - void onCallAudioStateChanged(String callId, in CallAudioState callAudioState); - // Streaming related. Client registered call streaming capabilities should override + // -- Streaming related. Client registered call streaming capabilities should override void onCallStreamingStarted(String callId, in ResultReceiver callback); void onCallStreamingFailed(String callId, int reason); + // -- Audio related. + void onCallEndpointChanged(String callId, in CallEndpoint endpoint); + void onAvailableCallEndpointsChanged(String callId, in List<CallEndpoint> endpoint); + void onMuteStateChanged(String callId, boolean isMuted); // hidden methods that help with cleanup void removeCallFromTransactionalServiceWrapper(String callId); }
\ No newline at end of file |