Merge "Retry sending hangup command on new connection after redial completes" into sc-dev
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index abc9613..53e923e 100755
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -165,32 +165,7 @@
AsyncResult ar = (AsyncResult) msg.obj;
com.android.internal.telephony.Connection connection =
(com.android.internal.telephony.Connection) ar.result;
- if (connection == null) {
- setDisconnected(DisconnectCauseUtil
- .toTelecomDisconnectCause(DisconnectCause.OUT_OF_NETWORK,
- "handover failure, no connection"));
- close();
- break;
- }
- if (mOriginalConnection != null) {
- if (connection != null &&
- ((connection.getAddress() != null &&
- mOriginalConnection.getAddress() != null &&
- mOriginalConnection.getAddress().equals(connection.getAddress())) ||
- connection.getState() == mOriginalConnection.getStateBeforeHandover())) {
- Log.i(TelephonyConnection.this, "Setting original connection after"
- + " handover or redial, current original connection="
- + mOriginalConnection.toString()
- + ", new original connection="
- + connection.toString());
- setOriginalConnection(connection);
- mWasImsConnection = false;
- }
- } else {
- Log.w(TelephonyConnection.this,
- what + ": mOriginalConnection==null --"
- + " invalid state (not cleaned up)");
- }
+ onOriginalConnectionRedialed(connection);
break;
case MSG_RINGBACK_TONE:
Log.v(TelephonyConnection.this, "MSG_RINGBACK_TONE");
@@ -360,6 +335,54 @@
private final Messenger mHandlerMessenger = new Messenger(mHandler);
/**
+ * The underlying telephony Connection has been redialed on a different domain (CS or IMS).
+ * Track the new telephony Connection and set back up appropriate callbacks.
+ * @param connection The new telephony Connection associated with this TelephonyConnection.
+ */
+ @VisibleForTesting
+ public void onOriginalConnectionRedialed(
+ com.android.internal.telephony.Connection connection) {
+ if (connection == null) {
+ setDisconnected(DisconnectCauseUtil
+ .toTelecomDisconnectCause(DisconnectCause.OUT_OF_NETWORK,
+ "handover failure, no connection"));
+ close();
+ return;
+ }
+ if (mOriginalConnection != null) {
+ if ((connection.getAddress() != null
+ && mOriginalConnection.getAddress() != null
+ && mOriginalConnection.getAddress().equals(connection.getAddress()))
+ || connection.getState() == mOriginalConnection.getStateBeforeHandover()) {
+ Log.i(TelephonyConnection.this, "Setting original connection after"
+ + " handover or redial, current original connection="
+ + mOriginalConnection.toString()
+ + ", new original connection="
+ + connection.toString());
+ setOriginalConnection(connection);
+ mWasImsConnection = false;
+ if (mHangupDisconnectCause != DisconnectCause.NOT_VALID) {
+ // A hangup request was initiated during the handover process, so
+ // go ahead and initiate the hangup on the new connection.
+ try {
+ Log.i(TelephonyConnection.this, "user has tried to hangup "
+ + "during handover, retrying hangup.");
+ connection.hangup();
+ } catch (CallStateException e) {
+ // Call state exception may be thrown if the connection was
+ // already disconnected, so just log this case.
+ Log.w(TelephonyConnection.this, "hangup during "
+ + "handover or redial resulted in an exception:" + e);
+ }
+ }
+ }
+ } else {
+ Log.w(TelephonyConnection.this, " mOriginalConnection==null --"
+ + " invalid state (not cleaned up)");
+ }
+ }
+
+ /**
* Handles {@link SuppServiceNotification}s pertinent to Telephony.
* @param ssn the notification.
*/
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
index c55dee7..388fd29 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
@@ -8,11 +8,15 @@
import static junit.framework.TestCase.assertFalse;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.Bundle;
import android.telecom.Connection;
import android.telephony.CarrierConfigManager;
+import android.telephony.DisconnectCause;
import androidx.test.runner.AndroidJUnit4;
@@ -132,6 +136,23 @@
}
@Test
+ public void testHangupAfterRedial() throws Exception {
+ TestTelephonyConnection c = new TestTelephonyConnection();
+ c.hangup(DisconnectCause.LOCAL);
+ verify(c.mMockRadioConnection).hangup();
+
+ // hangup failed because redial was in progress... The new original connection has been sent
+ // to the TelephonyConnection
+ com.android.internal.telephony.Connection newMockRadioConnection =
+ mock(com.android.internal.telephony.Connection.class);
+ doReturn("5551212").when(c.mMockRadioConnection).getAddress();
+ doReturn("5551212").when(newMockRadioConnection).getAddress();
+ doReturn(Call.State.DIALING).when(newMockRadioConnection).getState();
+ c.onOriginalConnectionRedialed(newMockRadioConnection);
+ verify(newMockRadioConnection).hangup();
+ }
+
+ @Test
public void testSetupDtmfOnly() {
TestTelephonyConnection c = new TestTelephonyConnection();
c.setIsImsConnection(true);