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

Commit a4c178c3 authored by Jack Yu's avatar Jack Yu Committed by Sarah Chin
Browse files

Supported the legacy allowed initial attach APN types config

Some carriers requires user-added APNs to be used for initial
attach, but IA was automatically removed by the APN editor on
purpose. So the compromised solution was supporting the old
allowed IA APN types carrier config in the new data stack.

Fix: 216867081
Test: Manual
Change-Id: I08200da33e08bbb3729a66329a27fbcba7283141
Merged-In: I08200da33e08bbb3729a66329a27fbcba7283141
parent 34d7b5dc
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -792,13 +792,31 @@ public class DataConfigManager extends Handler {
    }

    /**
     * @return The PCO id used for determine if data networks are using NR advanved networks. 0
     * @return The PCO id used for determine if data networks are using NR advanced networks. 0
     * indicates this feature is disabled.
     */
    public int getNrAdvancedCapablePcoId() {
        return mCarrierConfig.getInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
    }

    /**
     * @return The allowed APN types for initial attach. The order in the list determines the
     * priority of it being considered as IA APN. Note this should be only used for some exception
     * cases that we need to use "user-added" APN for initial attach. The regular way to configure
     * IA APN is by adding "IA" type to the APN in APN config.
     */
    public @NonNull @ApnType List<Integer> getAllowedInitialAttachApnTypes() {
        String[] apnTypesArray = mCarrierConfig.getStringArray(
                CarrierConfigManager.KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY);
        if (apnTypesArray != null) {
            return Arrays.stream(apnTypesArray)
                    .map(ApnSetting::getApnTypesBitmaskFromString)
                    .collect(Collectors.toList());
        }

        return Collections.emptyList();
    }

    /**
     * Registration point for subscription info ready
     *
+15 −6
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.provider.Telephony;
import android.telephony.Annotation;
import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
@@ -432,17 +433,25 @@ public class DataProfileManager extends Handler {
     *
     * Note that starting from Android 13 only APNs that supports "IA" type will be used for
     * initial attach. Please update APN configuration file if needed.
     *
     * Some carriers might explicitly require that using "user-added" APN for initial
     * attach. In this case, exception can be configured through
     * {@link CarrierConfigManager#KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY}.
     */
    private void updateInitialAttachDataProfileAtModem() {
        DataProfile initialAttachDataProfile = null;
        if (mPreferredDataProfile != null
                && mPreferredDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IA)) {
            initialAttachDataProfile = mPreferredDataProfile;
        } else {
            initialAttachDataProfile = mAllDataProfiles.stream()
                    .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IA))

        // Sort the data profiles so the preferred data profile is at the beginning.
        List<DataProfile> allDataProfiles = mAllDataProfiles.stream()
                .sorted(Comparator.comparing((DataProfile dp) -> !dp.equals(mPreferredDataProfile)))
                .collect(Collectors.toList());
        // Search in the order. "IA" type should be the first from getAllowedInitialAttachApnTypes.
        for (int apnType : mDataConfigManager.getAllowedInitialAttachApnTypes()) {
            initialAttachDataProfile = allDataProfiles.stream()
                    .filter(dp -> dp.canSatisfy(DataUtils.apnTypeToNetworkCapability(apnType)))
                    .findFirst()
                    .orElse(null);
            if (initialAttachDataProfile != null) break;
        }

        if (!Objects.equals(mInitialAttachDataProfile, initialAttachDataProfile)) {
+20 −8
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.os.Looper;
import android.provider.Telephony;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataProfile;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
@@ -370,6 +371,8 @@ public class DataProfileManagerTest extends TelephonyTest {
                Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);

        doReturn(true).when(mDataConfigManager).isConfigCarrierSpecific();
        doReturn(List.of(ApnSetting.TYPE_IA, ApnSetting.TYPE_DEFAULT))
                .when(mDataConfigManager).getAllowedInitialAttachApnTypes();
        doAnswer(invocation -> {
            ((Runnable) invocation.getArguments()[0]).run();
            return null;
@@ -528,14 +531,13 @@ public class DataProfileManagerTest extends TelephonyTest {

    @Test
    public void testSetInitialAttachDataProfile() {
        verify(mMockedWwanDataServiceManager).setInitialAttachApn(any(DataProfile.class),
                eq(false), eq(null));
        ArgumentCaptor<DataProfile> dataProfileCaptor =
                ArgumentCaptor.forClass(DataProfile.class);

        List<DataProfile> dataProfiles = mDataProfileManagerUT
                .getDataProfilesForNetworkCapabilities(
                        new int[]{NetworkCapabilities.NET_CAPABILITY_IA});
        assertThat(dataProfiles).hasSize(1);
        assertThat(dataProfiles.get(0).getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
        verify(mMockedWwanDataServiceManager).setInitialAttachApn(dataProfileCaptor.capture(),
                eq(false), eq(null));
        assertThat(dataProfileCaptor.getValue().getApnSetting().getApnName())
                .isEqualTo(GENERAL_PURPOSE_APN);
    }

    @Test
@@ -569,14 +571,24 @@ public class DataProfileManagerTest extends TelephonyTest {
        testSimRemoval();
        Mockito.clearInvocations(mDataProfileManagerCallback);
        Mockito.clearInvocations(mMockedWwanDataServiceManager);

        doReturn(List.of(ApnSetting.TYPE_IMS))
                .when(mDataConfigManager).getAllowedInitialAttachApnTypes();

        mSimInserted = true;
        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
        processAllMessages();

        ArgumentCaptor<DataProfile> dataProfileCaptor =
                ArgumentCaptor.forClass(DataProfile.class);

        verify(mDataProfileManagerCallback).onDataProfilesChanged();
        verify(mMockedWwanDataServiceManager).setInitialAttachApn(any(DataProfile.class),
        verify(mMockedWwanDataServiceManager).setInitialAttachApn(dataProfileCaptor.capture(),
                eq(false), eq(null));

        // Should only use IMS APN for initial attach
        assertThat(dataProfileCaptor.getValue().getApnSetting().getApnName()).isEqualTo(IMS_APN);

        List<DataProfile> dataProfiles = mDataProfileManagerUT
                .getDataProfilesForNetworkCapabilities(
                        new int[]{NetworkCapabilities.NET_CAPABILITY_IMS});