Merge "add CallControl#answerCall" into udc-dev
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index e9458a4..09d8787 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -5960,18 +5960,24 @@
}
}
- // driver method to create and execute a new TransactionalFocusRequestCallback
- public void transactionRequestNewFocusCall(Call call,
+ /**
+ * Intended for ongoing or new calls that would like to go active/answered and need to
+ * update the mConnectionSvrFocusMgr before setting the state
+ */
+ public void transactionRequestNewFocusCall(Call call, int newCallState,
OutcomeReceiver<Boolean, CallException> callback) {
Log.d(this, "transactionRequestNewFocusCall");
- PendingAction pendingAction = new ActionSetCallState(call, CallState.ACTIVE,
+ PendingAction pendingAction = new ActionSetCallState(call, newCallState,
"transactional ActionSetCallState");
mConnectionSvrFocusMgr
.requestFocus(call,
new TransactionalFocusRequestCallback(pendingAction, call, callback));
}
- // request a new call focus and ensure the request was successful
+ /**
+ * Request a new call focus and ensure the request was successful via an OutcomeReceiver. Also,
+ * include a PendingAction that will execute if the call focus change is successful.
+ */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class TransactionalFocusRequestCallback implements
ConnectionServiceFocusManager.RequestFocusCallback {
@@ -5990,26 +5996,18 @@
@Override
public void onRequestFocusDone(ConnectionServiceFocusManager.CallFocus call) {
Call currentCallFocus = (Call) mConnectionSvrFocusMgr.getCurrentFocusCall();
-
- if (currentCallFocus == null) {
- Log.i(this, "TransactionalFocusRequestCallback: "
- + "currentCallFocus is null.");
- mCallback.onError(new CallException("currentCallFocus is null",
+ // verify the update was successful before updating the state
+ Log.i(this, "tFRC: currentCallFocus=[%s], targetFocus=[%s]",
+ mTargetCallFocus, currentCallFocus);
+ if (currentCallFocus == null ||
+ !currentCallFocus.getId().equals(mTargetCallFocus.getId())) {
+ mCallback.onError(new CallException("failed to switch focus to requested call",
CallException.CODE_CALL_CANNOT_BE_SET_TO_ACTIVE));
return;
}
-
- Log.i(this, "TransactionalFocusRequestCallback: targetId=[%s], "
- + "currentId=[%s]", mTargetCallFocus.getId(), currentCallFocus.getId());
- if (!currentCallFocus.getId().equals(mTargetCallFocus.getId())) {
- Log.i(this, "TransactionalFocusRequestCallback: "
- + "currentCallFocus is not equal to targetCallFocus.");
- mCallback.onError(new CallException("current focus is not target focus",
- CallException.CODE_CALL_CANNOT_BE_SET_TO_ACTIVE));
- return;
- }
- mPendingAction.performAction();
- mCallback.onResult(true);
+ // at this point, we know the FocusManager is able to update successfully
+ mPendingAction.performAction(); // set the call state
+ mCallback.onResult(true); // complete the transaction
}
}
diff --git a/src/com/android/server/telecom/TransactionalServiceWrapper.java b/src/com/android/server/telecom/TransactionalServiceWrapper.java
index 7cf661a..d97d192 100644
--- a/src/com/android/server/telecom/TransactionalServiceWrapper.java
+++ b/src/com/android/server/telecom/TransactionalServiceWrapper.java
@@ -38,6 +38,7 @@
import com.android.internal.telecom.ICallControl;
import com.android.internal.telecom.ICallEventCallback;
+import com.android.server.telecom.voip.AnswerCallTransaction;
import com.android.server.telecom.voip.CallEventCallbackAckTransaction;
import com.android.server.telecom.voip.EndpointChangeTransaction;
import com.android.server.telecom.voip.HoldCallTransaction;
@@ -67,7 +68,7 @@
// CallControl : Client (ex. voip app) --> Telecom
public static final String SET_ACTIVE = "SetActive";
public static final String SET_INACTIVE = "SetInactive";
- public static final String REJECT = "Reject";
+ public static final String ANSWER = "Answer";
public static final String DISCONNECT = "Disconnect";
public static final String START_STREAMING = "StartStreaming";
@@ -75,7 +76,6 @@
public static final String ON_SET_ACTIVE = "onSetActive";
public static final String ON_SET_INACTIVE = "onSetInactive";
public static final String ON_ANSWER = "onAnswer";
- public static final String ON_REJECT = "onReject";
public static final String ON_DISCONNECT = "onDisconnect";
public static final String ON_STREAMING_STARTED = "onStreamingStarted";
@@ -196,6 +196,17 @@
}
@Override
+ public void answer(int videoState, String callId, android.os.ResultReceiver callback)
+ throws RemoteException {
+ try {
+ Log.startSession("TSW.a");
+ createTransactions(callId, callback, ANSWER, videoState);
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
public void setInactive(String callId, android.os.ResultReceiver callback)
throws RemoteException {
try {
@@ -238,6 +249,10 @@
case SET_ACTIVE:
addTransactionsToManager(createSetActiveTransactions(call), callback);
break;
+ case ANSWER:
+ addTransactionsToManager(createSetAnswerTransactions(call,
+ (int) objects[0]), callback);
+ break;
case DISCONNECT:
addTransactionsToManager(new EndCallTransaction(mCallsManager,
(DisconnectCause) objects[0], call), callback);
@@ -541,13 +556,27 @@
// add t1. hold potential active call
transactions.add(new HoldActiveCallForNewCallTransaction(mCallsManager, call));
- // add t2. answer current call
+ // add t2. send request to set the current call active
transactions.add(new RequestFocusTransaction(mCallsManager, call));
// send off to Transaction Manager to process
return new SerialTransaction(transactions);
}
+ private SerialTransaction createSetAnswerTransactions(Call call, int videoState) {
+ // create list for multiple transactions
+ List<VoipCallTransaction> transactions = new ArrayList<>();
+
+ // add t1. hold potential active call
+ transactions.add(new HoldActiveCallForNewCallTransaction(mCallsManager, call));
+
+ // add t2. answer current call
+ transactions.add(new AnswerCallTransaction(mCallsManager, call, videoState));
+
+ // send off to Transaction Manager to process
+ return new SerialTransaction(transactions);
+ }
+
/***
*********************************************************************************************
** FocusManager **
diff --git a/src/com/android/server/telecom/voip/AnswerCallTransaction.java b/src/com/android/server/telecom/voip/AnswerCallTransaction.java
new file mode 100644
index 0000000..1eb34c4
--- /dev/null
+++ b/src/com/android/server/telecom/voip/AnswerCallTransaction.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom.voip;
+
+import android.os.OutcomeReceiver;
+import android.telecom.CallException;
+import android.util.Log;
+
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CallState;
+import com.android.server.telecom.CallsManager;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+
+/**
+ * This transaction should be created for new incoming calls that request to go from
+ * CallState.Ringing to CallState.Answered. Before changing the CallState, the focus manager must
+ * be updated. Once the focus manager updates, the call state will be set. If there is an issue
+ * answering the call, the transaction will fail.
+ */
+public class AnswerCallTransaction extends VoipCallTransaction {
+
+ private static final String TAG = AnswerCallTransaction.class.getSimpleName();
+ private final CallsManager mCallsManager;
+ private final Call mCall;
+ private final int mVideoState;
+
+ public AnswerCallTransaction(CallsManager callsManager, Call call, int videoState) {
+ mCallsManager = callsManager;
+ mCall = call;
+ mVideoState = videoState;
+ }
+
+ @Override
+ public CompletionStage<VoipCallTransactionResult> processTransaction(Void v) {
+ Log.d(TAG, "processTransaction");
+ CompletableFuture<VoipCallTransactionResult> future = new CompletableFuture<>();
+
+ mCall.setVideoState(mVideoState);
+
+ mCallsManager.transactionRequestNewFocusCall(mCall, CallState.ANSWERED,
+ new OutcomeReceiver<>() {
+ @Override
+ public void onResult(Boolean result) {
+ Log.d(TAG, "processTransaction: onResult");
+ future.complete(new VoipCallTransactionResult(
+ VoipCallTransactionResult.RESULT_SUCCEED, null));
+ }
+
+ @Override
+ public void onError(CallException exception) {
+ Log.d(TAG, "processTransaction: onError");
+ future.complete(new VoipCallTransactionResult(
+ exception.getCode(), exception.getMessage()));
+ }
+ });
+
+ return future;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/voip/RequestFocusTransaction.java b/src/com/android/server/telecom/voip/RequestFocusTransaction.java
index f13525f..5dedbda 100644
--- a/src/com/android/server/telecom/voip/RequestFocusTransaction.java
+++ b/src/com/android/server/telecom/voip/RequestFocusTransaction.java
@@ -21,6 +21,7 @@
import android.util.Log;
import com.android.server.telecom.Call;
+import com.android.server.telecom.CallState;
import com.android.server.telecom.CallsManager;
import java.util.concurrent.CompletableFuture;
@@ -42,7 +43,8 @@
Log.d(TAG, "processTransaction");
CompletableFuture<VoipCallTransactionResult> future = new CompletableFuture<>();
- mCallsManager.transactionRequestNewFocusCall(mCall, new OutcomeReceiver<>() {
+ mCallsManager.transactionRequestNewFocusCall(mCall, CallState.ACTIVE,
+ new OutcomeReceiver<>() {
@Override
public void onResult(Boolean result) {
Log.d(TAG, "processTransaction: onResult");
diff --git a/tests/src/com/android/server/telecom/tests/TransactionTests.java b/tests/src/com/android/server/telecom/tests/TransactionTests.java
index a82fa78..1e6734b 100644
--- a/tests/src/com/android/server/telecom/tests/TransactionTests.java
+++ b/tests/src/com/android/server/telecom/tests/TransactionTests.java
@@ -47,6 +47,7 @@
import com.android.server.telecom.PhoneNumberUtilsAdapter;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.ui.ToastFactory;
+import com.android.server.telecom.voip.AnswerCallTransaction;
import com.android.server.telecom.voip.EndCallTransaction;
import com.android.server.telecom.voip.HoldCallTransaction;
import com.android.server.telecom.voip.IncomingCallTransaction;
@@ -152,7 +153,23 @@
// THEN
verify(mCallsManager, times(1))
- .transactionRequestNewFocusCall(eq(mMockCall1), isA(OutcomeReceiver.class));
+ .transactionRequestNewFocusCall(eq(mMockCall1), eq(CallState.ACTIVE),
+ isA(OutcomeReceiver.class));
+ }
+
+ @Test
+ public void testAnswerCallTransaction() throws Exception {
+ // GIVEN
+ AnswerCallTransaction transaction =
+ new AnswerCallTransaction(mCallsManager, mMockCall1, 0);
+
+ // WHEN
+ transaction.processTransaction(null);
+
+ // THEN
+ verify(mCallsManager, times(1))
+ .transactionRequestNewFocusCall(eq(mMockCall1), eq(CallState.ANSWERED),
+ isA(OutcomeReceiver.class));
}
@Test