Loading src/java/com/android/internal/telephony/satellite/SatelliteController.java +67 −2 Original line number Diff line number Diff line Loading @@ -18,9 +18,11 @@ package com.android.internal.telephony.satellite; import static android.provider.Settings.ACTION_SATELLITE_SETTING; import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE; import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT; import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY; import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL; import static android.telephony.SubscriptionManager.SATELLITE_ATTACH_ENABLED_FOR_CARRIER; import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS; Loading Loading @@ -129,11 +131,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; Loading Loading @@ -165,6 +167,9 @@ public class SatelliteController extends Handler { private static final String OEM_ENABLED_SATELLITE_PROVISION_STATUS_KEY = "oem_enabled_satellite_provision_status_key"; public static final long DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30); /** Message codes used in handleMessage() */ //TODO: Move the Commands and events related to position updates to PointingAppController private static final int CMD_START_SATELLITE_TRANSMISSION_UPDATES = 1; Loading Loading @@ -2638,6 +2643,32 @@ public class SatelliteController extends Handler { return false; } /** * @return {@code true} if satellite emergency messaging is supported via carrier by any * subscription on the device, {@code false} otherwise. */ public boolean isSatelliteEmergencyMessagingSupportedViaCarrier() { if (!mFeatureFlags.carrierEnabledSatelliteFlag()) { logd("isSatelliteEmergencyMessagingSupportedViaCarrier: carrierEnabledSatelliteFlag is" + " disabled"); return false; } for (Phone phone : PhoneFactory.getPhones()) { if (isSatelliteEmergencyMessagingSupportedViaCarrier(phone.getSubId())) { return true; } } return false; } private boolean isSatelliteEmergencyMessagingSupportedViaCarrier(int subId) { if (!isSatelliteSupportedViaCarrier(subId)) { return false; } PersistableBundle config = getPersistableBundle(subId); return config.getBoolean(KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL); } /** * @return {@code Pair<true, subscription ID>} if any subscription on the device is connected to * satellite, {@code Pair<false, null>} otherwise. Loading Loading @@ -2757,6 +2788,38 @@ public class SatelliteController extends Handler { return new ArrayList<>(); } /** * Get the carrier-enabled emergency call wait for connection timeout millis */ public long getCarrierEmergencyCallWaitForConnectionTimeoutMillis() { long maxTimeoutMillis = 0; for (Phone phone : PhoneFactory.getPhones()) { if (!isSatelliteEmergencyMessagingSupportedViaCarrier(phone.getSubId())) { continue; } int timeoutMillis = getCarrierEmergencyCallWaitForConnectionTimeoutMillis(phone.getSubId()); // Prioritize getting the timeout duration from the phone that is in satellite mode // with carrier roaming if (isInSatelliteModeForCarrierRoaming(phone)) { return timeoutMillis; } if (maxTimeoutMillis < timeoutMillis) { maxTimeoutMillis = timeoutMillis; } } if (maxTimeoutMillis != 0) { return maxTimeoutMillis; } return DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS; } private int getCarrierEmergencyCallWaitForConnectionTimeoutMillis(int subId) { PersistableBundle config = getPersistableBundle(subId); return config.getInt(KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected long getElapsedRealtime() { return SystemClock.elapsedRealtime(); Loading Loading @@ -3563,7 +3626,9 @@ public class SatelliteController extends Handler { KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT, KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY); KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY, KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT); if (config == null || config.isEmpty()) { config = CarrierConfigManager.getDefaultConfig(); } Loading src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java +22 −10 Original line number Diff line number Diff line Loading @@ -99,7 +99,8 @@ public class SatelliteSOSMessageRecommender extends Handler { private boolean mIsSatelliteAllowedForCurrentLocation = false; @GuardedBy("mLock") private boolean mCheckingAccessRestrictionInProgress = false; private final long mTimeoutMillis; protected long mTimeoutMillis = 0; private final long mOemEnabledTimeoutMillis; private final AtomicBoolean mIsSatelliteConnectedViaCarrierWithinHysteresisTime = new AtomicBoolean(false); @GuardedBy("mLock") Loading @@ -114,8 +115,7 @@ public class SatelliteSOSMessageRecommender extends Handler { * @param looper The looper used with the handler of this class. */ public SatelliteSOSMessageRecommender(@NonNull Context context, @NonNull Looper looper) { this(context, looper, SatelliteController.getInstance(), null, getEmergencyCallWaitForConnectionTimeoutMillis(context)); this(context, looper, SatelliteController.getInstance(), null); } /** Loading @@ -127,17 +127,16 @@ public class SatelliteSOSMessageRecommender extends Handler { * @param satelliteController The SatelliteController singleton instance. * @param imsManager The ImsManager instance associated with the phone, which is used for making * the emergency call. This argument is not null only in unit tests. * @param timeoutMillis The timeout duration of the timer. */ @VisibleForTesting protected SatelliteSOSMessageRecommender(@NonNull Context context, @NonNull Looper looper, @NonNull SatelliteController satelliteController, ImsManager imsManager, long timeoutMillis) { @NonNull SatelliteController satelliteController, ImsManager imsManager) { super(looper); mContext = context; mSatelliteController = satelliteController; mImsManager = imsManager; mTimeoutMillis = timeoutMillis; mOemEnabledTimeoutMillis = getOemEnabledEmergencyCallWaitForConnectionTimeoutMillis(context); mISatelliteProvisionStateCallback = new ISatelliteProvisionStateCallback.Stub() { @Override public void onSatelliteProvisionStateChanged(boolean provisioned) { Loading Loading @@ -185,7 +184,7 @@ public class SatelliteSOSMessageRecommender extends Handler { */ public void onEmergencyCallStarted(@NonNull Connection connection) { if (!mSatelliteController.isSatelliteSupportedViaOem() && !mSatelliteController.isSatelliteSupportedViaCarrier()) { && !mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) { logd("onEmergencyCallStarted: satellite is not supported"); return; } Loading @@ -212,7 +211,7 @@ public class SatelliteSOSMessageRecommender extends Handler { String callId, @Connection.ConnectionState int state) { logd("callId=" + callId + ", state=" + state); if (!mSatelliteController.isSatelliteSupportedViaOem() && !mSatelliteController.isSatelliteSupportedViaCarrier()) { && !mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) { logd("onEmergencyCallConnectionStateChanged: satellite is not supported"); return; } Loading @@ -229,6 +228,8 @@ public class SatelliteSOSMessageRecommender extends Handler { if (sendEventDisplayEmergencyMessageForcefully(connection)) { return; } selectEmergencyCallWaitForConnectionTimeoutDuration(); if (mEmergencyConnection == null) { handleStateChangedEventForHysteresisTimer(); registerForInterestedStateChangedEvents(); Loading Loading @@ -504,7 +505,18 @@ public class SatelliteSOSMessageRecommender extends Handler { } } private static long getEmergencyCallWaitForConnectionTimeoutMillis(@NonNull Context context) { private void selectEmergencyCallWaitForConnectionTimeoutDuration() { if (mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) { mTimeoutMillis = mSatelliteController.getCarrierEmergencyCallWaitForConnectionTimeoutMillis(); } else { mTimeoutMillis = mOemEnabledTimeoutMillis; } logd("mTimeoutMillis = " + mTimeoutMillis); } private static long getOemEnabledEmergencyCallWaitForConnectionTimeoutMillis( @NonNull Context context) { return context.getResources().getInteger( R.integer.config_emergency_call_wait_for_connection_timeout_millis); } Loading tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java +101 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.internal.telephony.satellite; import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT; import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS; Loading Loading @@ -57,6 +58,7 @@ import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERV import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS; import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS; import static com.android.internal.telephony.satellite.SatelliteController.DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS; import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_FALSE; import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_TRUE; Loading Loading @@ -3554,6 +3556,105 @@ public class SatelliteControllerTest extends TelephonyTest { assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, errorCode); } @Test public void testIsSatelliteEmergencyMessagingSupportedViaCarrier() { // Carrier-enabled flag is off when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false); assertFalse(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); // Carrier-enabled flag is on and satellite attach is not supported when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true); assertFalse(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); // Trigger carrier config changed to enable satellite attach mCarrierConfigBundle.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair : mCarrierConfigChangedListenerList) { pair.first.execute(() -> pair.second.onCarrierConfigChanged( /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } processAllMessages(); assertFalse(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); // Trigger carrier config changed to enable satellite attach & emergency messaging mCarrierConfigBundle.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); mCarrierConfigBundle.putBoolean( CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, true); for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair : mCarrierConfigChangedListenerList) { pair.first.execute(() -> pair.second.onCarrierConfigChanged( /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } processAllMessages(); assertTrue(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); } @Test public void testGetCarrierEmergencyCallWaitForConnectionTimeoutMillis() { // Carrier-enabled flag is off when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false); assertEquals(DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Carrier-enabled flag is on when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true); assertEquals(DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Trigger carrier config changed to enable satellite attach int timeoutMillisForCarrier1 = 1000; PersistableBundle carrierConfigBundle1 = new PersistableBundle(); carrierConfigBundle1.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); carrierConfigBundle1.putBoolean( CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, true); carrierConfigBundle1.putInt( KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT, timeoutMillisForCarrier1); doReturn(carrierConfigBundle1) .when(mCarrierConfigManager).getConfigForSubId(eq(SUB_ID), anyVararg()); int timeoutMillisForCarrier2 = 2000; PersistableBundle carrierConfigBundle2 = new PersistableBundle(); carrierConfigBundle2.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); carrierConfigBundle2.putBoolean( CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, true); carrierConfigBundle2.putInt( KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT, timeoutMillisForCarrier2); doReturn(carrierConfigBundle2) .when(mCarrierConfigManager).getConfigForSubId(eq(SUB_ID1), anyVararg()); for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair : mCarrierConfigChangedListenerList) { pair.first.execute(() -> pair.second.onCarrierConfigChanged( /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } processAllMessages(); // Both phones are not in satellite mode for carrier roaming, and thus the max timeout // duration - timeoutMillisForCarrier2 - is used assertEquals(timeoutMillisForCarrier2, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Phone 1 is in satellite mode for carrier roaming when(mServiceState.isUsingNonTerrestrialNetwork()).thenReturn(true); assertEquals(timeoutMillisForCarrier1, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Both phones are in satellite mode for carrier roaming. The timeout duration of the first // phone will be selected when(mServiceState2.isUsingNonTerrestrialNetwork()).thenReturn(true); assertEquals(timeoutMillisForCarrier1, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); } private void resetSatelliteControllerUTEnabledState() { logd("resetSatelliteControllerUTEnabledState"); setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE); Loading tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java +51 −9 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ import java.util.concurrent.Executor; @TestableLooper.RunWithLooper public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { private static final String TAG = "SatelliteSOSMessageRecommenderTest"; private static final long TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 500; private static final int TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 500; private static final int PHONE_ID = 0; private static final int PHONE_ID2 = 1; private static final String CALL_ID = "CALL_ID"; Loading Loading @@ -118,6 +118,9 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { .thenReturn(""); when(mResources.getString(R.string.config_satellite_emergency_handover_intent_action)) .thenReturn(DEFAULT_HANDOVER_INTENT_ACTION); when(mResources.getInteger( R.integer.config_emergency_call_wait_for_connection_timeout_millis)) .thenReturn(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS); when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true); mTestSatelliteController = new TestSatelliteController(mContext, Looper.myLooper(), mFeatureFlags); Loading @@ -132,8 +135,7 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { when(mPhone2.getServiceState()).thenReturn(mServiceState2); when(mPhone2.getPhoneId()).thenReturn(PHONE_ID2); mTestSOSMessageRecommender = new TestSOSMessageRecommender(mContext, Looper.myLooper(), mTestSatelliteController, mTestImsManager, TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS); mTestSatelliteController, mTestImsManager); when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); when(mServiceState2.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); when(mPhone.isImsRegistered()).thenReturn(false); Loading Loading @@ -505,8 +507,7 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { TestSOSMessageRecommender testSOSMessageRecommender = new TestSOSMessageRecommender( mContext, Looper.myLooper(), satelliteController, mTestImsManager, TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS); satelliteController, mTestImsManager); testSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); Loading @@ -532,6 +533,32 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { originalIsSatelliteViaOemProvisioned; } @Test public void testSelectEmergencyCallWaitForConnectionTimeoutDuration() { // Both OEM and carrier don't support satellite mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = false; mTestSatelliteController.isOemEnabledSatelliteSupported = false; mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); assertEquals(0, mTestSOSMessageRecommender.getTimeOutMillis()); // Only OEM support satellite mTestSatelliteController.isOemEnabledSatelliteSupported = true; mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); assertEquals(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS, mTestSOSMessageRecommender.getTimeOutMillis()); // Both OEM and carrier support satellite. Thus, carrier's timeout duration will be used long carrierTimeoutMillis = 1000; mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = true; mTestSatelliteController.carrierEmergencyCallWaitForConnectionTimeoutMillis = carrierTimeoutMillis; mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); assertEquals(carrierTimeoutMillis, mTestSOSMessageRecommender.getTimeOutMillis()); } private void testStopTrackingCallBeforeTimeout( @Connection.ConnectionState int connectionState) { mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); Loading Loading @@ -636,6 +663,9 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { private boolean mIsSatelliteConnectedViaCarrierWithinHysteresisTime = true; public boolean isOemEnabledSatelliteSupported = true; public boolean isCarrierEnabledSatelliteSupported = true; public boolean isSatelliteEmergencyMessagingSupportedViaCarrier = true; public long carrierEmergencyCallWaitForConnectionTimeoutMillis = TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS; /** * Create a SatelliteController to act as a backend service of Loading Loading @@ -696,6 +726,16 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { return INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE; } @Override public boolean isSatelliteEmergencyMessagingSupportedViaCarrier() { return isSatelliteEmergencyMessagingSupportedViaCarrier; } @Override public long getCarrierEmergencyCallWaitForConnectionTimeoutMillis() { return carrierEmergencyCallWaitForConnectionTimeoutMillis; } public void setSatelliteConnectedViaCarrierWithinHysteresisTime( boolean connectedViaCarrier) { mIsSatelliteConnectedViaCarrierWithinHysteresisTime = connectedViaCarrier; Loading Loading @@ -811,12 +851,10 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { * @param imsManager The ImsManager instance associated with the phone, which is * used for making the emergency call. This argument is not * null only in unit tests. * @param timeoutMillis The timeout duration of the timer. */ TestSOSMessageRecommender(Context context, Looper looper, SatelliteController satelliteController, ImsManager imsManager, long timeoutMillis) { super(context, looper, satelliteController, imsManager, timeoutMillis); SatelliteController satelliteController, ImsManager imsManager) { super(context, looper, satelliteController, imsManager); } @Override Loading @@ -843,6 +881,10 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { public void sendServiceStateChangedEvent() { sendMessage(obtainMessage(EVENT_SERVICE_STATE_CHANGED)); } public long getTimeOutMillis() { return mTimeoutMillis; } } private static class TestConnection extends Connection { Loading Loading
src/java/com/android/internal/telephony/satellite/SatelliteController.java +67 −2 Original line number Diff line number Diff line Loading @@ -18,9 +18,11 @@ package com.android.internal.telephony.satellite; import static android.provider.Settings.ACTION_SATELLITE_SETTING; import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE; import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT; import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY; import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL; import static android.telephony.SubscriptionManager.SATELLITE_ATTACH_ENABLED_FOR_CARRIER; import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS; Loading Loading @@ -129,11 +131,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; Loading Loading @@ -165,6 +167,9 @@ public class SatelliteController extends Handler { private static final String OEM_ENABLED_SATELLITE_PROVISION_STATUS_KEY = "oem_enabled_satellite_provision_status_key"; public static final long DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30); /** Message codes used in handleMessage() */ //TODO: Move the Commands and events related to position updates to PointingAppController private static final int CMD_START_SATELLITE_TRANSMISSION_UPDATES = 1; Loading Loading @@ -2638,6 +2643,32 @@ public class SatelliteController extends Handler { return false; } /** * @return {@code true} if satellite emergency messaging is supported via carrier by any * subscription on the device, {@code false} otherwise. */ public boolean isSatelliteEmergencyMessagingSupportedViaCarrier() { if (!mFeatureFlags.carrierEnabledSatelliteFlag()) { logd("isSatelliteEmergencyMessagingSupportedViaCarrier: carrierEnabledSatelliteFlag is" + " disabled"); return false; } for (Phone phone : PhoneFactory.getPhones()) { if (isSatelliteEmergencyMessagingSupportedViaCarrier(phone.getSubId())) { return true; } } return false; } private boolean isSatelliteEmergencyMessagingSupportedViaCarrier(int subId) { if (!isSatelliteSupportedViaCarrier(subId)) { return false; } PersistableBundle config = getPersistableBundle(subId); return config.getBoolean(KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL); } /** * @return {@code Pair<true, subscription ID>} if any subscription on the device is connected to * satellite, {@code Pair<false, null>} otherwise. Loading Loading @@ -2757,6 +2788,38 @@ public class SatelliteController extends Handler { return new ArrayList<>(); } /** * Get the carrier-enabled emergency call wait for connection timeout millis */ public long getCarrierEmergencyCallWaitForConnectionTimeoutMillis() { long maxTimeoutMillis = 0; for (Phone phone : PhoneFactory.getPhones()) { if (!isSatelliteEmergencyMessagingSupportedViaCarrier(phone.getSubId())) { continue; } int timeoutMillis = getCarrierEmergencyCallWaitForConnectionTimeoutMillis(phone.getSubId()); // Prioritize getting the timeout duration from the phone that is in satellite mode // with carrier roaming if (isInSatelliteModeForCarrierRoaming(phone)) { return timeoutMillis; } if (maxTimeoutMillis < timeoutMillis) { maxTimeoutMillis = timeoutMillis; } } if (maxTimeoutMillis != 0) { return maxTimeoutMillis; } return DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS; } private int getCarrierEmergencyCallWaitForConnectionTimeoutMillis(int subId) { PersistableBundle config = getPersistableBundle(subId); return config.getInt(KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected long getElapsedRealtime() { return SystemClock.elapsedRealtime(); Loading Loading @@ -3563,7 +3626,9 @@ public class SatelliteController extends Handler { KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT, KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY); KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY, KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT); if (config == null || config.isEmpty()) { config = CarrierConfigManager.getDefaultConfig(); } Loading
src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java +22 −10 Original line number Diff line number Diff line Loading @@ -99,7 +99,8 @@ public class SatelliteSOSMessageRecommender extends Handler { private boolean mIsSatelliteAllowedForCurrentLocation = false; @GuardedBy("mLock") private boolean mCheckingAccessRestrictionInProgress = false; private final long mTimeoutMillis; protected long mTimeoutMillis = 0; private final long mOemEnabledTimeoutMillis; private final AtomicBoolean mIsSatelliteConnectedViaCarrierWithinHysteresisTime = new AtomicBoolean(false); @GuardedBy("mLock") Loading @@ -114,8 +115,7 @@ public class SatelliteSOSMessageRecommender extends Handler { * @param looper The looper used with the handler of this class. */ public SatelliteSOSMessageRecommender(@NonNull Context context, @NonNull Looper looper) { this(context, looper, SatelliteController.getInstance(), null, getEmergencyCallWaitForConnectionTimeoutMillis(context)); this(context, looper, SatelliteController.getInstance(), null); } /** Loading @@ -127,17 +127,16 @@ public class SatelliteSOSMessageRecommender extends Handler { * @param satelliteController The SatelliteController singleton instance. * @param imsManager The ImsManager instance associated with the phone, which is used for making * the emergency call. This argument is not null only in unit tests. * @param timeoutMillis The timeout duration of the timer. */ @VisibleForTesting protected SatelliteSOSMessageRecommender(@NonNull Context context, @NonNull Looper looper, @NonNull SatelliteController satelliteController, ImsManager imsManager, long timeoutMillis) { @NonNull SatelliteController satelliteController, ImsManager imsManager) { super(looper); mContext = context; mSatelliteController = satelliteController; mImsManager = imsManager; mTimeoutMillis = timeoutMillis; mOemEnabledTimeoutMillis = getOemEnabledEmergencyCallWaitForConnectionTimeoutMillis(context); mISatelliteProvisionStateCallback = new ISatelliteProvisionStateCallback.Stub() { @Override public void onSatelliteProvisionStateChanged(boolean provisioned) { Loading Loading @@ -185,7 +184,7 @@ public class SatelliteSOSMessageRecommender extends Handler { */ public void onEmergencyCallStarted(@NonNull Connection connection) { if (!mSatelliteController.isSatelliteSupportedViaOem() && !mSatelliteController.isSatelliteSupportedViaCarrier()) { && !mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) { logd("onEmergencyCallStarted: satellite is not supported"); return; } Loading @@ -212,7 +211,7 @@ public class SatelliteSOSMessageRecommender extends Handler { String callId, @Connection.ConnectionState int state) { logd("callId=" + callId + ", state=" + state); if (!mSatelliteController.isSatelliteSupportedViaOem() && !mSatelliteController.isSatelliteSupportedViaCarrier()) { && !mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) { logd("onEmergencyCallConnectionStateChanged: satellite is not supported"); return; } Loading @@ -229,6 +228,8 @@ public class SatelliteSOSMessageRecommender extends Handler { if (sendEventDisplayEmergencyMessageForcefully(connection)) { return; } selectEmergencyCallWaitForConnectionTimeoutDuration(); if (mEmergencyConnection == null) { handleStateChangedEventForHysteresisTimer(); registerForInterestedStateChangedEvents(); Loading Loading @@ -504,7 +505,18 @@ public class SatelliteSOSMessageRecommender extends Handler { } } private static long getEmergencyCallWaitForConnectionTimeoutMillis(@NonNull Context context) { private void selectEmergencyCallWaitForConnectionTimeoutDuration() { if (mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) { mTimeoutMillis = mSatelliteController.getCarrierEmergencyCallWaitForConnectionTimeoutMillis(); } else { mTimeoutMillis = mOemEnabledTimeoutMillis; } logd("mTimeoutMillis = " + mTimeoutMillis); } private static long getOemEnabledEmergencyCallWaitForConnectionTimeoutMillis( @NonNull Context context) { return context.getResources().getInteger( R.integer.config_emergency_call_wait_for_connection_timeout_millis); } Loading
tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java +101 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.internal.telephony.satellite; import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT; import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS; Loading Loading @@ -57,6 +58,7 @@ import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERV import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS; import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS; import static com.android.internal.telephony.satellite.SatelliteController.DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS; import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_FALSE; import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_TRUE; Loading Loading @@ -3554,6 +3556,105 @@ public class SatelliteControllerTest extends TelephonyTest { assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, errorCode); } @Test public void testIsSatelliteEmergencyMessagingSupportedViaCarrier() { // Carrier-enabled flag is off when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false); assertFalse(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); // Carrier-enabled flag is on and satellite attach is not supported when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true); assertFalse(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); // Trigger carrier config changed to enable satellite attach mCarrierConfigBundle.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair : mCarrierConfigChangedListenerList) { pair.first.execute(() -> pair.second.onCarrierConfigChanged( /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } processAllMessages(); assertFalse(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); // Trigger carrier config changed to enable satellite attach & emergency messaging mCarrierConfigBundle.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); mCarrierConfigBundle.putBoolean( CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, true); for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair : mCarrierConfigChangedListenerList) { pair.first.execute(() -> pair.second.onCarrierConfigChanged( /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } processAllMessages(); assertTrue(mSatelliteControllerUT.isSatelliteEmergencyMessagingSupportedViaCarrier()); } @Test public void testGetCarrierEmergencyCallWaitForConnectionTimeoutMillis() { // Carrier-enabled flag is off when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false); assertEquals(DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Carrier-enabled flag is on when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true); assertEquals(DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Trigger carrier config changed to enable satellite attach int timeoutMillisForCarrier1 = 1000; PersistableBundle carrierConfigBundle1 = new PersistableBundle(); carrierConfigBundle1.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); carrierConfigBundle1.putBoolean( CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, true); carrierConfigBundle1.putInt( KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT, timeoutMillisForCarrier1); doReturn(carrierConfigBundle1) .when(mCarrierConfigManager).getConfigForSubId(eq(SUB_ID), anyVararg()); int timeoutMillisForCarrier2 = 2000; PersistableBundle carrierConfigBundle2 = new PersistableBundle(); carrierConfigBundle2.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); carrierConfigBundle2.putBoolean( CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, true); carrierConfigBundle2.putInt( KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT, timeoutMillisForCarrier2); doReturn(carrierConfigBundle2) .when(mCarrierConfigManager).getConfigForSubId(eq(SUB_ID1), anyVararg()); for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair : mCarrierConfigChangedListenerList) { pair.first.execute(() -> pair.second.onCarrierConfigChanged( /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } processAllMessages(); // Both phones are not in satellite mode for carrier roaming, and thus the max timeout // duration - timeoutMillisForCarrier2 - is used assertEquals(timeoutMillisForCarrier2, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Phone 1 is in satellite mode for carrier roaming when(mServiceState.isUsingNonTerrestrialNetwork()).thenReturn(true); assertEquals(timeoutMillisForCarrier1, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); // Both phones are in satellite mode for carrier roaming. The timeout duration of the first // phone will be selected when(mServiceState2.isUsingNonTerrestrialNetwork()).thenReturn(true); assertEquals(timeoutMillisForCarrier1, mSatelliteControllerUT.getCarrierEmergencyCallWaitForConnectionTimeoutMillis()); } private void resetSatelliteControllerUTEnabledState() { logd("resetSatelliteControllerUTEnabledState"); setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE); Loading
tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java +51 −9 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ import java.util.concurrent.Executor; @TestableLooper.RunWithLooper public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { private static final String TAG = "SatelliteSOSMessageRecommenderTest"; private static final long TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 500; private static final int TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 500; private static final int PHONE_ID = 0; private static final int PHONE_ID2 = 1; private static final String CALL_ID = "CALL_ID"; Loading Loading @@ -118,6 +118,9 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { .thenReturn(""); when(mResources.getString(R.string.config_satellite_emergency_handover_intent_action)) .thenReturn(DEFAULT_HANDOVER_INTENT_ACTION); when(mResources.getInteger( R.integer.config_emergency_call_wait_for_connection_timeout_millis)) .thenReturn(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS); when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true); mTestSatelliteController = new TestSatelliteController(mContext, Looper.myLooper(), mFeatureFlags); Loading @@ -132,8 +135,7 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { when(mPhone2.getServiceState()).thenReturn(mServiceState2); when(mPhone2.getPhoneId()).thenReturn(PHONE_ID2); mTestSOSMessageRecommender = new TestSOSMessageRecommender(mContext, Looper.myLooper(), mTestSatelliteController, mTestImsManager, TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS); mTestSatelliteController, mTestImsManager); when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); when(mServiceState2.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); when(mPhone.isImsRegistered()).thenReturn(false); Loading Loading @@ -505,8 +507,7 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { TestSOSMessageRecommender testSOSMessageRecommender = new TestSOSMessageRecommender( mContext, Looper.myLooper(), satelliteController, mTestImsManager, TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS); satelliteController, mTestImsManager); testSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); Loading @@ -532,6 +533,32 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { originalIsSatelliteViaOemProvisioned; } @Test public void testSelectEmergencyCallWaitForConnectionTimeoutDuration() { // Both OEM and carrier don't support satellite mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = false; mTestSatelliteController.isOemEnabledSatelliteSupported = false; mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); assertEquals(0, mTestSOSMessageRecommender.getTimeOutMillis()); // Only OEM support satellite mTestSatelliteController.isOemEnabledSatelliteSupported = true; mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); assertEquals(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS, mTestSOSMessageRecommender.getTimeOutMillis()); // Both OEM and carrier support satellite. Thus, carrier's timeout duration will be used long carrierTimeoutMillis = 1000; mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = true; mTestSatelliteController.carrierEmergencyCallWaitForConnectionTimeoutMillis = carrierTimeoutMillis; mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); processAllMessages(); assertEquals(carrierTimeoutMillis, mTestSOSMessageRecommender.getTimeOutMillis()); } private void testStopTrackingCallBeforeTimeout( @Connection.ConnectionState int connectionState) { mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection); Loading Loading @@ -636,6 +663,9 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { private boolean mIsSatelliteConnectedViaCarrierWithinHysteresisTime = true; public boolean isOemEnabledSatelliteSupported = true; public boolean isCarrierEnabledSatelliteSupported = true; public boolean isSatelliteEmergencyMessagingSupportedViaCarrier = true; public long carrierEmergencyCallWaitForConnectionTimeoutMillis = TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS; /** * Create a SatelliteController to act as a backend service of Loading Loading @@ -696,6 +726,16 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { return INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE; } @Override public boolean isSatelliteEmergencyMessagingSupportedViaCarrier() { return isSatelliteEmergencyMessagingSupportedViaCarrier; } @Override public long getCarrierEmergencyCallWaitForConnectionTimeoutMillis() { return carrierEmergencyCallWaitForConnectionTimeoutMillis; } public void setSatelliteConnectedViaCarrierWithinHysteresisTime( boolean connectedViaCarrier) { mIsSatelliteConnectedViaCarrierWithinHysteresisTime = connectedViaCarrier; Loading Loading @@ -811,12 +851,10 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { * @param imsManager The ImsManager instance associated with the phone, which is * used for making the emergency call. This argument is not * null only in unit tests. * @param timeoutMillis The timeout duration of the timer. */ TestSOSMessageRecommender(Context context, Looper looper, SatelliteController satelliteController, ImsManager imsManager, long timeoutMillis) { super(context, looper, satelliteController, imsManager, timeoutMillis); SatelliteController satelliteController, ImsManager imsManager) { super(context, looper, satelliteController, imsManager); } @Override Loading @@ -843,6 +881,10 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest { public void sendServiceStateChangedEvent() { sendMessage(obtainMessage(EVENT_SERVICE_STATE_CHANGED)); } public long getTimeOutMillis() { return mTimeoutMillis; } } private static class TestConnection extends Connection { Loading