Merge aosp-24Q3-ts-dev

Bug: 358400644
Merged-In: I918f6562949e32d3581bf0a69c9bfe02dce1cd3b
Change-Id: I8e89f0d5d38f094eac3d606f929ed9272b17ad32
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
index 20761e2..9f4fa11 100644
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ b/src/java/com/android/internal/telephony/data/DataConfigManager.java
@@ -1503,6 +1503,14 @@
     }
 
     /**
+     * {@code True} enables mms to be attempted on iwlan if possible, even if existing cellular
+     *  networks already supports iwlan.
+     */
+    public boolean isForceIwlanMmsFeatureEnabled() {
+        return mResources.getBoolean(com.android.internal.R.bool.force_iwlan_mms_feature_enabled);
+    }
+
+    /**
      * Log debug messages.
      * @param s debug messages
      */
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 8369874..87c392e 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -1263,7 +1263,7 @@
                         getHandler(), EVENT_VOICE_CALL_ENDED, null);
             }
 
-            if (mFlags.forceIwlanMms()) {
+            if (mFlags.forceIwlanMms() && mDataConfigManager.isForceIwlanMmsFeatureEnabled()) {
                 if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_MMS)) {
                     mAccessNetworksManagerCallback = new AccessNetworksManagerCallback(
                             getHandler()::post) {
@@ -1289,7 +1289,8 @@
         @Override
         public void exit() {
             logv("Unregistering all events.");
-            if (mFlags.forceIwlanMms() && mAccessNetworksManagerCallback != null) {
+            if (mFlags.forceIwlanMms() && mAccessNetworksManagerCallback != null
+                    && mDataConfigManager.isForceIwlanMmsFeatureEnabled()) {
                 mAccessNetworksManager.unregisterCallback(mAccessNetworksManagerCallback);
             }
 
@@ -2488,7 +2489,8 @@
         // will be attempted on IWLAN if possible, even if existing cellular networks already
         // supports IWLAN.
         if (mFlags.forceIwlanMms() && builder.build()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
+                .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
+                && mDataConfigManager.isForceIwlanMmsFeatureEnabled()) {
             // If QNS sets MMS preferred on IWLAN, and it is possible to setup an MMS network on
             // IWLAN, then we need to remove the MMS capability on the cellular network. This will
             // allow the new MMS network to be brought up on IWLAN when MMS network request arrives.
diff --git a/src/java/com/android/internal/telephony/domainselection/OWNERS b/src/java/com/android/internal/telephony/domainselection/OWNERS
index 2a76770..5874c98 100644
--- a/src/java/com/android/internal/telephony/domainselection/OWNERS
+++ b/src/java/com/android/internal/telephony/domainselection/OWNERS
@@ -1,7 +1,7 @@
 # automatically inherit owners from fw/opt/telephony
 
 hwangoo@google.com
-forestchoi@google.com
+jaesikkong@google.com
 avinashmp@google.com
 mkoon@google.com
 seheele@google.com
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
index 8478cff..167062f 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
@@ -564,6 +564,11 @@
         Rlog.i(TAG, "startEmergencyCall: phoneId=" + phone.getPhoneId()
                 + ", callId=" + c.getTelecomCallId());
 
+        if (needToSwitchPhone(phone)) {
+            Rlog.e(TAG, "startEmergencyCall failed. need to switch stacks.");
+            return CompletableFuture.completedFuture(DisconnectCause.EMERGENCY_PERM_FAILURE);
+        }
+
         if (mPhone != null) {
             // Create new future to return as to not interfere with any uncompleted futures.
             // Case1) When 2nd emergency call is initiated during an active call on the same phone.
@@ -2105,4 +2110,63 @@
             endNormalRoutingEmergencyCall(c);
         }
     }
+
+    /**
+     * Determines whether switching stacks is needed or not.
+     *
+     * @param phone the {@code Phone} on which to process the emergency call.
+     * @return true if switching stacks is needed.
+     */
+    @VisibleForTesting
+    public boolean needToSwitchPhone(Phone phone) {
+        int subId = phone.getSubId();
+        int phoneId = phone.getPhoneId();
+
+        if (isSimReady(phoneId, subId)) return false;
+
+        boolean switchPhone = false;
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            Rlog.i(TAG, "needToSwitchPhone SIM absent");
+            if (phoneId != 0 || isThereOtherPhone(phoneId, true)) {
+                // Prefer default Phone or other Phone with a SIM regardless of lock state.
+                switchPhone = true;
+            }
+        } else {
+            Rlog.i(TAG, "needToSwitchPhone SIM not ready");
+            if ((phoneId == 0 && isThereOtherPhone(phoneId, false))
+                    || (phoneId != 0 && isThereOtherPhone(phoneId, true))) {
+                // If there is another one with a SIM ready, switch Phones.
+                // Otherwise, prefer default Phone if both SIMs are locked.
+                switchPhone = true;
+            }
+        }
+        Rlog.i(TAG, "needToSwitchPhone " + switchPhone);
+        return switchPhone;
+    }
+
+    private boolean isThereOtherPhone(int skipPhoneId, boolean ignoreLockState) {
+        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
+            int phoneId = phone.getPhoneId();
+            if (phoneId == skipPhoneId) {
+                continue;
+            }
+
+            int subId = phone.getSubId();
+            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+                Rlog.i(TAG, "isThereOtherPhone phoneId=" + phoneId + ", subId=" + subId);
+                continue;
+            }
+            int simState = mTelephonyManagerProxy.getSimState(phoneId);
+            if ((simState == TelephonyManager.SIM_STATE_READY) || (ignoreLockState
+                    && simState != TelephonyManager.SIM_STATE_ABSENT
+                    && simState != TelephonyManager.SIM_STATE_NOT_READY)) {
+                Rlog.i(TAG, "isThereOtherPhone found, ignoreLockState=" + ignoreLockState
+                        + ", phoneId=" + phoneId + ", simState=" + simState);
+                return true;
+            }
+            Rlog.i(TAG, "isThereOtherPhone phoneId=" + phoneId + ", simState=" + simState);
+        }
+
+        return false;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index f826f0b..14e7b76 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -2269,6 +2269,15 @@
         int error = evaluateOemSatelliteRequestAllowed(true);
         if (error == SATELLITE_RESULT_SUCCESS) {
             mNtnSignalStrengthChangedListeners.put(callback.asBinder(), callback);
+            synchronized (mNtnSignalsStrengthLock) {
+                try {
+                    callback.onNtnSignalStrengthChanged(mNtnSignalStrength);
+                    plogd("registerForNtnSignalStrengthChanged: " + mNtnSignalStrength);
+                } catch (RemoteException ex) {
+                    ploge("registerForNtnSignalStrengthChanged: RemoteException ex="
+                            + ex);
+                }
+            }
         } else {
             throw new RemoteException(new IllegalStateException("registration fails: " + error));
         }
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
index 3fe2970..0e938c1 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.satellite;
 
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.telephony.ServiceState.STATE_EMERGENCY_ONLY;
 import static android.telephony.ServiceState.STATE_IN_SERVICE;
 import static android.telephony.ServiceState.STATE_OUT_OF_SERVICE;
@@ -29,6 +30,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityOptions;
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
@@ -251,10 +253,11 @@
 
         selectEmergencyCallWaitForConnectionTimeoutDuration();
         if (mEmergencyConnection == null) {
-            handleStateChangedEventForHysteresisTimer();
             registerForInterestedStateChangedEvents();
         }
         mEmergencyConnection = connection;
+        handleStateChangedEventForHysteresisTimer();
+
         synchronized (mLock) {
             mCheckingAccessRestrictionInProgress = false;
             mIsSatelliteAllowedForCurrentLocation = false;
@@ -413,7 +416,6 @@
         for (Phone phone : PhoneFactory.getPhones()) {
             phone.registerForServiceStateChanged(
                     this, EVENT_SERVICE_STATE_CHANGED, null);
-            registerForImsRegistrationStateChanged(phone);
         }
     }
 
@@ -433,7 +435,6 @@
                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mISatelliteProvisionStateCallback);
         for (Phone phone : PhoneFactory.getPhones()) {
             phone.unregisterForServiceStateChanged(this);
-            unregisterForImsRegistrationStateChanged(phone);
         }
     }
 
@@ -525,7 +526,7 @@
     }
 
     private synchronized void handleStateChangedEventForHysteresisTimer() {
-        if (!isCellularAvailable()) {
+        if (!isCellularAvailable() && mEmergencyConnection != null) {
             startTimer();
         } else {
             logv("handleStateChangedEventForHysteresisTimer stopTimer");
@@ -701,10 +702,15 @@
             intent = new Intent(Intent.ACTION_SENDTO, uri);
         } else {
             intent = new Intent(action);
+            intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
         }
+        Bundle activityOptions = ActivityOptions.makeBasic()
+                .setPendingIntentCreatorBackgroundActivityStartMode(
+                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+                .toBundle();
         intent.setComponent(new ComponentName(packageName, className));
         return PendingIntent.getActivity(mContext, 0, intent,
-                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
+                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE, activityOptions);
     }
 
     private boolean isEmergencyCallToSatelliteHandoverTypeT911Enforced() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index 7795e42..09cfa6f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -2419,6 +2419,7 @@
     @Test
     public void testMmsCapabilityRemovedWhenMmsPreferredOnIwlan() throws Exception {
         doReturn(true).when(mFeatureFlags).forceIwlanMms();
+        doReturn(true).when(mDataConfigManager).isForceIwlanMmsFeatureEnabled();
         setupDataNetwork();
 
         assertThat(mDataNetworkUT.getNetworkCapabilities()
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/OWNERS b/tests/telephonytests/src/com/android/internal/telephony/domainselection/OWNERS
index 2a76770..5874c98 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/domainselection/OWNERS
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/OWNERS
@@ -1,7 +1,7 @@
 # automatically inherit owners from fw/opt/telephony
 
 hwangoo@google.com
-forestchoi@google.com
+jaesikkong@google.com
 avinashmp@google.com
 mkoon@google.com
 seheele@google.com
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
index f05099d..0eb5c13 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
@@ -3171,6 +3171,207 @@
                 anyBoolean(), eq(0));
     }
 
+    /**
+     * Test Phone selection.
+     * SIM absent and SIM ready on the other Phone.
+     */
+    @Test
+    @SmallTest
+    public void testSwitchPhoneAbsentAndReady() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        Phone phone1 = getPhone(1);
+
+        // Phone0
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+                .when(phone0).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_ABSENT)
+                .when(mTelephonyManagerProxy).getSimState(eq(0));
+
+        // Phone1
+        doReturn(2).when(phone1).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_READY)
+                .when(mTelephonyManagerProxy).getSimState(eq(1));
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(
+                phone0, mTestConnection1, true);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        // Expect: DisconnectCause#EMERGENCY_PERM_FAILURE
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.EMERGENCY_PERM_FAILURE));
+        verify(phone0, never()).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    /**
+     * Test Phone selection.
+     * PIN locked and SIM ready on the other Phone.
+     */
+    @Test
+    @SmallTest
+    public void testSwitchPhonePinLockedAndReady() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        Phone phone1 = getPhone(1);
+
+        // Phone0
+        doReturn(1).when(phone0).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+                .when(mTelephonyManagerProxy).getSimState(eq(0));
+
+        // Phone1
+        doReturn(2).when(phone1).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_READY)
+                .when(mTelephonyManagerProxy).getSimState(eq(1));
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(
+                phone0, mTestConnection1, true);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        // Expect: DisconnectCause#EMERGENCY_PERM_FAILURE
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.EMERGENCY_PERM_FAILURE));
+        verify(phone0, never()).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    /**
+     * Test Phone selection.
+     * SIM ready and SIM ready on the other Phone.
+     */
+    @Test
+    @SmallTest
+    public void testSwitchPhoneReadyAndReady() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        Phone phone1 = getPhone(1);
+
+        // Phone0
+        doReturn(1).when(phone0).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_READY)
+                .when(mTelephonyManagerProxy).getSimState(eq(0));
+
+        // Phone1
+        doReturn(2).when(phone1).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_READY)
+                .when(mTelephonyManagerProxy).getSimState(eq(1));
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(
+                phone0, mTestConnection1, true);
+        processAllMessages();
+
+        assertFalse(future.isDone());
+        verify(phone0).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    /**
+     * Test Phone selection.
+     * PIN locked and PIN locked on the other Phone.
+     */
+    @Test
+    @SmallTest
+    public void testSwitchPhonePinLockedAndPinLocked() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        Phone phone1 = getPhone(1);
+
+        // Phone0
+        doReturn(1).when(phone0).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+                .when(mTelephonyManagerProxy).getSimState(eq(0));
+
+        // Phone1
+        doReturn(2).when(phone1).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+                .when(mTelephonyManagerProxy).getSimState(eq(1));
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(
+                phone0, mTestConnection1, true);
+        processAllMessages();
+
+        assertFalse(future.isDone());
+        verify(phone0).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    /**
+     * Test Phone selection.
+     * SIM absent and SIM absent on default Phone.
+     */
+    @Test
+    @SmallTest
+    public void testSwitchPhoneAbsentAndAbsentOnDefaultPhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        Phone phone1 = getPhone(1);
+
+        // Phone0
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+                .when(phone0).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_ABSENT)
+                .when(mTelephonyManagerProxy).getSimState(eq(0));
+
+        // Phone1
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+                .when(phone1).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_ABSENT)
+                .when(mTelephonyManagerProxy).getSimState(eq(1));
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(
+                phone1, mTestConnection1, true);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        // Expect: DisconnectCause#EMERGENCY_PERM_FAILURE
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.EMERGENCY_PERM_FAILURE));
+        verify(phone1, never()).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    /**
+     * Test Phone selection.
+     * PIN locked and PIN locked on default Phone.
+     */
+    @Test
+    @SmallTest
+    public void testSwitchPhonePinLockedandPinLockedOnDefaultPhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        Phone phone1 = getPhone(1);
+
+        // Phone0
+        doReturn(1).when(phone0).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+                .when(mTelephonyManagerProxy).getSimState(eq(0));
+
+        // Phone1
+        doReturn(2).when(phone1).getSubId();
+        doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+                .when(mTelephonyManagerProxy).getSimState(eq(1));
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(
+                phone1, mTestConnection1, true);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        // Expect: DisconnectCause#EMERGENCY_PERM_FAILURE
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.EMERGENCY_PERM_FAILURE));
+        verify(phone1, never()).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
     private EmergencyStateTracker setupEmergencyStateTracker(
             boolean isSuplDdsSwitchRequiredForEmergencyCall) {
         doReturn(mPhoneSwitcher).when(mPhoneSwitcherProxy).getPhoneSwitcher();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index da40c32..d9ef95a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -2389,6 +2389,10 @@
         verifyRegisterForNtnSignalStrengthChanged(SUB_ID, callback,
                 SATELLITE_RESULT_SUCCESS);
         verifyRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+        processAllMessages();
+        assertTrue(waitForForEvents(
+                semaphore, 1, "testRegisterForNtnSignalStrengthChanged"));
+        assertEquals(expectedLevel, signalStrength[0].getLevel());
 
         expectedLevel = NTN_SIGNAL_STRENGTH_GOOD;
         sendNtnSignalStrengthChangedEvent(expectedLevel, null);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
index 876fc51..f4fa48e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony.satellite;
 
-import static android.telephony.ServiceState.STATE_IN_SERVICE;
 import static android.telephony.ServiceState.STATE_OUT_OF_SERVICE;
 import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
 import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT;
@@ -193,14 +192,25 @@
                 DEFAULT_HANDOVER_INTENT_ACTION);
     }
 
+    @Test
+    public void testStartTimer_emergencyCallNull() {
+        when(mServiceState.getState()).thenReturn(STATE_OUT_OF_SERVICE);
+        when(mServiceState2.getState()).thenReturn(STATE_OUT_OF_SERVICE);
+        mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
+        mTestSOSMessageRecommender.onEmergencyCallStarted(null);
+        processAllMessages();
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+    }
+
     private void testTimeoutBeforeEmergencyCallEnd(int expectedHandoverType,
             String expectedPackageName, String expectedClassName, String expectedAction) {
         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
         processAllMessages();
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1,  1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
 
         // Move Location service to emergency mode
@@ -220,8 +230,8 @@
             assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
                     expectedHandoverType, expectedPackageName, expectedClassName, expectedAction));
         }
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
     }
 
     @Test
@@ -232,8 +242,8 @@
         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
         processAllMessages();
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
 
         // Move Location service to emergency mode
@@ -247,8 +257,8 @@
         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
         processAllMessages();
         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
     }
 
     @Test
@@ -259,8 +269,8 @@
         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
         processAllMessages();
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
 
         // Move Location service to emergency mode
@@ -277,8 +287,8 @@
                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911,
                 DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS,
                 DEFAULT_T911_HANDOVER_INTENT_ACTION));
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         mTestSatelliteController.isOemEnabledSatelliteSupported = true;
     }
 
@@ -299,45 +309,8 @@
         processAllMessages();
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
-        assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
-
-        when(mPhone.isImsRegistered()).thenReturn(true);
-        when(mServiceState.getState()).thenReturn(STATE_IN_SERVICE);
-        mTestImsManager.sendImsRegistrationStateChangedEvent(0, true);
-        processAllMessages();
-
-        assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
-        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
-        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
-
-        when(mPhone.isImsRegistered()).thenReturn(false);
-        when(mServiceState.getState()).thenReturn(STATE_OUT_OF_SERVICE);
-        mTestImsManager.sendImsRegistrationStateChangedEvent(0, true);
-        processAllMessages();
-
-        assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
-        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
-        assertEquals(2, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
-
-        when(mPhone.isImsRegistered()).thenReturn(false);
-        when(mPhone2.isImsRegistered()).thenReturn(true);
-        when(mServiceState.getState()).thenReturn(STATE_IN_SERVICE);
-        mTestImsManager.sendImsRegistrationStateChangedEvent(1, true);
-        processAllMessages();
-        assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
-        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
-        assertEquals(2, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
-
-        when(mPhone2.isImsRegistered()).thenReturn(false);
-        when(mServiceState.getState()).thenReturn(STATE_OUT_OF_SERVICE);
-        mTestImsManager.sendImsRegistrationStateChangedEvent(1, false);
-        processAllMessages();
-        assertEquals(3, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
 
         // Move Location service to emergency mode
@@ -354,8 +327,8 @@
         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
     }
 
@@ -366,8 +339,8 @@
 
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
 
         mTestSatelliteController.sendProvisionStateChangedEvent(
                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false);
@@ -375,15 +348,15 @@
 
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
 
         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
         processAllMessages();
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 2, 4, 2);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 2, 4, 2);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 2, 2);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 2, 2);
 
         // Move Location service to emergency mode
         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
@@ -405,8 +378,8 @@
                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 2, 4, 2);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 2, 4, 2);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 2, 2);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 2, 2);
     }
 
     @Test
@@ -416,8 +389,8 @@
         processAllMessages();
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
 
         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
@@ -425,8 +398,8 @@
         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
 
         // Move Location service to emergency mode
         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
@@ -442,8 +415,8 @@
         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
     }
@@ -479,8 +452,8 @@
 
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
 
         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
                 WRONG_CALL_ID, Connection.STATE_ACTIVE);
@@ -489,8 +462,8 @@
         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
     }
 
     @Test
@@ -514,10 +487,10 @@
 
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
     }
 
     @Test
@@ -586,8 +559,8 @@
 
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
 
         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(CALL_ID, connectionState);
         processAllMessages();
@@ -595,8 +568,8 @@
         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
     }
 
     private void testCellularServiceStateChangedBeforeTimeout(
@@ -608,8 +581,8 @@
         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
 
         when(mServiceState.getState()).thenReturn(availableServiceState);
         mTestSOSMessageRecommender.sendServiceStateChangedEvent();
@@ -617,8 +590,8 @@
         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 0, 0, 0);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 0, 0);
 
         when(mServiceState.getState()).thenReturn(unavailableServiceState);
         when(mServiceState2.getState()).thenReturn(availableServiceState);
@@ -647,28 +620,24 @@
         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
-        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
-        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
     }
 
-    private void assertRegisterForStateChangedEventsTriggered(
-            Phone phone, int registerForProvisionCount, int registerForImsCount,
-            int registerForCellularCount) {
+    private void assertRegisterForStateChangedEventsTriggered(Phone phone,
+            int registerForProvisionCount, int registerForCellularCount) {
         assertEquals(registerForProvisionCount,
                 mTestSatelliteController.getRegisterForSatelliteProvisionStateChangedCalls());
-        assertEquals(registerForImsCount, mTestImsManager.getAddRegistrationCallbackCalls());
         verify(phone, times(registerForCellularCount))
                 .registerForServiceStateChanged(any(), anyInt(), any());
     }
 
     private void assertUnregisterForStateChangedEventsTriggered(
-            Phone phone, int unregisterForProvisionCount, int unregisterForImsCount,
-            int unregisterForCellularCount) {
+            Phone phone, int unregisterForProvisionCount, int unregisterForCellularCount) {
         assertEquals(unregisterForProvisionCount,
                 mTestSatelliteController.getUnregisterForSatelliteProvisionStateChangedCalls());
-        assertEquals(unregisterForImsCount, mTestImsManager.getRemoveRegistrationListenerCalls());
         verify(phone, times(unregisterForCellularCount)).unregisterForServiceStateChanged(any());
     }