summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hwangoo Park <hwangoo@google.com> 2025-03-11 02:19:10 +0000
committer Hwangoo Park <hwangoo@google.com> 2025-03-11 02:19:10 +0000
commite0e16e47ed50b1548ebe8e4afc3c31c7f293dbb3 (patch)
tree5ffb307586eef2da172c85032e45c4910f983fd5
parent5f1d65d85918f3be7b73c98f8157b11a79a0282a (diff)
Update satellite mode condition for emergency call
This change is to update the conditions to check whether the modem is currently in satellite mode when making an emergency call by adding the various conditions such as the device or carrier configurations. Bug: 398929326 Flag: EXEMPT bugfix Test: atest EmergencyStateTrackerTest Test: manual (verified emergency call while in satellite mode) Change-Id: I0578cb9435a50058b6a4a57a90e7462b4efb52d5
-rw-r--r--src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java97
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java108
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 3c95d77afc..220a368960 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
@@ -472,13 +476,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);
}
}
@@ -499,12 +514,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,
@@ -541,6 +562,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
@@ -551,6 +578,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) {
@@ -558,6 +587,10 @@ public class EmergencyStateTracker {
mHandler = new MyHandler(looper);
mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall;
mWaitForInServiceTimeoutMs = waitForInServiceTimeout;
+ mTurnOffOemEnabledSatelliteDuringEmergencyCall =
+ turnOffOemEnabledSatelliteDuringEmergencyCall;
+ mTurnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall =
+ turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall;
mPhoneFactoryProxy = phoneFactoryProxy;
mPhoneSwitcherProxy = phoneSwitcherProxy;
mTelephonyManagerProxy = telephonyManagerProxy;
@@ -1714,8 +1747,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()) {
@@ -1751,7 +1783,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);
@@ -1784,7 +1816,7 @@ public class EmergencyStateTracker {
return false;
}
return phone.getServiceStateTracker().isRadioOn()
- && !satelliteController.isSatelliteEnabledOrBeingEnabled();
+ && !shouldExitSatelliteMode();
}
@Override
@@ -1796,7 +1828,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 {
@@ -2306,4 +2338,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 28edeae002..e6533c80c1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
@@ -82,6 +82,7 @@ import com.android.internal.telephony.PhoneConstants;
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;
@@ -89,6 +90,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;
@@ -140,8 +142,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());
}
@@ -149,8 +153,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();
@@ -3291,6 +3297,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.
@@ -3494,11 +3585,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);
}