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

Commit 6a489a8e authored by Hidayat Khan's avatar Hidayat Khan
Browse files

Changes to support geofence for carrier satellite

Bug: 381798055
Test: atest SatelliteControllerTest
FLAG: com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn
Change-Id: Ie1972bdd8e4e7edc2437ca524a09317ea5ddb682
parent 2fc488ae
Loading
Loading
Loading
Loading
+164 −6
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
import android.telephony.satellite.ISelectedNbIotSatelliteSubscriptionCallback;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteModemEnableRequestAttributes;
@@ -146,6 +147,7 @@ import android.telephony.satellite.SatelliteSubscriberInfo;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.telephony.satellite.SatelliteSubscriptionInfo;
import android.telephony.satellite.SystemSelectionSpecifier;
import android.telephony.satellite.SatelliteAccessConfiguration;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -319,6 +321,7 @@ public class SatelliteController extends Handler {
    @NonNull private final ProvisionMetricsStats mProvisionMetricsStats;
    @NonNull private SessionMetricsStats mSessionMetricsStats;
    @NonNull private CarrierRoamingSatelliteControllerStats mCarrierRoamingSatelliteControllerStats;

    @NonNull private final SubscriptionManagerService mSubscriptionManagerService;
    @NonNull private final TelephonyCountryDetector mCountryDetector;
    @NonNull private final TelecomManager mTelecomManager;
@@ -391,6 +394,8 @@ public class SatelliteController extends Handler {
            new AtomicBoolean(false);
    private final AtomicBoolean mRegisteredForTerrestrialNetworkAvailableChanged =
            new AtomicBoolean(false);
    private final AtomicBoolean mRegisteredForSatelliteCommunicationAllowedStateChanged =
        new AtomicBoolean(false);
    /**
     * Map key: subId, value: callback to get error code of the provision request.
     */
@@ -725,6 +730,15 @@ public class SatelliteController extends Handler {
    // device.
    private List<DeviceState> mDeviceStates = new ArrayList();

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    protected final Object mSatelliteAccessConfigLock = new Object();
    @GuardedBy("mSatelliteAccessConfigLock")
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    protected List<Integer> mCurrentLocationTagIds = new ArrayList();
    @GuardedBy("mSatelliteAccessConfigLock")
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    protected boolean mSatelliteAccessAllowed = false;

    public static final int RESULT_RECEIVER_COUNT_ANOMALY_THRESHOLD = 500;
    protected final Object mResultReceiverTotalCountLock = new Object();
    @GuardedBy("mResultReceiverTotalCountLock")
@@ -884,6 +898,7 @@ public class SatelliteController extends Handler {
        registerForSatelliteModemStateChanged();
        registerForServiceStateChanged();
        registerForSignalStrengthChanged();
        registerForSatelliteCommunicationAllowedStateChanged();
        mContentResolver = mContext.getContentResolver();
        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);

@@ -5637,7 +5652,7 @@ public class SatelliteController extends Handler {
                KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL);
    }

    public int getCarrierRoamingNtnConnectType(int subId) {
    private int getCarrierRoamingNtnConnectType(int subId) {
        return getConfigForSubId(subId).getInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT);
    }

@@ -6092,6 +6107,8 @@ public class SatelliteController extends Handler {
            return;
        }

        registerForSatelliteCommunicationAllowedStateChanged();

        boolean eligible = isCarrierRoamingNtnEligible(getSatellitePhone());
        plogd("evaluateCarrierRoamingNtnEligibilityChange: "
                + "isCarrierRoamingNtnEligible=" + eligible);
@@ -7053,6 +7070,8 @@ public class SatelliteController extends Handler {
                        mSubscriptionManagerService.getDefaultSmsSubId() == subId;
                boolean isNtnOnly = info.isOnlyNonTerrestrialNetwork();
                boolean isESOSSupported = info.isSatelliteESOSSupported();
                boolean isCarrierSatelliteHigherPriority =
                    isCarrierSatelliteHigherPriority(info);
                if (!isNtnOnly && !isESOSSupported) {
                    continue;
                }
@@ -7065,9 +7084,13 @@ public class SatelliteController extends Handler {
                    continue;
                }

                int keyPriority = (isESOSSupported && isActive && isDefaultSmsSubId) ? 0
                        : (isESOSSupported && isActive) ? 1
                                : (isNtnOnly) ? 2 : (isESOSSupported) ? 3 : -1;
                int keyPriority = (isESOSSupported && isActive && isDefaultSmsSubId
                    && isCarrierSatelliteHigherPriority)
                    ? 0 : (isESOSSupported && isActive &&
                        isCarrierSatelliteHigherPriority)
                        ? 1 : (isNtnOnly)
                            ? 2 : (isESOSSupported)
                                ? 3 : -1;
                if (keyPriority != -1) {
                    newSubsInfoListPerPriority.computeIfAbsent(keyPriority,
                            k -> new ArrayList<>()).add(info);
@@ -7379,11 +7402,14 @@ public class SatelliteController extends Handler {
        int selectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        List<SatelliteSubscriberProvisionStatus> satelliteSubscribers =
                getPrioritizedSatelliteSubscriberProvisionStatusList();

        for (SatelliteSubscriberProvisionStatus status : satelliteSubscribers) {
            // TODO: need to check if satellite is allowed at current location for the subscription
            int subId = getSubIdFromSubscriberId(
                    status.getSatelliteSubscriberInfo().getSubscriberId());
            if (status.isProvisioned() && isActiveSubId(subId)) {

            if (status.isProvisioned() && isActiveSubId(subId) &&
                isSatelliteAvailableAtCurrentLocation(
                    mSubscriptionManagerService.getSubscriptionInfo(subId))) {
                selectedSubId = subId;
                break;
            }
@@ -7402,6 +7428,67 @@ public class SatelliteController extends Handler {
        handleEventSelectedNbIotSatelliteSubscriptionChanged(selectedSubId);
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    protected boolean isCarrierSatelliteHigherPriority(SubscriptionInfo info) {
        if(!isSatelliteAccessAllowedAtCurrentLocation()) {
            return true;
        }
        if(isSatelliteAvailableAtCurrentLocation(info)) {
            return true;
        }
        return false;
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    protected boolean isSatelliteAvailableAtCurrentLocation(@Nullable SubscriptionInfo info) {
        if(info == null) {
            plogd("isSatelliteAvailableAtCurrentLocation: subscriptionInfo is null");
            return false;
        }
        if (!isSatelliteAccessAllowedAtCurrentLocation()) {
            plogd("isSatelliteAvailableAtCurrentLocation: satellite access is not allowed at " +
                    "current location");
            return false;
        }
        if(info.isOnlyNonTerrestrialNetwork()) {
            return true;
        }

        int[] carrierTagIdsArray = mContext.getResources().getIntArray(
            R.array.config_verizon_satellite_enabled_tagids);
        List<Integer> carrierTagIds = null;

        if(carrierTagIdsArray != null && carrierTagIdsArray.length > 0) {
            carrierTagIds = Arrays.stream(carrierTagIdsArray)
                .boxed()
                .collect(Collectors.toList());
        }

        if(carrierTagIds == null) {
            plogd("isSatelliteAvailableAtCurrentLocation: tagids for carrier satellite enabled " +
                    "are not available");
            return false;
        }

        return isCarrierSatelliteAvailableAtCurrentLocation(carrierTagIds);
    }

    /**
     * Compares tagIds and determine if
     * carrier satellite is available at current location while selecting highest priority profile.
     *
     * @param carrierTagIds a list of integer tagIds representing regions where carrier satellite
     * coverage is available.
     * @return {@code true} if the carrier satellite is available at current location,
     *      {@code false} otherwise.
     */
    public boolean isCarrierSatelliteAvailableAtCurrentLocation(
        List<Integer> carrierTagIds) {
        synchronized (mSatelliteAccessConfigLock) {
            return !Collections.disjoint(carrierTagIds, mCurrentLocationTagIds);
        }
    }

    private int getSubIdFromSubscriberId(String subscriberId) {
        synchronized (mSatelliteTokenProvisionedLock) {
            return mSubscriberIdPerSub.getOrDefault(subscriberId,
@@ -7819,6 +7906,71 @@ public class SatelliteController extends Handler {
        }
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    protected void registerForSatelliteCommunicationAllowedStateChanged() {
        if (mRegisteredForSatelliteCommunicationAllowedStateChanged.get()) {
            if (DEBUG) {
                plogd("registerForSatelliteCommunicationAllowedStateChanged: already registered.");
            }
            return;
        }

        SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class);
        if (satelliteManager == null) {
            ploge("registerForSatelliteCommunicationAllowedStateChanged: SatelliteManager is null");
            return;
        }

        SatelliteCommunicationAllowedStateCallback allowedStateCallback =
            new SatelliteCommunicationAllowedStateCallback() {
                @Override
                public void onSatelliteCommunicationAllowedStateChanged(boolean isAllowed) {
                    plogd("onSatelliteCommunicationAllowedStateChanged: isAllowed="
                        + isAllowed);
                    synchronized (mSatelliteAccessConfigLock) {
                        mSatelliteAccessAllowed = isAllowed;
                    }
                }

                @Override
                public void onSatelliteAccessConfigurationChanged(
                    SatelliteAccessConfiguration satelliteAccessConfiguration) {
                    plogd("onSatelliteAccessConfigurationChanged: satelliteAccessConfiguration="
                        + satelliteAccessConfiguration);
                    handleSatelliteAccessConfigUpdateResult(satelliteAccessConfiguration);
                }
            };
        try {
            satelliteManager.registerForCommunicationAllowedStateChanged(
                    this::post, allowedStateCallback);
        } catch(RuntimeException e) {
            plogd("registerForSatelliteCommunicationAllowedStateChanged: " +
                    "satelliteManager.registerForCommunicationAllowedStateChanged() failed, " +
                    "e=" + e);
            return;
        }
        mRegisteredForSatelliteCommunicationAllowedStateChanged.set(true);
    }

    private void handleSatelliteAccessConfigUpdateResult(
        SatelliteAccessConfiguration satelliteAccessConfig) {
        if(satelliteAccessConfig != null) {
            synchronized (mSatelliteAccessConfigLock) {
                plogd("handleSatelliteAccessConfigUpdateResult:" + " satelliteAccessConfig="
                    + satelliteAccessConfig);
                List<Integer> tagIds = satelliteAccessConfig.getTagIds();
                if (!mCurrentLocationTagIds.equals(tagIds)) {
                    mCurrentLocationTagIds = tagIds;
                    sendMessageDelayed(obtainMessage(CMD_EVALUATE_ESOS_PROFILES_PRIORITIZATION),
                        mEvaluateEsosProfilesPrioritizationDurationMillis);
                }
            }
        } else {
                plogd("handleSatelliteAccessConfigUpdateResult: "
                    + "satelliteAccessConfiguration is null");
        }
    }

    private void handleEventSatelliteRegistrationFailure(int causeCode) {
        plogd("handleEventSatelliteRegistrationFailure: " + causeCode);

@@ -8332,6 +8484,12 @@ public class SatelliteController extends Handler {
        }
    }

    private boolean isSatelliteAccessAllowedAtCurrentLocation() {
        synchronized (mSatelliteAccessConfigLock) {
            return mSatelliteAccessAllowed;
        }
    }

    @Nullable
    private Boolean getIsSatelliteEnabled() {
        synchronized (mIsSatelliteEnabledLock) {
+110 −14
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ import android.telephony.satellite.ISatelliteSupportedStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
import android.telephony.satellite.ISelectedNbIotSatelliteSubscriptionCallback;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteAccessConfiguration;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteInfo;
@@ -258,6 +259,9 @@ public class SatelliteControllerTest extends TelephonyTest {
    private PersistableBundle mCarrierConfigBundle;
    private ServiceState mServiceState2;

    private SubscriptionInfo testSubscriptionInfo;
    private SubscriptionInfo testSubscriptionInfo2;

    @Mock private SatelliteController mMockSatelliteController;
    @Mock private DatagramController mMockDatagramController;
    @Mock private SatelliteModemInterface mMockSatelliteModemInterface;
@@ -1769,7 +1773,7 @@ public class SatelliteControllerTest extends TelephonyTest {
        assertEquals(SATELLITE_RESULT_SUCCESS, errorCode);

        try {
            setSatelliteSubscriberTesting();
            setSatelliteSubscriberTesting(true);
        } catch (Exception ex) {
            fail("provisionSatelliteService.setSatelliteSubscriberTesting: ex=" + ex);
        }
@@ -4639,7 +4643,7 @@ public class SatelliteControllerTest extends TelephonyTest {
    }

    private void verifyRequestSatelliteSubscriberProvisionStatus() throws Exception {
        setSatelliteSubscriberTesting();
        setSatelliteSubscriberTesting(true);
        List<SatelliteSubscriberInfo> list = getExpectedSatelliteSubscriberInfoList();
        mCarrierConfigBundle.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        mCarrierConfigBundle.putString(KEY_SATELLITE_NIDD_APN_NAME_STRING, mNiddApn);
@@ -4855,26 +4859,31 @@ public class SatelliteControllerTest extends TelephonyTest {
        assertTrue(mDeprovisionDone);
    }

    private void setSatelliteSubscriberTesting() throws Exception {
    private void setSatelliteSubscriberTesting(boolean sameCarrier) throws Exception {
        doReturn("123").when(mContext).getAttributionTag();
        final int carrierId = 0;
        final int carrierId_subID = 0;
        final int carrierId_subID1 = sameCarrier ? 0 : 1;
        SubscriptionInfo subscriptionInfo = new SubscriptionInfo.Builder()
                .setId(SUB_ID).setIccId(mIccId).setSimSlotIndex(0).setOnlyNonTerrestrialNetwork(
                        false).setSatelliteESOSSupported(true).setCarrierId(carrierId).build();
                        false).setSatelliteESOSSupported(true).setCarrierId(
                            carrierId_subID).build();
        SubscriptionInfo subscriptionInfo2 = new SubscriptionInfo.Builder()
                .setId(SUB_ID1).setIccId(mIccId2).setSimSlotIndex(1).setOnlyNonTerrestrialNetwork(
                        true).setSatelliteESOSSupported(false).setCarrierId(carrierId).build();
                        true).setSatelliteESOSSupported(false).setCarrierId(
                            carrierId_subID1).build();
        List<SubscriptionInfo> allSubInfos = new ArrayList<>();
        allSubInfos.add(subscriptionInfo);
        allSubInfos.add(subscriptionInfo2);
        testSubscriptionInfo = subscriptionInfo;
        testSubscriptionInfo2 = subscriptionInfo2;
        doReturn(allSubInfos).when(mMockSubscriptionManagerService).getAllSubInfoList(
                anyString(), anyString());
        SubscriptionInfoInternal subInfoInternal =
                new SubscriptionInfoInternal.Builder().setCarrierId(0).setImsi(mImsi).setIccId(
                        mIccId).build();
                new SubscriptionInfoInternal.Builder().setCarrierId(
                    carrierId_subID).setImsi(mImsi).setIccId(mIccId).build();
        SubscriptionInfoInternal subInfoInternal2 =
                new SubscriptionInfoInternal.Builder().setCarrierId(0).setImsi(mImsi2).setIccId(
                        mIccId2).build();
                new SubscriptionInfoInternal.Builder().setCarrierId(
                    carrierId_subID1).setImsi(mImsi2).setIccId(mIccId2).build();
        doReturn(subscriptionInfo).when(mMockSubscriptionManagerService).getSubscriptionInfo(
                eq(SUB_ID));
        doReturn(subscriptionInfo2).when(mMockSubscriptionManagerService).getSubscriptionInfo(
@@ -5017,11 +5026,80 @@ public class SatelliteControllerTest extends TelephonyTest {
        verify(mContext, times(1)).sendBroadcast(any(Intent.class));
    }

    @Test
    public void testRegisterForSatelliteCommunicationAllowedStateChanged() throws Exception {
        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
        mContextFixture.putIntArrayResource(
                R.array.config_verizon_satellite_enabled_tagids,
                new int[]{1001});
        when(mContext.getResources()).thenReturn(mResources);
        when(mResources.getIntArray(
                R.array.config_verizon_satellite_enabled_tagids)).thenReturn(new int[]{1001});
        // carrierID is same as SUBID for this test
        final int carrierSubId = SUB_ID;
        final int oemSubId = SUB_ID1;
        final String carrierSubscriberId = mSubscriberId;
        final String oemSubscriberId = mSubscriberId2;
        mCarrierConfigBundle.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        setSatelliteSubscriberTesting(false);
        invokeCarrierConfigChanged();

        Field provisionedSubscriberIdField = SatelliteController.class.getDeclaredField(
                "mProvisionedSubscriberId");
        provisionedSubscriberIdField.setAccessible(true);
        Map<String, Boolean> testProvisionedSubscriberId = new HashMap<>();;
        testProvisionedSubscriberId.put(carrierSubscriberId, true);
        testProvisionedSubscriberId.put(oemSubscriberId, true);
        provisionedSubscriberIdField.set(mSatelliteControllerUT, testProvisionedSubscriberId);

        Field currentLocationTagIdsField = SatelliteController.class.getDeclaredField(
                "mCurrentLocationTagIds");
        currentLocationTagIdsField.setAccessible(true);

        setComponentName();
        mSatelliteControllerUT.setIsSatelliteAllowedState(true);

        mSatelliteControllerUT.registerForSatelliteCommunicationAllowedStateChanged();

        // Test satelliteAccessConfigCallback.onSuccess
        // with current location NOT supporting carrier satellite
        // OEM satellite subscription should be selected
        currentLocationTagIdsField.set(mSatelliteControllerUT, Arrays.asList(100));

        mSatelliteControllerUT.subsInfoListPerPriority().computeIfAbsent(
                        getKeyPriority(testSubscriptionInfo), k -> new ArrayList<>())
                .add(testSubscriptionInfo);
        mSatelliteControllerUT.subsInfoListPerPriority().computeIfAbsent(
                        getKeyPriority(testSubscriptionInfo2), k -> new ArrayList<>())
                .add(testSubscriptionInfo2);

        mSatelliteControllerUT.evaluateESOSProfilesPrioritizationTest();
        processAllMessages();
        assertEquals(oemSubId, mSatelliteControllerUT.getSelectedSatelliteSubId());

        // Test satelliteAccessConfigCallback.onSuccess
        // with current location supporting carrier satellite
        // Carrier satellite subscription should be selected
        currentLocationTagIdsField.set(mSatelliteControllerUT, Arrays.asList(1001, 100));

        mSatelliteControllerUT.subsInfoListPerPriority().computeIfAbsent(
                        getKeyPriority(testSubscriptionInfo), k -> new ArrayList<>())
                .add(testSubscriptionInfo);
        mSatelliteControllerUT.subsInfoListPerPriority().computeIfAbsent(
                        getKeyPriority(testSubscriptionInfo2), k -> new ArrayList<>())
                .add(testSubscriptionInfo2);

        mSatelliteControllerUT.evaluateESOSProfilesPrioritizationTest();
        processAllMessages();
        assertEquals(carrierSubId, mSatelliteControllerUT.getSelectedSatelliteSubId());
    }


    @Test
    public void testProvisionStatusPerSubscriberIdGetFromDb() throws Exception {
        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);

        setSatelliteSubscriberTesting();
        setSatelliteSubscriberTesting(true);
        // Check if the cache is not updated when the value read from the database is false.
        verifyProvisionStatusPerSubscriberIdGetFromDb(false);

@@ -5033,7 +5111,7 @@ public class SatelliteControllerTest extends TelephonyTest {
    public void testProvisionStatusPerSubscriberIdStoreToDb() throws Exception {
        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);

        setSatelliteSubscriberTesting();
        setSatelliteSubscriberTesting(true);
        // Check if the cache is not updated when the value read from the database is false.
        verifyProvisionStatusPerSubscriberIdGetFromDb(false);

@@ -5333,9 +5411,12 @@ public class SatelliteControllerTest extends TelephonyTest {
        boolean isActive = subscriptionInfo.isActive();
        boolean isNtnOnly = subscriptionInfo.isOnlyNonTerrestrialNetwork();
        boolean isESOSSupported = subscriptionInfo.isSatelliteESOSSupported();
        boolean isCarrierSatelliteHigherPriority =
                mSatelliteControllerUT.isCarrierSatelliteHigherPriorityTest(
                        subscriptionInfo);

        int keyPriority;
        if (isESOSSupported && isActive) {
        if (isESOSSupported && isActive && isCarrierSatelliteHigherPriority) {
            keyPriority = 1;
        } else if (isNtnOnly) {
            keyPriority = 2;
@@ -5931,7 +6012,7 @@ public class SatelliteControllerTest extends TelephonyTest {
        verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);

        try {
            setSatelliteSubscriberTesting();
            setSatelliteSubscriberTesting(true);
        } catch (Exception ex) {
            fail("provisionSatelliteService.setSatelliteSubscriberTesting: ex=" + ex);
        }
@@ -6157,6 +6238,11 @@ public class SatelliteControllerTest extends TelephonyTest {
            return elapsedRealtime;
        }

        @Override
        protected void registerForSatelliteCommunicationAllowedStateChanged() {
            logd("registerForSatelliteCommunicationAllowedStateChanged");
        }

        void setSatelliteSessionController(SatelliteSessionController satelliteSessionController) {
            mSatelliteSessionController = satelliteSessionController;
        }
@@ -6263,6 +6349,10 @@ public class SatelliteControllerTest extends TelephonyTest {
            evaluateESOSProfilesPrioritization();
        }

        public boolean isCarrierSatelliteHigherPriorityTest(SubscriptionInfo info) {
            return isCarrierSatelliteHigherPriority(info);
        }

        public String getStringFromOverlayConfigTest(int resourceId) {
            return getStringFromOverlayConfig(resourceId);
        }
@@ -6282,6 +6372,12 @@ public class SatelliteControllerTest extends TelephonyTest {
                return mResultReceiverCountPerMethodMap;
            }
        }

        public void setIsSatelliteAllowedState(boolean isAllowed) {
            synchronized(mSatelliteAccessConfigLock) {
                mSatelliteAccessAllowed = isAllowed;
            }
        }
    }

    @Test
+10 −0
Original line number Diff line number Diff line
@@ -876,6 +876,11 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest {
            return isCarrierEnabledSatelliteSupported;
        }

        @Override
        protected void registerForSatelliteCommunicationAllowedStateChanged() {
            logd("registerForSatelliteCommunicationAllowedStateChanged");
        }

        @Override
        @SatelliteManager.SatelliteResult public int registerForSatelliteProvisionStateChanged(
                @NonNull ISatelliteProvisionStateCallback callback) {
@@ -997,6 +1002,11 @@ public class SatelliteSOSMessageRecommenderTest extends TelephonyTest {
            return List.of(new DeviceState(new DeviceState.Configuration.Builder(0 /* identifier */,
                    "DEFAULT" /* name */).build()));
        }

        @Override
        protected void registerForSatelliteCommunicationAllowedStateChanged() {
            logd("registerForSatelliteCommunicationAllowedStateChanged");
        }
    }

    private static class TestImsManager extends ImsManager {