Merge "Add field to store who is initiating the call"
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 7a17dde..56f0963 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1514,7 +1514,7 @@
* MMI codes which can be dialed when one or more calls are in progress.
* <P>
* Checks for numbers formatted similar to the MMI codes defined in:
- * {@link com.android.internal.telephony.gsm.GSMPhone#handleInCallMmiCommands(String)}
+ * {@link com.android.internal.telephony.GsmCdmaPhone#handleInCallMmiCommands(String)}
* and
* {@link com.android.internal.telephony.imsphone.ImsPhone#handleInCallMmiCommands(String)}
*
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 28ea05d..91056d2 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -41,6 +41,7 @@
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -62,6 +63,7 @@
public class TelecomServiceImpl {
private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
"android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
+ private static final int DEFAULT_VIDEO_STATE = -1;
private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
@Override
@@ -589,7 +591,25 @@
long token = Binder.clearCallingIdentity();
try {
- acceptRingingCallInternal();
+ acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+
+ /**
+ * @see android.telecom.TelecomManager#acceptRingingCall(int)
+ *
+ */
+ @Override
+ public void acceptRingingCallWithVideoState(int videoState) {
+ synchronized (mLock) {
+ enforceModifyPermission();
+
+ long token = Binder.clearCallingIdentity();
+ try {
+ acceptRingingCallInternal(videoState);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1038,10 +1058,13 @@
return false;
}
- private void acceptRingingCallInternal() {
+ private void acceptRingingCallInternal(int videoState) {
Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
if (call != null) {
- call.answer(call.getVideoState());
+ if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
+ videoState = call.getVideoState();
+ }
+ call.answer(videoState);
}
}
@@ -1204,4 +1227,23 @@
private TelephonyManager getTelephonyManager() {
return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
}
+
+ /**
+ * Determines if a video state is valid for accepting an incoming call.
+ * For the purpose of accepting a call, states {@link VideoProfile#STATE_AUDIO_ONLY}, and
+ * any combination of {@link VideoProfile#STATE_RX_ENABLED} and
+ * {@link VideoProfile#STATE_TX_ENABLED} are considered valid.
+ *
+ * @param videoState The video state.
+ * @return {@code true} if the video state is valid, {@code false} otherwise.
+ */
+ private boolean isValidAcceptVideoState(int videoState) {
+ // Given a video state input, turn off TX and RX so that we can determine if those were the
+ // only bits set.
+ int remainingState = videoState & ~VideoProfile.STATE_TX_ENABLED;
+ remainingState = remainingState & ~VideoProfile.STATE_RX_ENABLED;
+
+ // If only TX or RX were set (or neither), the video state is valid.
+ return remainingState == 0;
+ }
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index a637470..4576690 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -31,6 +31,9 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
+ <!-- Used to access TelephonyManager APIs -->
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+
<application android:label="@string/app_name"
android:debuggable="true">
<uses-library android:name="android.test.runner" />
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index dfaeed1..f3f4e5b 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -420,6 +420,15 @@
String number,
PhoneAccountHandle phoneAccountHandle,
final ConnectionServiceFixture connectionServiceFixture) throws Exception {
+ return startIncomingPhoneCall(number, phoneAccountHandle, VideoProfile.STATE_AUDIO_ONLY,
+ connectionServiceFixture);
+ }
+
+ private IdPair startIncomingPhoneCall(
+ String number,
+ PhoneAccountHandle phoneAccountHandle,
+ int videoState,
+ final ConnectionServiceFixture connectionServiceFixture) throws Exception {
reset(
connectionServiceFixture.getTestDouble(),
mInCallServiceFixtureX.getTestDouble(),
@@ -450,10 +459,15 @@
eq(true),
eq(false));
+ mConnectionServiceFixtureA.mConnectionById.get(
+ connectionServiceFixture.mLatestConnectionId).videoState = videoState;
+
connectionServiceFixture.sendHandleCreateConnectionComplete(
connectionServiceFixture.mLatestConnectionId);
connectionServiceFixture.sendSetRinging(
connectionServiceFixture.mLatestConnectionId);
+ connectionServiceFixture.sendSetVideoState(
+ connectionServiceFixture.mLatestConnectionId);
// For the case of incoming calls, Telecom connecting the InCall services and adding the
// Call is triggered by the async completion of the CallerInfoAsyncQuery. Once the Call
@@ -607,6 +621,99 @@
mInCallServiceFixtureY.getCall(ids.mCallId).getState());
}
+ /**
+ * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming
+ * audio-only call.
+ *
+ * @throws Exception
+ */
+ public void testTelecomManagerAcceptRingingCall() throws Exception {
+ IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
+ mConnectionServiceFixtureA);
+
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+ // Use TelecomManager API to answer the ringing call.
+ TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
+ .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
+ telecomManager.acceptRingingCall();
+
+ verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
+ .answer(ids.mCallId);
+ }
+
+ /**
+ * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming
+ * video call, which should be answered as video.
+ *
+ * @throws Exception
+ */
+ public void testTelecomManagerAcceptRingingVideoCall() throws Exception {
+ IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
+ VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);
+
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+ // Use TelecomManager API to answer the ringing call; the default expected behavior is to
+ // answer using whatever video state the ringing call requests.
+ TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
+ .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
+ telecomManager.acceptRingingCall();
+
+ // Answer video API should be called
+ verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
+ .answerVideo(eq(ids.mCallId), eq(VideoProfile.STATE_BIDIRECTIONAL));
+ }
+
+ /**
+ * Tests the {@link TelecomManager#acceptRingingCall(int)} API. Tests answering a video call
+ * as an audio call.
+ *
+ * @throws Exception
+ */
+ public void testTelecomManagerAcceptRingingVideoCallAsAudio() throws Exception {
+ IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
+ VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);
+
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+ // Use TelecomManager API to answer the ringing call.
+ TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
+ .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
+ telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY);
+
+ // The generic answer method on the ConnectionService is used to answer audio-only calls.
+ verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
+ .answer(eq(ids.mCallId));
+ }
+
+ /**
+ * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming
+ * video call, where an attempt is made to answer with an invalid video state.
+ *
+ * @throws Exception
+ */
+ public void testTelecomManagerAcceptRingingInvalidVideoState() throws Exception {
+ IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
+ VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);
+
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+ assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+ // Use TelecomManager API to answer the ringing call; the default expected behavior is to
+ // answer using whatever video state the ringing call requests.
+ TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
+ .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
+ telecomManager.acceptRingingCall(999 /* invalid videostate */);
+
+ // Answer video API should be called
+ verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
+ .answerVideo(eq(ids.mCallId), eq(VideoProfile.STATE_BIDIRECTIONAL));
+ }
+
// A simple incoming call, similar in scope to the previous test
private IdPair startAndMakeActiveIncomingCall(
String number,