diff options
author | 2025-03-20 16:54:44 -0700 | |
---|---|---|
committer | 2025-03-20 16:54:44 -0700 | |
commit | 964afa32854b79efd481aca7c820af8b53da94fb (patch) | |
tree | 23f508828d91bb384117b57d41e83512eed9b3c4 | |
parent | affac042eb60e249d4cbb496b971dbd0e352314b (diff) | |
parent | e0e16e47ed50b1548ebe8e4afc3c31c7f293dbb3 (diff) |
Merge "Update satellite mode condition for emergency call" into main
-rw-r--r-- | src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java | 97 | ||||
-rw-r--r-- | tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java | 108 |
2 files changed, 194 insertions, 11 deletions
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java index ee00e45dca..4a3ab21c55 100644 --- a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java +++ b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java @@ -74,6 +74,8 @@ import com.android.internal.telephony.data.PhoneSwitcher; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.imsphone.ImsPhoneConnection; import com.android.internal.telephony.satellite.SatelliteController; +import com.android.internal.telephony.subscription.SubscriptionInfoInternal; +import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.telephony.Rlog; import java.lang.annotation.Retention; @@ -141,6 +143,8 @@ public class EmergencyStateTracker { private final Handler mHandler; private final boolean mIsSuplDdsSwitchRequiredForEmergencyCall; private final int mWaitForInServiceTimeoutMs; + private final boolean mTurnOffOemEnabledSatelliteDuringEmergencyCall; + private final boolean mTurnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall; private final PowerManager.WakeLock mWakeLock; private RadioOnHelper mRadioOnHelper; @EmergencyConstants.EmergencyMode @@ -488,13 +492,24 @@ public class EmergencyStateTracker { * @param context The context of the application. * @param isSuplDdsSwitchRequiredForEmergencyCall Whether gnss supl requires default data for * emergency call. + * @param turnOffOemEnabledSatelliteDuringEmergencyCall Specifying whether OEM enabled satellite + * should be turned off during emergency + * call. + * @param turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall Specifying whether non-emergency + * NB-IOT NTN satellite should be + * turned off for emergency call. * @param featureFlags The telephony feature flags. */ public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall, - int waitForInServiceTimeout, @NonNull FeatureFlags featureFlags) { + int waitForInServiceTimeout, boolean turnOffOemEnabledSatelliteDuringEmergencyCall, + boolean turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall, + @NonNull FeatureFlags featureFlags) { if (INSTANCE == null) { INSTANCE = new EmergencyStateTracker(context, Looper.myLooper(), - isSuplDdsSwitchRequiredForEmergencyCall, waitForInServiceTimeout, featureFlags); + isSuplDdsSwitchRequiredForEmergencyCall, waitForInServiceTimeout, + turnOffOemEnabledSatelliteDuringEmergencyCall, + turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall, + featureFlags); } } @@ -515,12 +530,18 @@ public class EmergencyStateTracker { */ private EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, int waitForInServiceTimeout, + boolean turnOffOemEnabledSatelliteDuringEmergencyCall, + boolean turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall, @NonNull FeatureFlags featureFlags) { mEcmExitTimeoutMs = DEFAULT_ECM_EXIT_TIMEOUT_MS; mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mWaitForInServiceTimeoutMs = waitForInServiceTimeout; + mTurnOffOemEnabledSatelliteDuringEmergencyCall = + turnOffOemEnabledSatelliteDuringEmergencyCall; + mTurnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall = + turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall; mFeatureFlags = featureFlags; PowerManager pm = context.getSystemService(PowerManager.class); mWakeLock = (pm != null) ? pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, @@ -557,6 +578,12 @@ public class EmergencyStateTracker { * modem to get in-service state when emergency * call is dialed in airplane mode before * starting the emergency call. + * @param turnOffOemEnabledSatelliteDuringEmergencyCall Specifying whether OEM enabled satellite + * should be turned off during emergency + * call. + * @param turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall Specifying whether non-emergency + * NB-IOT NTN satellite should be + * turned off for emergency call. * @param phoneFactoryProxy The {@link PhoneFactoryProxy} to be injected. * @param phoneSwitcherProxy The {@link PhoneSwitcherProxy} to be injected. * @param telephonyManagerProxy The {@link TelephonyManagerProxy} to be @@ -567,6 +594,8 @@ public class EmergencyStateTracker { @VisibleForTesting public EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, int waitForInServiceTimeout, + boolean turnOffOemEnabledSatelliteDuringEmergencyCall, + boolean turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall, PhoneFactoryProxy phoneFactoryProxy, PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy, RadioOnHelper radioOnHelper, long ecmExitTimeoutMs, FeatureFlags featureFlags) { @@ -574,6 +603,10 @@ public class EmergencyStateTracker { mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mWaitForInServiceTimeoutMs = waitForInServiceTimeout; + mTurnOffOemEnabledSatelliteDuringEmergencyCall = + turnOffOemEnabledSatelliteDuringEmergencyCall; + mTurnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall = + turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall; mPhoneFactoryProxy = phoneFactoryProxy; mPhoneSwitcherProxy = phoneSwitcherProxy; mTelephonyManagerProxy = telephonyManagerProxy; @@ -1732,8 +1765,7 @@ public class EmergencyStateTracker { boolean isTestEmergencyNumber) { final boolean isAirplaneModeOn = isAirplaneModeOn(mContext); boolean needToTurnOnRadio = !isRadioOn() || isAirplaneModeOn; - final SatelliteController satelliteController = SatelliteController.getInstance(); - boolean needToTurnOffSatellite = satelliteController.isSatelliteEnabledOrBeingEnabled(); + boolean needToTurnOffSatellite = shouldExitSatelliteMode(); if (isAirplaneModeOn && !isPowerOff() && !phone.getServiceStateTracker().getDesiredPowerState()) { @@ -1769,7 +1801,7 @@ public class EmergencyStateTracker { return; } if (!isRadioReady) { - if (satelliteController.isSatelliteEnabledOrBeingEnabled()) { + if (shouldExitSatelliteMode()) { // Could not turn satellite off Rlog.e(TAG, "Failed to turn off satellite modem."); completeEmergencyMode(emergencyType, DisconnectCause.SATELLITE_ENABLED); @@ -1802,7 +1834,7 @@ public class EmergencyStateTracker { return false; } return phone.getServiceStateTracker().isRadioOn() - && !satelliteController.isSatelliteEnabledOrBeingEnabled(); + && !shouldExitSatelliteMode(); } @Override @@ -1814,7 +1846,7 @@ public class EmergencyStateTracker { } // onTimeout shall be called only with the Phone for emergency return phone.getServiceStateTracker().isRadioOn() - && !satelliteController.isSatelliteEnabledOrBeingEnabled(); + && !shouldExitSatelliteMode(); } }, !isTestEmergencyNumber, phone, isTestEmergencyNumber, waitForInServiceTimeout); } else { @@ -2324,4 +2356,55 @@ public class EmergencyStateTracker { return false; } + + /** + * Checks whether the satellite mode should be turned off to proceed with an emergency call + * when satellite mode is enabled or an NTN(Non Terrestrial Network) session is in progress. + * + * @return {@code true} if satellite mode should be exited before an emergency call is being + * processed, {@code false} otherwise. + */ + @VisibleForTesting + public boolean shouldExitSatelliteMode() { + final SatelliteController satelliteController = SatelliteController.getInstance(); + + if (!satelliteController.isSatelliteEnabledOrBeingEnabled()) { + return false; + } + + if (!mTurnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall) { + // Carrier + return false; + } + + if (satelliteController.isDemoModeEnabled()) { + // If user makes emergency call in demo mode, end the satellite session + return true; + } else if (mFeatureFlags.carrierRoamingNbIotNtn() + && !satelliteController.getRequestIsEmergency()) { + // If satellite is not for emergency, end the satellite session + return true; + } else { // satellite is for emergency + if (mFeatureFlags.carrierRoamingNbIotNtn()) { + int subId = satelliteController.getSelectedSatelliteSubId(); + SubscriptionInfoInternal info = SubscriptionManagerService.getInstance() + .getSubscriptionInfoInternal(subId); + if (info == null) { + Rlog.e(TAG, "satellite is/being enabled, but satellite sub " + + subId + " is null"); + return false; + } + + if (info.getOnlyNonTerrestrialNetwork() == 1) { + // OEM + return mTurnOffOemEnabledSatelliteDuringEmergencyCall; + } else { + // Carrier + return satelliteController.shouldTurnOffCarrierSatelliteForEmergencyCall(); + } + } else { + return mTurnOffOemEnabledSatelliteDuringEmergencyCall; + } + } + } } 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 2909966b2b..d50e781f2c 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java @@ -84,6 +84,7 @@ import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.data.PhoneSwitcher; +import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import org.junit.After; import org.junit.Before; @@ -91,6 +92,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.ArrayList; @@ -149,8 +151,10 @@ public class EmergencyStateTrackerTest extends TelephonyTest { EmergencyStateTracker.getInstance(); }); - EmergencyStateTracker - .make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mFeatureFlags); + EmergencyStateTracker.make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, + true, /* turnOffOemEnabledSatelliteDuringEmergencyCall */ + true, /* turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall */ + mFeatureFlags); assertNotNull(EmergencyStateTracker.getInstance()); } @@ -158,8 +162,10 @@ public class EmergencyStateTrackerTest extends TelephonyTest { @Test @SmallTest public void getInstance_returnsSameInstance() { - EmergencyStateTracker - .make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mFeatureFlags); + EmergencyStateTracker.make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, + true, /* turnOffOemEnabledSatelliteDuringEmergencyCall */ + true, /* turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall */ + mFeatureFlags); EmergencyStateTracker instance1 = EmergencyStateTracker.getInstance(); EmergencyStateTracker instance2 = EmergencyStateTracker.getInstance(); @@ -3300,6 +3306,91 @@ public class EmergencyStateTrackerTest extends TelephonyTest { anyBoolean(), eq(0)); } + @Test + @SmallTest + public void testShouldExitSatelliteModeWhenSatelliteModeNotEnabled() { + // Satellite mode is not enabled. + doReturn(false).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); + EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(true); + + assertFalse(emergencyStateTracker.shouldExitSatelliteMode()); + } + + @Test + @SmallTest + public void testShouldExitSatelliteModeWhenConfigTurnOffNonEmergencyNbIotNtnSessionDisabled() { + doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); + // Config for turning off non-emergency NB-IOT NTN session for emergency call: false + EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(true, true, false); + + assertFalse(emergencyStateTracker.shouldExitSatelliteMode()); + } + + @Test + @SmallTest + public void testShouldExitSatelliteModeWhenSatelliteDemoModeEnabled() { + doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); + // Satellite demo mode is enabled + doReturn(true).when(mSatelliteController).isDemoModeEnabled(); + EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(true, true, true); + + assertTrue(emergencyStateTracker.shouldExitSatelliteMode()); + } + + @Test + @SmallTest + public void testShouldExitSatelliteModeWhenCarrierRoamingNbIotNtnEnabledAndNtnNonEmergency() { + // carrierRoamingNbIotNtn feature enabled + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true); + doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); + doReturn(false).when(mSatelliteController).isDemoModeEnabled(); + // NTN non-emergency session is in progress + doReturn(false).when(mSatelliteController).getRequestIsEmergency(); + + EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(true, true, true); + + assertTrue(emergencyStateTracker.shouldExitSatelliteMode()); + } + + @Test + @SmallTest + public void testShouldExitSatelliteModeWhenNtnEmergency() { + // carrierRoamingNbIotNtn feature enabled + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true); + doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled(); + doReturn(false).when(mSatelliteController).isDemoModeEnabled(); + doReturn(true).when(mSatelliteController).getRequestIsEmergency(); + doReturn(null).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt()); + + boolean turnOffOemEnabledSatelliteDuringEmergencyCall = true; + EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker( + true, turnOffOemEnabledSatelliteDuringEmergencyCall, true); + + // No valid subscription + assertFalse(emergencyStateTracker.shouldExitSatelliteMode()); + + SubscriptionInfoInternal subInfo = Mockito.mock(SubscriptionInfoInternal.class); + doReturn(1).when(subInfo).getOnlyNonTerrestrialNetwork(); + doReturn(subInfo).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt()); + + // Only non-terrestrial networks + assertEquals(turnOffOemEnabledSatelliteDuringEmergencyCall, + emergencyStateTracker.shouldExitSatelliteMode()); + + doReturn(0).when(subInfo).getOnlyNonTerrestrialNetwork(); + + // Not only non-terrestrial networks + emergencyStateTracker.shouldExitSatelliteMode(); + + verify(mSatelliteController).shouldTurnOffCarrierSatelliteForEmergencyCall(); + + // carrierRoamingNbIotNtn feature disabled + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(false); + + assertEquals(turnOffOemEnabledSatelliteDuringEmergencyCall, + emergencyStateTracker.shouldExitSatelliteMode()); + } + /** * Test Phone selection. * SIM absent and SIM ready on the other Phone. @@ -3571,11 +3662,20 @@ public class EmergencyStateTrackerTest extends TelephonyTest { private EmergencyStateTracker setupEmergencyStateTracker( boolean isSuplDdsSwitchRequiredForEmergencyCall) { + return setupEmergencyStateTracker(isSuplDdsSwitchRequiredForEmergencyCall, true, true); + } + + private EmergencyStateTracker setupEmergencyStateTracker( + boolean isSuplDdsSwitchRequiredForEmergencyCall, + boolean turnOffOemEnabledSatelliteDuringEmergencyCall, + boolean turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall) { doReturn(mPhoneSwitcher).when(mPhoneSwitcherProxy).getPhoneSwitcher(); doNothing().when(mPhoneSwitcher).overrideDefaultDataForEmergency( anyInt(), anyInt(), any()); return new EmergencyStateTracker(mContext, mTestableLooper.getLooper(), isSuplDdsSwitchRequiredForEmergencyCall, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, + turnOffOemEnabledSatelliteDuringEmergencyCall, + turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall, mPhoneFactoryProxy, mPhoneSwitcherProxy, mTelephonyManagerProxy, mRadioOnHelper, TEST_ECM_EXIT_TIMEOUT_MS, mFeatureFlags); } |