diff options
author | Hunsuk Choi <forestchoi@google.com> | 2023-12-05 23:32:47 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2023-12-05 23:32:47 +0000 |
commit | b0e5784d3807688a7ad37f7f955e9d3b4233131b (patch) | |
tree | 64552cf906a9ea1cd879b7404300b798c5b818d5 | |
parent | ebe1720dee4948d5d0432f528265e1d5a9737572 (diff) | |
parent | 3afe29e4cdbe1abf17fbbd575708926a12841ded (diff) | |
download | telephony-b0e5784d3807688a7ad37f7f955e9d3b4233131b.tar.gz |
Merge "Exit emergency callback mode before turning off radio power" into main
10 files changed, 127 insertions, 22 deletions
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java index 01d6e4ce7c..d19e4cb359 100644 --- a/src/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java @@ -94,6 +94,8 @@ import com.android.internal.telephony.data.AccessNetworksManager; import com.android.internal.telephony.data.AccessNetworksManager.AccessNetworksManagerCallback; import com.android.internal.telephony.data.DataNetwork; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; +import com.android.internal.telephony.domainselection.DomainSelectionResolver; +import com.android.internal.telephony.emergency.EmergencyStateTracker; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.imsphone.ImsPhone; import com.android.internal.telephony.metrics.RadioPowerStateStats; @@ -4969,6 +4971,9 @@ public class ServiceStateTracker extends Handler { public void powerOffRadioSafely() { synchronized (this) { SatelliteController.getInstance().onCellularRadioPowerOffRequested(); + if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { + EmergencyStateTracker.getInstance().onCellularRadioPowerOffRequested(); + } if (!mPendingRadioPowerOffAfterDataOff) { // hang up all active voice calls first if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) { diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java index 30235017be..0692f7d3bd 100644 --- a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java +++ b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java @@ -892,6 +892,18 @@ public class EmergencyStateTracker { } } + /** + * Handles the radio power off request. + */ + public void onCellularRadioPowerOffRequested() { + synchronized (mLock) { + if (isInEcm()) { + exitEmergencyCallbackMode(null); + } + exitEmergencyModeIfDelayed(); + } + } + private static boolean isVoWiFi(int properties) { return (properties & android.telecom.Connection.PROPERTY_WIFI) > 0 || (properties & android.telecom.Connection.PROPERTY_CROSS_SIM) > 0; diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java index 2fdff9ed7b..369980c4e4 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java @@ -41,7 +41,6 @@ import android.testing.TestableLooper; import androidx.test.filters.FlakyTest; import com.android.internal.telephony.PhoneInternalInterface.DialArgs; -import com.android.internal.telephony.domainselection.DomainSelectionResolver; import org.junit.After; import org.junit.Assert; @@ -67,16 +66,12 @@ public class GsmCdmaCallTrackerTest extends TelephonyTest { // Mocked classes private GsmCdmaConnection mConnection; private Handler mHandler; - private DomainSelectionResolver mDomainSelectionResolver; @Before public void setUp() throws Exception { super.setUp(getClass().getSimpleName()); mConnection = mock(GsmCdmaConnection.class); mHandler = mock(Handler.class); - mDomainSelectionResolver = mock(DomainSelectionResolver.class); - doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported(); - DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver); mSimulatedCommands.setRadioPower(true, null); mPhone.mCi = this.mSimulatedCommands; @@ -91,7 +86,6 @@ public class GsmCdmaCallTrackerTest extends TelephonyTest { @After public void tearDown() throws Exception { mCTUT = null; - DomainSelectionResolver.setDomainSelectionResolver(null); super.tearDown(); } diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java index 34087b69cd..c8510eb0eb 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java @@ -132,7 +132,6 @@ public class GsmCdmaPhoneTest extends TelephonyTest { private UiccSlot mUiccSlot; private CommandsInterface mMockCi; private AdnRecordCache adnRecordCache; - private DomainSelectionResolver mDomainSelectionResolver; //mPhoneUnderTest private GsmCdmaPhone mPhoneUT; @@ -173,13 +172,10 @@ public class GsmCdmaPhoneTest extends TelephonyTest { mUiccPort = Mockito.mock(UiccPort.class); mMockCi = Mockito.mock(CommandsInterface.class); adnRecordCache = Mockito.mock(AdnRecordCache.class); - mDomainSelectionResolver = Mockito.mock(DomainSelectionResolver.class); mFeatureFlags = Mockito.mock(FeatureFlags.class); doReturn(false).when(mSST).isDeviceShuttingDown(); doReturn(true).when(mImsManager).isVolteEnabledByPlatform(); - doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported(); - DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver); mPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0, PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager, @@ -198,7 +194,6 @@ public class GsmCdmaPhoneTest extends TelephonyTest { public void tearDown() throws Exception { mPhoneUT.removeCallbacksAndMessages(null); mPhoneUT = null; - DomainSelectionResolver.setDomainSelectionResolver(null); try { DeviceConfig.setProperties(mPreTestProperties); } catch (DeviceConfig.BadConfigException e) { diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java index 9e067a2ec9..c54285786d 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java @@ -99,6 +99,7 @@ import com.android.internal.R; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; import com.android.internal.telephony.data.AccessNetworksManager; import com.android.internal.telephony.data.DataNetworkController; +import com.android.internal.telephony.emergency.EmergencyStateTracker; import com.android.internal.telephony.metrics.ServiceStateStats; import com.android.internal.telephony.satellite.SatelliteController; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; @@ -145,6 +146,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { private ServiceStateTrackerTestHandler mSSTTestHandler; private PersistableBundle mBundle; private SatelliteController mSatelliteController; + private EmergencyStateTracker mEmergencyStateTracker; private static final int EVENT_REGISTERED_TO_NETWORK = 1; private static final int EVENT_SUBSCRIPTION_INFO_READY = 2; @@ -390,6 +392,9 @@ public class ServiceStateTrackerTest extends TelephonyTest { sendCarrierConfigUpdate(PHONE_ID); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); + mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class); + replaceInstance(EmergencyStateTracker.class, "INSTANCE", null, mEmergencyStateTracker); + logd("ServiceStateTrackerTest -Setup!"); } @@ -480,6 +485,66 @@ public class ServiceStateTrackerTest extends TelephonyTest { waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); verify(mDataNetworkController, times(1)).unregisterDataNetworkControllerCallback(any()); assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState()); + verify(mEmergencyStateTracker, never()).onCellularRadioPowerOffRequested(); + } + + @Test + public void testSetRadioPowerExitEmergencyMode() throws Exception { + doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported(); + + // Set up DSDS environment + GsmCdmaPhone phone2 = Mockito.mock(GsmCdmaPhone.class); + DataNetworkController dataNetworkController_phone2 = + Mockito.mock(DataNetworkController.class); + mPhones = new Phone[] {mPhone, phone2}; + replaceInstance(PhoneFactory.class, "sPhones", null, mPhones); + doReturn(dataNetworkController_phone2).when(phone2).getDataNetworkController(); + doReturn(mSST).when(phone2).getServiceStateTracker(); + doReturn(false).when(mDataNetworkController).areAllDataDisconnected(); + doReturn(false).when(dataNetworkController_phone2).areAllDataDisconnected(); + doReturn(1).when(mPhone).getSubId(); + doReturn(2).when(phone2).getSubId(); + + // Start with radio on + sst.setRadioPower(true); + waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); + assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState()); + + // Turn on APM + sst.setRadioPower(false); + waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); + assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState()); + + // Verify checking emergency mode + verify(mEmergencyStateTracker).onCellularRadioPowerOffRequested(); + + // Verify that both subs are waiting for all data disconnected + verify(mDataNetworkController).tearDownAllDataNetworks( + eq(3 /* TEAR_DOWN_REASON_AIRPLANE_MODE_ON */)); + verify(dataNetworkController_phone2, never()).tearDownAllDataNetworks(anyInt()); + ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback1 = + ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class); + ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback2 = + ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class); + verify(mDataNetworkController, times(1)).registerDataNetworkControllerCallback( + callback1.capture()); + verify(dataNetworkController_phone2, times(1)).registerDataNetworkControllerCallback( + callback2.capture()); + + // Data disconnected on sub 2, still waiting for data disconnected on sub 1 + doReturn(true).when(dataNetworkController_phone2).areAllDataDisconnected(); + callback2.getValue().onAnyDataNetworkExistingChanged(false); + waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); + assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState()); + verify(dataNetworkController_phone2, times(1)).unregisterDataNetworkControllerCallback( + any()); + + // Data disconnected on sub 1, radio should power off now + doReturn(true).when(mDataNetworkController).areAllDataDisconnected(); + callback1.getValue().onAnyDataNetworkExistingChanged(false); + waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); + verify(mDataNetworkController, times(1)).unregisterDataNetworkControllerCallback(any()); + assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState()); } @Test diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java index 1ebe96dbbb..921256714c 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java @@ -108,6 +108,7 @@ import com.android.internal.telephony.data.DataServiceManager; import com.android.internal.telephony.data.DataSettingsManager; import com.android.internal.telephony.data.LinkBandwidthEstimator; import com.android.internal.telephony.data.PhoneSwitcher; +import com.android.internal.telephony.domainselection.DomainSelectionResolver; import com.android.internal.telephony.emergency.EmergencyNumberTracker; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.imsphone.ImsExternalCallTracker; @@ -281,6 +282,7 @@ public abstract class TelephonyTest { protected SatelliteController mSatelliteController; protected DeviceStateHelper mDeviceStateHelper; protected CellularIdentifierDisclosureNotifier mIdentifierDisclosureNotifier; + protected DomainSelectionResolver mDomainSelectionResolver; // Initialized classes protected ActivityManager mActivityManager; @@ -552,6 +554,7 @@ public abstract class TelephonyTest { mSatelliteController = Mockito.mock(SatelliteController.class); mDeviceStateHelper = Mockito.mock(DeviceStateHelper.class); mIdentifierDisclosureNotifier = Mockito.mock(CellularIdentifierDisclosureNotifier.class); + mDomainSelectionResolver = Mockito.mock(DomainSelectionResolver.class); TelephonyManager.disableServiceHandleCaching(); PropertyInvalidatedCache.disableForTestMode(); @@ -888,6 +891,9 @@ public abstract class TelephonyTest { .getFoldState(); doReturn(null).when(mContext).getSystemService(eq(Context.DEVICE_STATE_SERVICE)); + doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported(); + DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver); + //Use reflection to mock singletons replaceInstance(CallManager.class, "INSTANCE", null, mCallManager); replaceInstance(TelephonyComponentFactory.class, "sInstance", null, @@ -990,6 +996,7 @@ public abstract class TelephonyTest { mTestableLoopers.clear(); mTestableLoopers = null; mTestableLooper = null; + DomainSelectionResolver.setDomainSelectionResolver(null); } protected static void logd(String s) { diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java index 7095909d97..eaf11a4e4a 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java @@ -83,6 +83,8 @@ public class DomainSelectionResolverTest extends TelephonyTest { @Test @SmallTest public void testGetInstance() throws IllegalStateException { + DomainSelectionResolver.setDomainSelectionResolver(null); + assertThrows(IllegalStateException.class, () -> { DomainSelectionResolver.getInstance(); }); 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 1eff979acd..fff1b68e75 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java @@ -886,6 +886,42 @@ public class EmergencyStateTrackerTest extends TelephonyTest { } /** + * Test that once endCall() is called and we enter ECM, then we exit ECM when turning on + * airplane mode. + */ + @Test + @SmallTest + public void endCall_entersEcm_thenExitsEcmWhenTurnOnAirplaneMode() { + // Setup EmergencyStateTracker + EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker( + /* isSuplDdsSwitchRequiredForEmergencyCall= */ true); + // Create test Phone + Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true, + /* isRadioOn= */ true); + setUpAsyncResultForSetEmergencyMode(testPhone, E_REG_RESULT); + setUpAsyncResultForExitEmergencyMode(testPhone); + CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone, + TEST_CALL_ID, false); + // Set call to ACTIVE + emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID); + // Set ecm as supported + setEcmSupportedConfig(testPhone, /* ecmSupported= */ true); + + processAllMessages(); + + emergencyStateTracker.endCall(TEST_CALL_ID); + + assertTrue(emergencyStateTracker.isInEcm()); + + emergencyStateTracker.onCellularRadioPowerOffRequested(); + + // Verify exitEmergencyMode() is called. + verify(testPhone).exitEmergencyMode(any(Message.class)); + assertFalse(emergencyStateTracker.isInEcm()); + assertFalse(emergencyStateTracker.isInEmergencyMode()); + } + + /** * Test that after exitEmergencyCallbackMode() is called, the correct intents are sent and * emergency mode is exited on the modem. */ diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java index 04ae9d01d6..bfa702cf40 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java @@ -126,7 +126,6 @@ import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.SrvccConnection; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.d2d.RtpTransport; -import com.android.internal.telephony.domainselection.DomainSelectionResolver; import com.android.internal.telephony.imsphone.ImsPhoneCallTracker.VtDataUsageProvider; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; @@ -174,7 +173,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { private INetworkStatsProviderCallback mVtDataUsageProviderCb; private ImsPhoneCallTracker.ConnectorFactory mConnectorFactory; private CommandsInterface mMockCi; - private DomainSelectionResolver mDomainSelectionResolver; private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener; private final Executor mExecutor = Runnable::run; @@ -242,7 +240,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState(); doReturn(mImsCallProfile).when(mImsManager).createCallProfile(anyInt(), anyInt()); mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS); - mDomainSelectionResolver = mock(DomainSelectionResolver.class); doReturn(new SubscriptionInfoInternal.Builder().setSimSlotIndex(0).setId(1).build()) .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt()); @@ -281,9 +278,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { return mMockConnector; }).when(mConnectorFactory).create(any(), anyInt(), anyString(), any(), any()); - DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver); - doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported(); - doReturn(false) .when(mFeatureFlags).updateImsServiceByGatheringProvisioningChanges(); diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java index fbb30ff45b..f491041e9d 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java @@ -125,7 +125,6 @@ public class ImsPhoneTest extends TelephonyTest { private ImsPhoneCall mBackgroundCall; private ImsPhoneCall mRingingCall; private Handler mTestHandler; - private DomainSelectionResolver mDomainSelectionResolver; Connection mConnection; ImsUtInterface mImsUtInterface; private FeatureFlags mFeatureFlags; @@ -152,10 +151,7 @@ public class ImsPhoneTest extends TelephonyTest { mTestHandler = mock(Handler.class); mConnection = mock(Connection.class); mImsUtInterface = mock(ImsUtInterface.class); - mDomainSelectionResolver = mock(DomainSelectionResolver.class); mFeatureFlags = mock(FeatureFlags.class); - doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported(); - DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver); mImsCT.mForegroundCall = mForegroundCall; mImsCT.mBackgroundCall = mBackgroundCall; @@ -200,7 +196,6 @@ public class ImsPhoneTest extends TelephonyTest { public void tearDown() throws Exception { mImsPhoneUT = null; mBundle = null; - DomainSelectionResolver.setDomainSelectionResolver(null); super.tearDown(); } |