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

Commit fab27de6 authored by sangyun's avatar sangyun Committed by Sangyun Yun
Browse files

Cache last internet connected data profile by subscription id.

Even for the same type of sim card,
The preferred internet network may be different even if there are
the same type of sim card. Changed to contains the profile that was
most recently connected to the internet for each subscription id.
To prevent the use of too many subIds, Least Recently Used Cache
was used to store last internet data profile upto 256.

Bug: 332474929
Test: atest DataProfileManagerTest
Test: tested for call and data network while sim swap.
Change-Id: Id183003c74ee1bad091a512f20a371aa46223289
parent f8e30e78
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.LruCache;

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback;
@@ -102,8 +103,9 @@ public class DataProfileManager extends Handler {
    /** The preferred data profile used for internet. */
    private @Nullable DataProfile mPreferredDataProfile = null;

    /** The last data profile that's successful for internet connection. */
    private @Nullable DataProfile mLastInternetDataProfile = null;
    /** The last data profile that's successful for internet connection by subscription id. */
    private @NonNull LruCache<Integer, DataProfile> mLastInternetDataProfiles =
            new LruCache<>(256);

    /** Preferred data profile set id. */
    private int mPreferredDataProfileSetId = Telephony.Carriers.NO_APN_SET_ID;
@@ -452,9 +454,11 @@ public class DataProfileManager extends Handler {
            }
        }

        // Update a working internet data profile as a future candidate for preferred data profile
        // after APNs are reset to default
        mLastInternetDataProfile = defaultProfile;
        // Update a working internet data profile by subid as a future candidate for preferred
        // data profile after APNs are reset to default
        if (defaultProfile != null) {
            mLastInternetDataProfiles.put(mPhone.getSubId(), defaultProfile);
        }

        // If the live default internet network is not using the preferred data profile, since
        // brought up a network means it passed sophisticated checks, update the preferred data
@@ -542,7 +546,8 @@ public class DataProfileManager extends Handler {
     */
    private boolean updatePreferredDataProfile() {
        DataProfile preferredDataProfile;
        if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
        int subId = mPhone.getSubId();
        if (SubscriptionManager.isValidSubscriptionId(subId)) {
            preferredDataProfile = getPreferredDataProfileFromDb();
            if (preferredDataProfile == null) {
                preferredDataProfile = getPreferredDataProfileFromConfig();
@@ -551,7 +556,8 @@ public class DataProfileManager extends Handler {
                    setPreferredDataProfile(preferredDataProfile);
                } else {
                    preferredDataProfile = mAllDataProfiles.stream()
                            .filter(dp -> areDataProfilesSharingApn(dp, mLastInternetDataProfile))
                            .filter(dp -> areDataProfilesSharingApn(dp,
                                    mLastInternetDataProfiles.get(subId)))
                            .findFirst()
                            .orElse(null);
                    if (preferredDataProfile != null) {
@@ -1208,7 +1214,10 @@ public class DataProfileManager extends Handler {
        pw.println("Preferred data profile from db=" + getPreferredDataProfileFromDb());
        pw.println("Preferred data profile from config=" + getPreferredDataProfileFromConfig());
        pw.println("Preferred data profile set id=" + mPreferredDataProfileSetId);
        pw.println("Last internet data profile=" + mLastInternetDataProfile);
        pw.println("Last internet data profile for=");
        pw.increaseIndent();
        mLastInternetDataProfiles.snapshot().forEach((key, value) -> pw.println(key + ":" + value));
        pw.decreaseIndent();
        pw.println("Initial attach data profile=" + mInitialAttachDataProfile);
        pw.println("isTetheringDataProfileExisting=" + isTetheringDataProfileExisting(
                TelephonyManager.NETWORK_TYPE_LTE));
+91 −0
Original line number Diff line number Diff line
@@ -1118,6 +1118,97 @@ public class DataProfileManagerTest extends TelephonyTest {
        assertThat(mDataProfileManagerUT.isDataProfilePreferred(legacyRatDataProfile)).isTrue();
    }

    @Test
    public void testSetPreferredDataProfileBySubscriptionId() {
        // NetworkRequest.
        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        .build(), mPhone, mFeatureFlags);
        // DataNetwork for internet
        DataNetwork internetNetwork = Mockito.mock(DataNetwork.class);

        // Step 1. With sudId 1, connect to internet and set as prefer APN.
        // Test for SubId 1.
        doReturn(1).when(mPhone).getSubId();

        // Sim Loaded and loads profiles.
        changeSimStateTo(TelephonyManager.SIM_STATE_LOADED);
        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
        processAllMessages();

        // Find DataProfile based on network request
        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());

        // Connected to internet. At this time, This test expects that dataProfile is stored in
        // mLastInternetDataProfiles for subid 1.
        doReturn(dataProfile).when(internetNetwork).getDataProfile();
        doReturn(new DataNetworkController.NetworkRequestList(List.of(tnr)))
                .when(internetNetwork).getAttachedNetworkRequestList();
        mDataNetworkControllerCallback.onConnectedInternetDataNetworksChanged(
                Set.of(internetNetwork));
        processAllMessages();

        // After internet connected, preferred APN should be set
        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();


        // Step 2. test prefer apn for subId 2.
        // Test for SubId 2.
        doReturn(2).when(mPhone).getSubId();
        // Sim Loaded and loads profiles.
        changeSimStateTo(TelephonyManager.SIM_STATE_ABSENT);
        changeSimStateTo(TelephonyManager.SIM_STATE_LOADED);
        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
        processAllMessages();

        // Find DataProfile based on network request
        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                tnr, TelephonyManager.NETWORK_TYPE_CDMA, false, false, false);
        assertThat(dataProfile.getApnSetting().getApnName())
                .isEqualTo(GENERAL_PURPOSE_APN_LEGACY_RAT);
        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
        doReturn(dataProfile).when(internetNetwork).getDataProfile();

        // APN reset
        mPreferredApnId = -1;
        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
        processAllMessages();

        // Since a new subid has been loaded, preferred APN should be null regardless of the last
        // internet connection of previous subid.
        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse();


        // Step 3. try again back to subId 1.
        // Test for SubId 1.
        doReturn(1).when(mPhone).getSubId();
        // Sim Loaded and loads profiles.
        changeSimStateTo(TelephonyManager.SIM_STATE_ABSENT);
        changeSimStateTo(TelephonyManager.SIM_STATE_LOADED);
        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
        processAllMessages();

        // Find DataProfile based on network request
        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
        doReturn(dataProfile).when(internetNetwork).getDataProfile();

        // APN reset
        mPreferredApnId = -1;
        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
        processAllMessages();

        // Since the old subid has been loaded, Even if preferapn for subid 1 is not in the db, the
        // preferapn can be loaded by mLastInternetDataProfiles
        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
    }

    @Test
    public void testSetInitialAttachDataProfile() {
        ArgumentCaptor<DataProfile> dataProfileCaptor =