Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7aeccde8 authored by Thomas Stuart's avatar Thomas Stuart
Browse files

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
parent 188c7870
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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>);
+38 −0
Original line number Diff line number Diff line
@@ -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;

/**
@@ -222,6 +224,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
+23 −7
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.telecom;

import android.annotation.NonNull;

import java.util.List;
import java.util.function.Consumer;

/**
@@ -94,13 +95,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.
     *
@@ -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);
}
+39 −4
Original line number Diff line number Diff line
@@ -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);
                }
            }
        }

+2 −0
Original line number Diff line number Diff line
@@ -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
Loading