Loading src/java/com/android/internal/telephony/ServiceStateTracker.java +10 −1 Original line number Diff line number Diff line Loading @@ -1164,6 +1164,9 @@ public class ServiceStateTracker extends Handler { mDesiredPowerState = power; setPowerStateToDesired(forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply); if (mDesiredPowerState) { SatelliteController.getInstance().onSetCellularRadioPowerStateRequested(true); } } /** Loading Loading @@ -1325,6 +1328,12 @@ public class ServiceStateTracker extends Handler { // Hence, issuing shut down regardless of radio power response mCi.requestShutdown(null); } ar = (AsyncResult) msg.obj; if (ar.exception != null) { loge("EVENT_RADIO_POWER_OFF_DONE: exception=" + ar.exception); SatelliteController.getInstance().onPowerOffCellularRadioFailed(); } break; // GSM Loading Loading @@ -4979,7 +4988,7 @@ public class ServiceStateTracker extends Handler { */ public void powerOffRadioSafely() { synchronized (this) { SatelliteController.getInstance().onCellularRadioPowerOffRequested(); SatelliteController.getInstance().onSetCellularRadioPowerStateRequested(false); if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { EmergencyStateTracker.getInstance().onCellularRadioPowerOffRequested(); } Loading src/java/com/android/internal/telephony/satellite/SatelliteController.java +91 −16 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ public class SatelliteController extends Handler { private static final int EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT = 46; private static final int EVENT_WIFI_CONNECTIVITY_STATE_CHANGED = 47; private static final int EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT = 48; protected static final int EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT = 49; @NonNull private static SatelliteController sInstance; @NonNull private final Context mContext; Loading Loading @@ -344,9 +345,13 @@ public class SatelliteController extends Handler { private final Object mIsSatelliteEnabledLock = new Object(); @GuardedBy("mIsSatelliteEnabledLock") private Boolean mIsSatelliteEnabled = null; private final Object mIsRadioOnLock = new Object(); @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected final Object mIsRadioOnLock = new Object(); @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected boolean mIsRadioOn; @GuardedBy("mIsRadioOnLock") private boolean mIsRadioOn = false; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected boolean mRadioOffRequested = false; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected final Object mSatelliteViaOemProvisionLock = new Object(); @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading Loading @@ -1325,6 +1330,14 @@ public class SatelliteController extends Handler { mIsRadioOn = true; } else if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) { resetCarrierRoamingSatelliteModeParams(); synchronized (mIsRadioOnLock) { if (mRadioOffRequested) { logd("EVENT_RADIO_STATE_CHANGED: set mIsRadioOn to false"); stopWaitForCellularModemOffTimer(); mIsRadioOn = false; mRadioOffRequested = false; } } } } Loading Loading @@ -1635,6 +1648,13 @@ public class SatelliteController extends Handler { break; } case EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT: { plogw("Timed out to wait for cellular modem OFF state"); synchronized (mIsRadioOnLock) { mRadioOffRequested = false; } } default: Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " + msg.what); Loading Loading @@ -1716,6 +1736,12 @@ public class SatelliteController extends Handler { SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result); return; } if (mRadioOffRequested) { ploge("Radio is being powering off, can not enable satellite"); sendErrorAndReportSessionMetrics( SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result); return; } } if (mTelecomManager.isInEmergencyCall()) { Loading Loading @@ -2900,27 +2926,50 @@ public class SatelliteController extends Handler { /** * This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify * {@link SatelliteController} that it has received a request to power off the cellular radio * modem. {@link SatelliteController} will then power off the satellite modem. * {@link SatelliteController} that it has received a request to power on or off the cellular * radio modem. * * @param powerOn {@code true} means cellular radio is about to be powered on, {@code false} * means cellular modem is about to be powered off. */ public void onCellularRadioPowerOffRequested() { logd("onCellularRadioPowerOffRequested()"); public void onSetCellularRadioPowerStateRequested(boolean powerOn) { logd("onSetCellularRadioPowerStateRequested: powerOn=" + powerOn); if (!mFeatureFlags.oemEnabledSatelliteFlag()) { plogd("onCellularRadioPowerOffRequested: oemEnabledSatelliteFlag is disabled"); plogd("onSetCellularRadioPowerStateRequested: oemEnabledSatelliteFlag is disabled"); return; } synchronized (mIsRadioOnLock) { mIsRadioOn = false; mRadioOffRequested = !powerOn; } if (powerOn) { stopWaitForCellularModemOffTimer(); } else { requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false /* enableSatellite */, false /* enableDemoMode */, false /* isEmergency */, false /* enableSatellite */, false /* enableDemoMode */, false /* isEmergency */, new IIntegerConsumer.Stub() { @Override public void accept(int result) { plogd("onRadioPowerOffRequested: requestSatelliteEnabled result=" + result); plogd("onSetCellularRadioPowerStateRequested: requestSatelliteEnabled" + " result=" + result); } }); startWaitForCellularModemOffTimer(); } } /** * This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify * {@link SatelliteController} that the request to power off the cellular radio modem has * failed. */ public void onPowerOffCellularRadioFailed() { logd("onPowerOffCellularRadioFailed"); synchronized (mIsRadioOnLock) { mRadioOffRequested = false; stopWaitForCellularModemOffTimer(); } } /** Loading Loading @@ -4956,6 +5005,32 @@ public class SatelliteController extends Handler { R.integer.config_wait_for_satellite_enabling_response_timeout_millis); } private long getWaitForCellularModemOffTimeoutMillis() { return mContext.getResources().getInteger( R.integer.config_satellite_wait_for_cellular_modem_off_timeout_millis); } private void startWaitForCellularModemOffTimer() { synchronized (mIsRadioOnLock) { if (hasMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT)) { plogd("startWaitForCellularModemOffTimer: the timer was already started"); return; } long timeoutMillis = getWaitForCellularModemOffTimeoutMillis(); plogd("Start timer to wait for cellular modem OFF state, timeoutMillis=" + timeoutMillis); sendMessageDelayed(obtainMessage(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT), timeoutMillis); } } private void stopWaitForCellularModemOffTimer() { synchronized (mSatelliteEnabledRequestLock) { plogd("Stop timer to wait for cellular modem OFF state"); removeMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT); } } private void startWaitForSatelliteEnablingResponseTimer( @NonNull RequestSatelliteEnabledArgument argument) { synchronized (mSatelliteEnabledRequestLock) { Loading tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java +6 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.nullable; Loading Loading @@ -594,7 +595,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { sst.setRadioPowerForReason(false, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController).onCellularRadioPowerOffRequested(); verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(false)); clearInvocations(mSatelliteController); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); Loading @@ -602,7 +603,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { TelephonyManager.RADIO_POWER_REASON_USER); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); verify(mSatelliteController, never()).onSetCellularRadioPowerStateRequested(anyBoolean()); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); Loading @@ -610,7 +611,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { // had been turned off for. sst.setRadioPowerForReason(true, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().isEmpty()); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(true)); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); Loading Loading @@ -1928,6 +1929,8 @@ public class ServiceStateTrackerTest extends TelephonyTest { sst.setRadioPower(false); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(false)); verify(mSatelliteController).onPowerOffCellularRadioFailed(); sst.requestShutdown(); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertFalse(mSimulatedCommands.getRadioState() Loading tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java +141 −2 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ public class SatelliteControllerTest extends TelephonyTest { private static final int[] ACTIVE_SUB_IDS = {SUB_ID}; private static final int TEST_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(60); private static final int TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(60); private static final String SATELLITE_PLMN = "00103"; private List<Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener>> Loading Loading @@ -518,6 +520,9 @@ public class SatelliteControllerTest extends TelephonyTest { mContextFixture.putIntResource( R.integer.config_wait_for_satellite_enabling_response_timeout_millis, TEST_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMEOUT_MILLIS); mContextFixture.putIntResource( R.integer.config_satellite_wait_for_cellular_modem_off_timeout_millis, TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS); doReturn(ACTIVE_SUB_IDS).when(mMockSubscriptionManagerService).getActiveSubIdList(true); mCarrierConfigBundle = mContextFixture.getCarrierConfigBundle(); Loading Loading @@ -728,6 +733,87 @@ public class SatelliteControllerTest extends TelephonyTest { processAllMessages(); verify(mMockSatelliteModemInterface, times(5)) .requestIsSatelliteSupported(any(Message.class)); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Radio is off during TN -> NTN image switch, SatelliteController should not set radio // state to OFF setRadioPower(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Turn on radio setRadioPower(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // SatelliteController should set the radio state to OFF setRadioPower(false); processAllMessages(); assertFalse(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Turn on radio setRadioPower(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Modem fails to power off radio. APM is disabled mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // The timer WaitForCellularModemOff time out moveTimeForward(TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Modem failed to power off the radio mSatelliteControllerUT.onPowerOffCellularRadioFailed(); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); } @Test Loading Loading @@ -848,7 +934,7 @@ public class SatelliteControllerTest extends TelephonyTest { mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false; setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS); setRadioPower(false); mSatelliteControllerUT.onCellularRadioPowerOffRequested(); mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_OFF, null); processAllMessages(); Loading Loading @@ -1062,12 +1148,49 @@ public class SatelliteControllerTest extends TelephonyTest { resetSatelliteControllerUTToOnAndProvisionedState(); when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false); mSatelliteControllerUT.onCellularRadioPowerOffRequested(); mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); // Satellite should not be powered off since the feature flag oemEnabledSatelliteFlag is // disabled when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true); verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS); // Successfully disable satellite. when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true); mIIntegerConsumerResults.clear(); setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS); mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, false, mIIntegerConsumer); processAllMessages(); assertTrue(waitForIIntegerConsumerResult(1)); assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0)); verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS); // Fail to enable satellite when radio is being powered off. mIIntegerConsumerResults.clear(); setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS); mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false, mIIntegerConsumer); processAllMessages(); assertTrue(waitForIIntegerConsumerResult(1)); // Radio is being powered off, can not enable satellite assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0)); // Modem failed to power off mSatelliteControllerUT.onPowerOffCellularRadioFailed(); // Successfully enable satellite when radio is on. mIIntegerConsumerResults.clear(); mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false; mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false; setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS); mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false, mIIntegerConsumer); processAllMessages(); assertTrue(waitForIIntegerConsumerResult(1)); assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0)); verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS); } @Test Loading Loading @@ -4719,5 +4842,21 @@ public class SatelliteControllerTest extends TelephonyTest { mIsSatelliteViaOemProvisioned = isProvisioned; } } public boolean isRadioOn() { synchronized (mIsRadioOnLock) { return mIsRadioOn; } } public boolean isRadioOffRequested() { synchronized (mIsRadioOnLock) { return mRadioOffRequested; } } public boolean isWaitForCellularModemOffTimerStarted() { return hasMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT); } } } Loading
src/java/com/android/internal/telephony/ServiceStateTracker.java +10 −1 Original line number Diff line number Diff line Loading @@ -1164,6 +1164,9 @@ public class ServiceStateTracker extends Handler { mDesiredPowerState = power; setPowerStateToDesired(forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply); if (mDesiredPowerState) { SatelliteController.getInstance().onSetCellularRadioPowerStateRequested(true); } } /** Loading Loading @@ -1325,6 +1328,12 @@ public class ServiceStateTracker extends Handler { // Hence, issuing shut down regardless of radio power response mCi.requestShutdown(null); } ar = (AsyncResult) msg.obj; if (ar.exception != null) { loge("EVENT_RADIO_POWER_OFF_DONE: exception=" + ar.exception); SatelliteController.getInstance().onPowerOffCellularRadioFailed(); } break; // GSM Loading Loading @@ -4979,7 +4988,7 @@ public class ServiceStateTracker extends Handler { */ public void powerOffRadioSafely() { synchronized (this) { SatelliteController.getInstance().onCellularRadioPowerOffRequested(); SatelliteController.getInstance().onSetCellularRadioPowerStateRequested(false); if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { EmergencyStateTracker.getInstance().onCellularRadioPowerOffRequested(); } Loading
src/java/com/android/internal/telephony/satellite/SatelliteController.java +91 −16 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ public class SatelliteController extends Handler { private static final int EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT = 46; private static final int EVENT_WIFI_CONNECTIVITY_STATE_CHANGED = 47; private static final int EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT = 48; protected static final int EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT = 49; @NonNull private static SatelliteController sInstance; @NonNull private final Context mContext; Loading Loading @@ -344,9 +345,13 @@ public class SatelliteController extends Handler { private final Object mIsSatelliteEnabledLock = new Object(); @GuardedBy("mIsSatelliteEnabledLock") private Boolean mIsSatelliteEnabled = null; private final Object mIsRadioOnLock = new Object(); @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected final Object mIsRadioOnLock = new Object(); @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected boolean mIsRadioOn; @GuardedBy("mIsRadioOnLock") private boolean mIsRadioOn = false; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected boolean mRadioOffRequested = false; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected final Object mSatelliteViaOemProvisionLock = new Object(); @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading Loading @@ -1325,6 +1330,14 @@ public class SatelliteController extends Handler { mIsRadioOn = true; } else if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) { resetCarrierRoamingSatelliteModeParams(); synchronized (mIsRadioOnLock) { if (mRadioOffRequested) { logd("EVENT_RADIO_STATE_CHANGED: set mIsRadioOn to false"); stopWaitForCellularModemOffTimer(); mIsRadioOn = false; mRadioOffRequested = false; } } } } Loading Loading @@ -1635,6 +1648,13 @@ public class SatelliteController extends Handler { break; } case EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT: { plogw("Timed out to wait for cellular modem OFF state"); synchronized (mIsRadioOnLock) { mRadioOffRequested = false; } } default: Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " + msg.what); Loading Loading @@ -1716,6 +1736,12 @@ public class SatelliteController extends Handler { SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result); return; } if (mRadioOffRequested) { ploge("Radio is being powering off, can not enable satellite"); sendErrorAndReportSessionMetrics( SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result); return; } } if (mTelecomManager.isInEmergencyCall()) { Loading Loading @@ -2900,27 +2926,50 @@ public class SatelliteController extends Handler { /** * This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify * {@link SatelliteController} that it has received a request to power off the cellular radio * modem. {@link SatelliteController} will then power off the satellite modem. * {@link SatelliteController} that it has received a request to power on or off the cellular * radio modem. * * @param powerOn {@code true} means cellular radio is about to be powered on, {@code false} * means cellular modem is about to be powered off. */ public void onCellularRadioPowerOffRequested() { logd("onCellularRadioPowerOffRequested()"); public void onSetCellularRadioPowerStateRequested(boolean powerOn) { logd("onSetCellularRadioPowerStateRequested: powerOn=" + powerOn); if (!mFeatureFlags.oemEnabledSatelliteFlag()) { plogd("onCellularRadioPowerOffRequested: oemEnabledSatelliteFlag is disabled"); plogd("onSetCellularRadioPowerStateRequested: oemEnabledSatelliteFlag is disabled"); return; } synchronized (mIsRadioOnLock) { mIsRadioOn = false; mRadioOffRequested = !powerOn; } if (powerOn) { stopWaitForCellularModemOffTimer(); } else { requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false /* enableSatellite */, false /* enableDemoMode */, false /* isEmergency */, false /* enableSatellite */, false /* enableDemoMode */, false /* isEmergency */, new IIntegerConsumer.Stub() { @Override public void accept(int result) { plogd("onRadioPowerOffRequested: requestSatelliteEnabled result=" + result); plogd("onSetCellularRadioPowerStateRequested: requestSatelliteEnabled" + " result=" + result); } }); startWaitForCellularModemOffTimer(); } } /** * This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify * {@link SatelliteController} that the request to power off the cellular radio modem has * failed. */ public void onPowerOffCellularRadioFailed() { logd("onPowerOffCellularRadioFailed"); synchronized (mIsRadioOnLock) { mRadioOffRequested = false; stopWaitForCellularModemOffTimer(); } } /** Loading Loading @@ -4956,6 +5005,32 @@ public class SatelliteController extends Handler { R.integer.config_wait_for_satellite_enabling_response_timeout_millis); } private long getWaitForCellularModemOffTimeoutMillis() { return mContext.getResources().getInteger( R.integer.config_satellite_wait_for_cellular_modem_off_timeout_millis); } private void startWaitForCellularModemOffTimer() { synchronized (mIsRadioOnLock) { if (hasMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT)) { plogd("startWaitForCellularModemOffTimer: the timer was already started"); return; } long timeoutMillis = getWaitForCellularModemOffTimeoutMillis(); plogd("Start timer to wait for cellular modem OFF state, timeoutMillis=" + timeoutMillis); sendMessageDelayed(obtainMessage(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT), timeoutMillis); } } private void stopWaitForCellularModemOffTimer() { synchronized (mSatelliteEnabledRequestLock) { plogd("Stop timer to wait for cellular modem OFF state"); removeMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT); } } private void startWaitForSatelliteEnablingResponseTimer( @NonNull RequestSatelliteEnabledArgument argument) { synchronized (mSatelliteEnabledRequestLock) { Loading
tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java +6 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.nullable; Loading Loading @@ -594,7 +595,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { sst.setRadioPowerForReason(false, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController).onCellularRadioPowerOffRequested(); verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(false)); clearInvocations(mSatelliteController); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); Loading @@ -602,7 +603,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { TelephonyManager.RADIO_POWER_REASON_USER); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); verify(mSatelliteController, never()).onSetCellularRadioPowerStateRequested(anyBoolean()); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); Loading @@ -610,7 +611,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { // had been turned off for. sst.setRadioPowerForReason(true, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().isEmpty()); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(true)); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); Loading Loading @@ -1928,6 +1929,8 @@ public class ServiceStateTrackerTest extends TelephonyTest { sst.setRadioPower(false); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(false)); verify(mSatelliteController).onPowerOffCellularRadioFailed(); sst.requestShutdown(); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertFalse(mSimulatedCommands.getRadioState() Loading
tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java +141 −2 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ public class SatelliteControllerTest extends TelephonyTest { private static final int[] ACTIVE_SUB_IDS = {SUB_ID}; private static final int TEST_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(60); private static final int TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(60); private static final String SATELLITE_PLMN = "00103"; private List<Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener>> Loading Loading @@ -518,6 +520,9 @@ public class SatelliteControllerTest extends TelephonyTest { mContextFixture.putIntResource( R.integer.config_wait_for_satellite_enabling_response_timeout_millis, TEST_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMEOUT_MILLIS); mContextFixture.putIntResource( R.integer.config_satellite_wait_for_cellular_modem_off_timeout_millis, TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS); doReturn(ACTIVE_SUB_IDS).when(mMockSubscriptionManagerService).getActiveSubIdList(true); mCarrierConfigBundle = mContextFixture.getCarrierConfigBundle(); Loading Loading @@ -728,6 +733,87 @@ public class SatelliteControllerTest extends TelephonyTest { processAllMessages(); verify(mMockSatelliteModemInterface, times(5)) .requestIsSatelliteSupported(any(Message.class)); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Radio is off during TN -> NTN image switch, SatelliteController should not set radio // state to OFF setRadioPower(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Turn on radio setRadioPower(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // SatelliteController should set the radio state to OFF setRadioPower(false); processAllMessages(); assertFalse(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Turn on radio setRadioPower(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Modem fails to power off radio. APM is disabled mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // The timer WaitForCellularModemOff time out moveTimeForward(TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // APM is triggered mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertTrue(mSatelliteControllerUT.isRadioOffRequested()); assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); // Modem failed to power off the radio mSatelliteControllerUT.onPowerOffCellularRadioFailed(); processAllMessages(); assertTrue(mSatelliteControllerUT.isRadioOn()); assertFalse(mSatelliteControllerUT.isRadioOffRequested()); assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted()); } @Test Loading Loading @@ -848,7 +934,7 @@ public class SatelliteControllerTest extends TelephonyTest { mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false; setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS); setRadioPower(false); mSatelliteControllerUT.onCellularRadioPowerOffRequested(); mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_OFF, null); processAllMessages(); Loading Loading @@ -1062,12 +1148,49 @@ public class SatelliteControllerTest extends TelephonyTest { resetSatelliteControllerUTToOnAndProvisionedState(); when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false); mSatelliteControllerUT.onCellularRadioPowerOffRequested(); mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); processAllMessages(); // Satellite should not be powered off since the feature flag oemEnabledSatelliteFlag is // disabled when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true); verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS); // Successfully disable satellite. when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true); mIIntegerConsumerResults.clear(); setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS); mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, false, mIIntegerConsumer); processAllMessages(); assertTrue(waitForIIntegerConsumerResult(1)); assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0)); verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS); // Fail to enable satellite when radio is being powered off. mIIntegerConsumerResults.clear(); setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS); mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false); mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false, mIIntegerConsumer); processAllMessages(); assertTrue(waitForIIntegerConsumerResult(1)); // Radio is being powered off, can not enable satellite assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0)); // Modem failed to power off mSatelliteControllerUT.onPowerOffCellularRadioFailed(); // Successfully enable satellite when radio is on. mIIntegerConsumerResults.clear(); mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false; mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false; setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS); mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false, mIIntegerConsumer); processAllMessages(); assertTrue(waitForIIntegerConsumerResult(1)); assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0)); verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS); } @Test Loading Loading @@ -4719,5 +4842,21 @@ public class SatelliteControllerTest extends TelephonyTest { mIsSatelliteViaOemProvisioned = isProvisioned; } } public boolean isRadioOn() { synchronized (mIsRadioOnLock) { return mIsRadioOn; } } public boolean isRadioOffRequested() { synchronized (mIsRadioOnLock) { return mRadioOffRequested; } } public boolean isWaitForCellularModemOffTimerStarted() { return hasMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT); } } }