Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0e16e47 authored by Hwangoo Park's avatar Hwangoo Park
Browse files

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
parent 5f1d65d8
Loading
Loading
Loading
Loading
+90 −7
Original line number Diff line number Diff line
@@ -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;
            }
        }
    }
}
+104 −4
Original line number Diff line number Diff line
@@ -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);
    }