Merge "Keep connection state updated while call is active"
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 2c43c7f..157ca03 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -543,19 +543,20 @@
                 }
 
                 @Override
-        public void onStateChanged(Connection connection, @Connection.ConnectionState int state) {
-            if (connection != null) {
-                TelephonyConnection c = (TelephonyConnection) connection;
-                Log.i(this, "onStateChanged callId=" + c.getTelecomCallId() + ", state=" + state);
-                if (c.getState() == Connection.STATE_ACTIVE) {
-                    mEmergencyStateTracker.onEmergencyCallStateChanged(
-                            c.getOriginalConnection().getState(), c.getTelecomCallId());
-                    c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
-                    releaseEmergencyCallDomainSelection(false);
+                public void onStateChanged(Connection connection,
+                        @Connection.ConnectionState int state) {
+                    if (mEmergencyCallDomainSelectionConnection == null) return;
+                    if (connection == null) return;
+                    TelephonyConnection c = (TelephonyConnection) connection;
+                    Log.i(this, "onStateChanged callId=" + c.getTelecomCallId()
+                            + ", state=" + state);
+                    if (c.getState() == Connection.STATE_ACTIVE) {
+                        mEmergencyStateTracker.onEmergencyCallStateChanged(
+                                c.getOriginalConnection().getState(), c.getTelecomCallId());
+                        releaseEmergencyCallDomainSelection(false);
+                    }
                 }
-            }
-        }
-    };
+            };
 
     /**
      * A listener for calls.
@@ -2328,6 +2329,7 @@
                 return maybeReselectDomainForEmergencyCall(c, callFailCause, reasonInfo);
             }
             Log.i(this, "maybeReselectDomain endCall()");
+            c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
             mEmergencyStateTracker.endCall(c.getTelecomCallId());
             mEmergencyCallId = null;
             return false;
@@ -2650,6 +2652,11 @@
         }
     }
 
+    @VisibleForTesting
+    public TelephonyConnection.TelephonyConnectionListener getEmergencyConnectionListener() {
+        return mEmergencyConnectionListener;
+    }
+
     private boolean isVideoCallHoldAllowed(Phone phone) {
          CarrierConfigManager cfgManager = (CarrierConfigManager)
                 phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 4826d89..734d7e3 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -2160,6 +2160,88 @@
     }
 
     @Test
+    public void testDomainSelectionListenOriginalConnectionConfigChange() throws Exception {
+        setupForCallTest();
+
+        int selectedDomain = DOMAIN_PS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+        verify(mPhone0).dial(anyString(), any(), any());
+
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setTelecomCallId(TELECOM_CALL_ID1);
+        c.setIsImsConnection(true);
+        Connection orgConn = c.getOriginalConnection();
+        doReturn(PhoneConstants.PHONE_TYPE_IMS).when(orgConn).getPhoneType();
+
+        TelephonyConnection.TelephonyConnectionListener connectionListener =
+                mTestConnectionService.getEmergencyConnectionListener();
+
+        connectionListener.onOriginalConnectionConfigured(c);
+
+        verify(mEmergencyStateTracker, times(1)).onEmergencyCallDomainUpdated(
+                eq(PhoneConstants.PHONE_TYPE_IMS), eq(TELECOM_CALL_ID1));
+
+        verify(mEmergencyStateTracker, times(0)).onEmergencyCallStateChanged(
+                any(), eq(TELECOM_CALL_ID1));
+
+        c.setActive();
+        doReturn(Call.State.ACTIVE).when(orgConn).getState();
+        connectionListener.onStateChanged(c, c.getState());
+
+        // ACTIVE sate is notified
+        verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
+                eq(Call.State.ACTIVE), eq(TELECOM_CALL_ID1));
+
+        // state change to HOLDING
+        c.setOnHold();
+        doReturn(Call.State.HOLDING).when(orgConn).getState();
+        connectionListener.onStateChanged(c, c.getState());
+
+        // state change not notified any more after CONNECTED once
+        verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
+                any(), eq(TELECOM_CALL_ID1));
+
+        // state change to ACTIVE again
+        c.setActive();
+        doReturn(Call.State.ACTIVE).when(orgConn).getState();
+        connectionListener.onStateChanged(c, c.getState());
+
+        // state change not notified any more after CONNECTED once
+        verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
+                any(), eq(TELECOM_CALL_ID1));
+
+        // SRVCC happens
+        c.setIsImsConnection(false);
+        orgConn = c.getOriginalConnection();
+        doReturn(PhoneConstants.PHONE_TYPE_GSM).when(orgConn).getPhoneType();
+        connectionListener.onOriginalConnectionConfigured(c);
+
+         // domain change notified
+        verify(mEmergencyStateTracker, times(1)).onEmergencyCallDomainUpdated(
+                eq(PhoneConstants.PHONE_TYPE_GSM), eq(TELECOM_CALL_ID1));
+
+        // state change to DISCONNECTED
+        c.setDisconnected(null);
+        doReturn(Call.State.DISCONNECTED).when(orgConn).getState();
+        connectionListener.onStateChanged(c, c.getState());
+
+        // state change not notified
+        verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
+                any(), eq(TELECOM_CALL_ID1));
+    }
+
+    @Test
     public void testDomainSelectionWithMmiCode() {
         //UT domain selection should not be handled by new domain selector.
         doNothing().when(mContext).startActivity(any());