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

Commit 30a60d07 authored by Nagendra Prasad Nagarle Basavaraju's avatar Nagendra Prasad Nagarle Basavaraju Committed by arunvoddu
Browse files

Update available services info for satellite

- Support Allowed Services Info from Entitlement at getSupportedServicesOnCarrierRoamingNtn()

Flag: com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn
Bug: 377367448
Test: m and atest
Change-Id: I4695fb04610d1ba5b66b85bacb92904f3da8bfdf
parent 9a9abb28
Loading
Loading
Loading
Loading
+67 −5
Original line number Diff line number Diff line
@@ -4337,9 +4337,10 @@ public class SatelliteController extends Handler {
                mEntitlementPlmnListPerCarrier.put(subId, allowedPlmnList);
                mEntitlementBarredPlmnListPerCarrier.put(subId, barredPlmnList);
                mEntitlementDataPlanMapPerCarrier.put(subId, plmnDataPlanMap);
                mEntitlementServiceTypeMapPerCarrier.put(subId, plmnServiceTypeMap);
                mEntitlementDataServicePolicyMapPerCarrier.put(subId, plmnDataServicePolicyMap);
                mEntitlementVoiceServicePolicyMapPerCarrier.put(subId, plmnVoiceServicePolicyMap);
                updateAndNotifyChangesInCarrierRoamingNtnAvailableServices(subId,
                        plmnServiceTypeMap);
                updatePlmnListPerCarrier(subId);
                configureSatellitePlmnForCarrier(subId);
                mSubscriptionManagerService.setSatelliteEntitlementPlmnList(subId, allowedPlmnList);
@@ -8229,6 +8230,31 @@ public class SatelliteController extends Handler {
                        .build();
    }

    /**
     * The method will notify the change in the services update the
     * mEntitlementServiceTypeMapPerCarrier.
     *
     * @param subId              : SubscriptionId
     * @param plmnServiceTypeMap : entitlement service map.
     */
    private void updateAndNotifyChangesInCarrierRoamingNtnAvailableServices(int subId,
            Map<String, List<Integer>> plmnServiceTypeMap) {
        // If a service list is already cached, check it for changes
        int[] existingServices = getSupportedServicesOnCarrierRoamingNtn(subId);
        synchronized (mSupportedSatelliteServicesLock) {
            mEntitlementServiceTypeMapPerCarrier.put(subId, plmnServiceTypeMap);
        }
        int[] updatedServices = getSupportedServicesOnCarrierRoamingNtn(subId);
        if (existingServices.length > 0 && Arrays.equals(existingServices, updatedServices)) {
            plogd("No change in Entitlement service support data");
            return;
        }
        if (mFeatureFlags.carrierRoamingNbIotNtn()) {
            updateLastNotifiedNtnAvailableServicesAndNotify(subId);
            evaluateCarrierRoamingNtnEligibilityChange();
        }
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    protected void handleCarrierRoamingNtnAvailableServicesChanged(int subId) {
        if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
@@ -8255,11 +8281,47 @@ public class SatelliteController extends Handler {
        phone.notifyCarrierRoamingNtnAvailableServicesChanged(services);
    }

    /** Return services that are supported on carrier roaming non-terrestrial network. */
    private int[] getAvailableServicesWithEntitlementForSubId(int subId) {
        synchronized (mSupportedSatelliteServicesLock) {
            Map<String, List<Integer>> allowedServicesList =
                    mEntitlementServiceTypeMapPerCarrier.get(subId);
            if (allowedServicesList != null && !allowedServicesList.isEmpty()) {
                Set<Integer> serviceTypes = new HashSet<>();
                for (List<Integer> values : allowedServicesList.values()) {
                    serviceTypes.addAll(values);
                }

                int[] result = new int[serviceTypes.size()];
                int i = 0;
                for (int value : serviceTypes) {
                    result[i++] = value;
                }
                return result;
            } else {
                return new int[0]; // Return an empty array if the map is null or empty
            }
        }
    }

    /**
     * Given a subscription ID, this returns the carriers' supported services on
     * non-terrestrial networks.
     *
     * @param subId Associated subscription ID.
     * return supported services at entitlement for the available carriers. Note: If available
     *        services/allowed service type field is empty at entitlement, information from
     *        {@link
     *        CarrierConfigManager#KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY}
     *        will be returned.
     */
    public int[] getSupportedServicesOnCarrierRoamingNtn(int subId) {
        if (isSatelliteSupportedViaCarrier(subId)) {
            // TODO: b/377367448 Cleanup get supported satellite services to align with starlink.
            int[] services = getSupportedSatelliteServicesForCarrier(subId);
        if (isValidSubscriptionId(subId) && isSatelliteSupportedViaCarrier(subId)) {
            // check available services supported at entitlement for sub id
            int[] services = getAvailableServicesWithEntitlementForSubId(subId);
            logd("getAvailableServicesWithEntitlementForSubId: " + Arrays.toString(services));
            if (services.length == 0) {
                services = getSupportedSatelliteServicesForCarrier(subId);
            }
            if (isP2PSmsDisallowedOnCarrierRoamingNtn(subId)) {
                services = Arrays.stream(services).filter(
                        value -> value != NetworkRegistrationInfo.SERVICE_TYPE_SMS).toArray();
+153 −1
Original line number Diff line number Diff line
@@ -207,6 +207,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@@ -6174,6 +6175,8 @@ public class SatelliteControllerTest extends TelephonyTest {
        public boolean mIsApplicationSupportsP2P = false;
        public int selectedSatelliteSubId = -1;

        private boolean callOnlySuperMethod = false;

        TestSatelliteController(
                Context context, Looper looper, @NonNull FeatureFlags featureFlags) {
            super(context, looper, featureFlags);
@@ -6262,8 +6265,12 @@ public class SatelliteControllerTest extends TelephonyTest {

        @Override
        protected void handleCarrierRoamingNtnAvailableServicesChanged(int subId) {
            if (callOnlySuperMethod) {
                super.handleCarrierRoamingNtnAvailableServicesChanged(subId);
            } else {
                isApplicationUpdated = true;
            }
        }

        @Override
        public boolean isApplicationSupportsP2P(String packageName) {
@@ -6272,6 +6279,9 @@ public class SatelliteControllerTest extends TelephonyTest {

        @Override
        public int[] getSupportedServicesOnCarrierRoamingNtn(int subId) {
            if (callOnlySuperMethod) {
                return super.getSupportedServicesOnCarrierRoamingNtn(subId);
            }
            return new int[]{3, 5};
        }

@@ -6353,6 +6363,10 @@ public class SatelliteControllerTest extends TelephonyTest {
                mSatelliteAccessAllowed = isAllowed;
            }
        }

        public void setCallOnlySuperMethod() {
            callOnlySuperMethod = true;
        }
    }

    @Test
@@ -6664,4 +6678,142 @@ public class SatelliteControllerTest extends TelephonyTest {
                .getSatelliteDataServicePolicyForPlmn(SUB_ID, "00101");
        assertEquals(SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED, dataSupportModeForPlmn);
    }

    @Test
    public void testNotifyCarrierRoamingNtnAvailableServicesChanged_noServices() throws Exception {
        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
        mSatelliteControllerUT.setCallOnlySuperMethod();
        List<String> overlayConfigPlmnList = new ArrayList<>();
        replaceInstance(SatelliteController.class, "mSatellitePlmnListFromOverlayConfig",
                mSatelliteControllerUT, overlayConfigPlmnList);
        mCarrierConfigBundle.putBoolean(
                CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
        mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
                true);
        List<String> entitlementPlmnList = Arrays.stream(
                new String[]{"00101", "00102", "00103", "00104"}).toList();
        mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
                entitlementPlmnList, new ArrayList<>(), new HashMap<>(),
                new HashMap<>() /*serviceTypeListMap*/, new HashMap<>(), new HashMap<>(),
                mIIntegerConsumer);
        verify(mPhone, times(1)).notifyCarrierRoamingNtnAvailableServicesChanged(
                (int[]) ArgumentMatchers.any());
    }

    @Test
    public void testNotifyCarrierRoamingNtnAvailableServicesChanged() throws Exception {
        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
        mSatelliteControllerUT.setCallOnlySuperMethod();
        List<String> overlayConfigPlmnList = new ArrayList<>();
        replaceInstance(SatelliteController.class, "mSatellitePlmnListFromOverlayConfig",
                mSatelliteControllerUT, overlayConfigPlmnList);
        mCarrierConfigBundle.putBoolean(
                CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
        mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
                true);

        List<String> entitlementPlmnList = Arrays.stream(
                new String[]{"00101", "00102", "00103", "00104"}).toList();
        List<String> barredPlmnList = new ArrayList<>();
        Map<String, List<Integer>> serviceTypeListMap = Map.of("00101",
                List.of(SERVICE_TYPE_DATA, SERVICE_TYPE_SMS), "00102",
                List.of(SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS), "00103",
                List.of(SERVICE_TYPE_DATA, SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS));
        mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
                entitlementPlmnList, barredPlmnList, new HashMap<>(), serviceTypeListMap,
                new HashMap<>(), new HashMap<>(), mIIntegerConsumer);
        int[] expectedServices = new int[]{1, 2, 3};
        int[] supportedServices = mSatelliteControllerUT.getSupportedServicesOnCarrierRoamingNtn(
                SUB_ID);
        assertArrayEquals(expectedServices, supportedServices);
        verify(mPhone, times(1)).notifyCarrierRoamingNtnAvailableServicesChanged(
                (int[]) ArgumentMatchers.any());
    }

    @Test
    public void testNotifyCarrierRoamingNtnAvailableServicesChange_duplicateUpdates()
            throws Exception {
        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
        mSatelliteControllerUT.setCallOnlySuperMethod();
        List<String> overlayConfigPlmnList = new ArrayList<>();
        replaceInstance(SatelliteController.class, "mSatellitePlmnListFromOverlayConfig",
                mSatelliteControllerUT, overlayConfigPlmnList);
        mCarrierConfigBundle.putBoolean(
                CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
        mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
                true);

        List<String> entitlementPlmnList = Arrays.stream(
                new String[]{"00101", "00102", "00103", "00104"}).toList();
        List<String> barredPlmnList = new ArrayList<>();
        Map<String, List<Integer>> serviceTypeListMap = Map.of("00101",
                List.of(SERVICE_TYPE_DATA, SERVICE_TYPE_SMS), "00102",
                List.of(SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS), "00103",
                List.of(SERVICE_TYPE_DATA, SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS));
        mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
                entitlementPlmnList, barredPlmnList, new HashMap<>(), serviceTypeListMap,
                new HashMap<>(), new HashMap<>(), mIIntegerConsumer);
        int[] expectedServices = new int[]{1, 2, 3};
        int[] supportedServices = mSatelliteControllerUT.getSupportedServicesOnCarrierRoamingNtn(
                SUB_ID);
        assertArrayEquals(expectedServices, supportedServices);
        verify(mPhone, times(1)).notifyCarrierRoamingNtnAvailableServicesChanged(
                (int[]) ArgumentMatchers.any());

        mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
                entitlementPlmnList, barredPlmnList, new HashMap<>(), serviceTypeListMap,
                new HashMap<>(), new HashMap<>(), mIIntegerConsumer);
        // There is no change in services between 2 calls, so notify should not invoke again.
        supportedServices = mSatelliteControllerUT.getSupportedServicesOnCarrierRoamingNtn(SUB_ID);
        assertArrayEquals(expectedServices, supportedServices);
        verify(mPhone, times(1)).notifyCarrierRoamingNtnAvailableServicesChanged(
                (int[]) ArgumentMatchers.any());
    }

    @Test
    public void testNotifyCarrierRoamingNtnAvailableServicesChange_multipleUpdates()
            throws Exception {
        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
        mSatelliteControllerUT.setCallOnlySuperMethod();
        List<String> overlayConfigPlmnList = new ArrayList<>();
        replaceInstance(SatelliteController.class, "mSatellitePlmnListFromOverlayConfig",
                mSatelliteControllerUT, overlayConfigPlmnList);
        mCarrierConfigBundle.putBoolean(
                CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
        mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
                true);

        List<String> entitlementPlmnList = Arrays.stream(
                new String[]{"00101", "00102", "00103", "00104"}).toList();
        List<String> barredPlmnList = new ArrayList<>();
        Map<String, List<Integer>> serviceTypeListMap = Map.of("00101",
                List.of(SERVICE_TYPE_DATA, SERVICE_TYPE_SMS), "00102",
                List.of(SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS), "00103",
                List.of(SERVICE_TYPE_DATA, SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS));
        mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
                entitlementPlmnList, barredPlmnList, new HashMap<>(), serviceTypeListMap,
                new HashMap<>(), new HashMap<>(), mIIntegerConsumer);
        int[] expectedServices = new int[]{1, 2, 3};
        int[] supportedServices = mSatelliteControllerUT.getSupportedServicesOnCarrierRoamingNtn(
                SUB_ID);
        assertArrayEquals(expectedServices, supportedServices);
        verify(mPhone, times(1)).notifyCarrierRoamingNtnAvailableServicesChanged(
                (int[]) ArgumentMatchers.any());

        serviceTypeListMap = Map.of("00101", List.of(SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS), "00102",
                List.of(SERVICE_TYPE_SMS), "00103", List.of(SERVICE_TYPE_VOICE, SERVICE_TYPE_SMS));
        mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
                entitlementPlmnList, barredPlmnList, new HashMap<>(), serviceTypeListMap,
                new HashMap<>(), new HashMap<>(), mIIntegerConsumer);
        expectedServices = new int[]{1, 3};
        supportedServices = mSatelliteControllerUT.getSupportedServicesOnCarrierRoamingNtn(SUB_ID);
        assertArrayEquals(expectedServices, supportedServices);
        // 2 times notify called due to previous and current changes
        verify(mPhone, times(2)).notifyCarrierRoamingNtnAvailableServicesChanged(
                (int[]) ArgumentMatchers.any());
    }
}