add setMuteState framework changes

previously, there was no way to mute a Transactional call via the
CallControl object.  In order to mute the call, the AudioService
was needed.

Now, clients can use CallControl#setMuteState to mute the call.

Fixes: 310669304
Test: 1 new CTS test
Change-Id: I7b5d834b8073dd8fbae07d31722aa8f54a88b26e
diff --git a/core/api/current.txt b/core/api/current.txt
index 46c8f82..6390d91 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -41655,6 +41655,7 @@
     method public void sendEvent(@NonNull String, @NonNull android.os.Bundle);
     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 @FlaggedApi("com.android.server.telecom.flags.set_mute_state") public void setMuteState(boolean, @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>);
   }
 
diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java
index 24d3918..fe699af 100644
--- a/telecomm/java/android/telecom/CallControl.java
+++ b/telecomm/java/android/telecom/CallControl.java
@@ -19,6 +19,7 @@
 import static android.telecom.CallException.TRANSACTION_EXCEPTION_KEY;
 
 import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
@@ -32,6 +33,7 @@
 
 import com.android.internal.telecom.ClientTransactionalServiceRepository;
 import com.android.internal.telecom.ICallControl;
+import com.android.server.telecom.flags.Flags;
 
 import java.util.List;
 import java.util.Objects;
@@ -292,6 +294,43 @@
     }
 
     /**
+     * Request a new mute state.  Note: {@link CallEventCallback#onMuteStateChanged(boolean)}
+     * will be called every time the mute state is changed and can be used to track the current
+     * mute state.
+     *
+     * @param isMuted  The new mute state.  Passing in a {@link Boolean#TRUE} for the isMuted
+     *                 parameter will mute the call.  {@link Boolean#FALSE} will unmute the call.
+     * @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 mute state.
+     *
+     *                 {@link OutcomeReceiver#onError} will be called if Telecom has failed to
+     *                 switch to the mute state.  A {@link CallException} will be
+     *                 passed that details why the operation failed.
+     */
+    @FlaggedApi(Flags.FLAG_SET_MUTE_STATE)
+    public void setMuteState(boolean isMuted, @CallbackExecutor @NonNull Executor executor,
+            @NonNull OutcomeReceiver<Void, CallException> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+        if (mServerInterface != null) {
+            try {
+                mServerInterface.setMuteState(isMuted,
+                        new CallControlResultReceiver("setMuteState", executor, callback));
+
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        } else {
+            throw new IllegalStateException(INTERFACE_ERROR_MSG);
+        }
+    }
+
+    /**
      * Raises an event to the {@link android.telecom.InCallService} implementations tracking this
      * call via {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)}.
      * These events and the associated extra keys for the {@code Bundle} parameter are mutually
diff --git a/telecomm/java/com/android/internal/telecom/ICallControl.aidl b/telecomm/java/com/android/internal/telecom/ICallControl.aidl
index 5e2c923..372e4a12 100644
--- a/telecomm/java/com/android/internal/telecom/ICallControl.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallControl.aidl
@@ -32,5 +32,6 @@
     void disconnect(String callId, in DisconnectCause disconnectCause, in ResultReceiver callback);
     void startCallStreaming(String callId, in ResultReceiver callback);
     void requestCallEndpointChange(in CallEndpoint callEndpoint, in ResultReceiver callback);
+    void setMuteState(boolean isMuted, in ResultReceiver callback);
     void sendEvent(String callId, String event, in Bundle extras);
 }
\ No newline at end of file