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

Commit f1f753f9 authored by Hunsuk Choi's avatar Hunsuk Choi
Browse files

Wait for the delayed power off

The radio power off can be delayed to disconnect data connections
when turning on airplane mode.

If emergency call is requested before the completion of power off
EmergencyStateTracker should wait for the completion of delayed
operation before turning on power again.

Bug: 332680076
Test: atest EmergencyStateTrackerTest
Change-Id: I19732d22076a898969ab1abe600246c67d868ff5
parent 3cab17f0
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ public class EmergencyStateTracker {
    private EmergencyRegistrationResult mLastEmergencyRegistrationResult;
    private boolean mIsEmergencyModeInProgress;
    private boolean mIsEmergencyCallStartedDuringEmergencySms;
    private boolean mIsWaitingForRadioOff;

    /** For emergency calls */
    private final long mEcmExitTimeoutMs;
@@ -268,6 +269,8 @@ public class EmergencyStateTracker {
    private static final int MSG_EXIT_SCBM = 4;
    @VisibleForTesting
    public static final int MSG_NEW_RINGING_CONNECTION = 5;
    @VisibleForTesting
    public static final int MSG_VOICE_REG_STATE_CHANGED = 6;

    private class MyHandler extends Handler {

@@ -431,6 +434,16 @@ public class EmergencyStateTracker {
                    handleNewRingingConnection(msg);
                    break;
                }
                case MSG_VOICE_REG_STATE_CHANGED: {
                    if (mIsWaitingForRadioOff && isPowerOff()) {
                        unregisterForVoiceRegStateOrRatChanged();
                        if (mPhone != null) {
                            turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL,
                                    mIsTestEmergencyNumber);
                        }
                    }
                    break;
                }
                default:
                    break;
            }
@@ -643,6 +656,7 @@ public class EmergencyStateTracker {
            mOngoingConnection = null;
            mOngoingCallProperties = 0;
            sendEmergencyCallStateChange(mPhone, false);
            unregisterForVoiceRegStateOrRatChanged();
        }

        if (wasActive && mActiveEmergencyCalls.isEmpty()
@@ -1494,6 +1508,34 @@ public class EmergencyStateTracker {
        return result;
    }

    /**
     * Returns {@code true} if service states of all phones from PhoneFactory are radio off.
     */
    private boolean isPowerOff() {
        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
            ServiceState ss = phone.getServiceStateTracker().getServiceState();
            if (ss.getState() != ServiceState.STATE_POWER_OFF) return false;
        }
        return true;
    }

    private void registerForVoiceRegStateOrRatChanged() {
        if (mIsWaitingForRadioOff) return;
        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
            phone.getServiceStateTracker().registerForVoiceRegStateOrRatChanged(mHandler,
                    MSG_VOICE_REG_STATE_CHANGED, null);
        }
        mIsWaitingForRadioOff = true;
    }

    private void unregisterForVoiceRegStateOrRatChanged() {
        if (!mIsWaitingForRadioOff) return;
        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
            phone.getServiceStateTracker().unregisterForVoiceRegStateOrRatChanged(mHandler);
        }
        mIsWaitingForRadioOff = false;
    }

    /**
     * Returns {@code true} if airplane mode is on.
     */
@@ -1524,6 +1566,14 @@ public class EmergencyStateTracker {
        final SatelliteController satelliteController = SatelliteController.getInstance();
        boolean needToTurnOffSatellite = satelliteController.isSatelliteEnabled();

        if (isAirplaneModeOn && !isPowerOff()
                && !phone.getServiceStateTracker().getDesiredPowerState()) {
            // power off is delayed to disconnect data connections
            Rlog.i(TAG, "turnOnRadioAndSwitchDds: wait for the delayed power off");
            registerForVoiceRegStateOrRatChanged();
            return;
        }

        if (needToTurnOnRadio || needToTurnOffSatellite) {
            Rlog.i(TAG, "turnOnRadioAndSwitchDds: phoneId=" + phone.getPhoneId() + " for "
                    + emergencyTypeToString(emergencyType));
+24 −0
Original line number Diff line number Diff line
@@ -3000,6 +3000,30 @@ public class EmergencyStateTrackerTest extends TelephonyTest {
        verify(phone0, times(2)).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
    }

    /**
     * Test that the EmergencyStateTracker waits for the delayed radio power off.
     */
    @Test
    @SmallTest
    public void startEmergencyCall_delayedRadioOff_waitForRadioOff() {
        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
        // Create test Phones and set radio on
        Phone testPhone = setupTestPhoneForEmergencyCall(false /* isRoaming */,
                true /* isRadioOn */);

        // Airplane mode is ON, but radio power state is still ON
        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);

        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
                mTestConnection1, false);

        // Wait for the radio off for all phones
        verify(mSST, times(2)).registerForVoiceRegStateOrRatChanged(any(), anyInt(), any());
        verify(mRadioOnHelper, never()).triggerRadioOnAndListen(any(), anyBoolean(), any(),
                anyBoolean(), eq(0));
    }

    private EmergencyStateTracker setupEmergencyStateTracker(
            boolean isSuplDdsSwitchRequiredForEmergencyCall) {
        doReturn(mPhoneSwitcher).when(mPhoneSwitcherProxy).getPhoneSwitcher();