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

Commit fbab4a6d authored by Jack Yu's avatar Jack Yu Committed by Automerger Merge Worker
Browse files

Optimized the boot up camping time am: 39d584c4

parents 4e3dafa8 39d584c4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2306,7 +2306,7 @@ public class DataNetworkController extends Handler {
    /** Called when subscription info changed. */
    private void onSubscriptionChanged() {
        if (mSubId != mPhone.getSubId()) {
            log("onDataConfigUpdated: mSubId changed from " + mSubId + " to "
            log("onSubscriptionChanged: mSubId changed from " + mSubId + " to "
                    + mPhone.getSubId());
            if (isImsGracefulTearDownSupported()) {
                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
+136 −51
Original line number Diff line number Diff line
@@ -19,8 +19,12 @@ package com.android.internal.telephony.data;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.NetworkCapabilities;
@@ -67,6 +71,9 @@ import java.util.stream.Collectors;
public class DataProfileManager extends Handler {
    private static final boolean VDBG = true;

    /** Event for SIM loaded. */
    private static final int EVENT_SIM_LOADED = 1;

    /** Event for APN database changed. */
    private static final int EVENT_APN_DATABASE_CHANGED = 2;

@@ -156,7 +163,60 @@ public class DataProfileManager extends Handler {
        mWwanDataServiceManager = dataServiceManager;
        mDataConfigManager = dataNetworkController.getDataConfigManager();
        mDataProfileManagerCallbacks.add(callback);

        IntentFilter filter = new IntentFilter();
        filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
        mPhone.getContext().registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(
                        TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED)) {
                    if (mPhone.getPhoneId() == intent.getIntExtra(
                            CarrierConfigManager.EXTRA_SLOT_INDEX,
                            SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
                        sendMessageAtFrontOfQueue(obtainMessage(EVENT_SIM_LOADED));
                    }
                }
            }
        }, filter, null, mPhone);

        registerAllEvents();
        log("created.");
    }

    /**
     * Called when SIM loaded.
     */
    private void onSimLoaded() {
        // Below is for boot up camping optimization purpose. We do not need to wait until carrier
        // config ready to load the profiles. Although preferred data profile might be affected by
        // the carrier config, that's only for the first time boot up. In that case, the preferred
        // data profile from the db would be empty, and we can wait until carrier config ready to
        // determine the preferred data profile. By just loading the essential profiles when SIM
        // loaded, the boot up camping time is slightly improved.
        //
        // The default (i.e. framework generated) data profiles for enterprise, emergency, and IMS
        // will also be added at that time if they are missing from all profiles.
        log("onSimLoaded: subId=" + mPhone.getSubId());
        if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
            int preferredProfileId = getPreferredDataProfileIdFromDb();
            if (preferredProfileId < 0) {
                // Preferred data profile does not exist. This might be the first time boot up.
                // Deferred until carrier config loaded so we can determine the correct preferred
                // data profile. It is intended to bail out here. If we load all the data profiles
                // without knowing the preferred data profile, we might end up with setting up
                // with the wrong one.
                log("onSimLoaded: Preferred data profile does not exist.");
                return;
            }
            mPreferredDataProfile = getPreferredDataProfileFromDb();
            mPreferredDataProfileSetId = getPreferredDataProfileSetId();
            log("onSimLoaded: mPreferredDataProfileSetId=" + mPreferredDataProfileSetId);

            mAllDataProfiles.clear();
            mAllDataProfiles.addAll(loadDataProfilesFromDatabase());
            log("onSimLoaded: Loaded " + mAllDataProfiles);
        }
    }

    /**
@@ -191,6 +251,9 @@ public class DataProfileManager extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case EVENT_SIM_LOADED:
                onSimLoaded();
                break;
            case EVENT_SIM_REFRESH:
                log("Update data profiles due to SIM refresh.");
                updateDataProfiles(FORCED_UPDATE_IA);
@@ -245,21 +308,21 @@ public class DataProfileManager extends Handler {
        cursor.close();
        return dataProfile;
    }

    /**
     * Update all data profiles, including preferred data profile, and initial attach data profile.
     * Also send those profiles down to the modem if needed.
     * Load all data profiles associated with the current SIM from the database.
     *
     * @param forceUpdateIa If {@code true}, we should always send IA again to modem.
     * @return The loaded profiles. Empty list if not found.
     */
    private void updateDataProfiles(boolean forceUpdateIa) {
    private @NonNull List<DataProfile> loadDataProfilesFromDatabase() {
        log("loadDataProfilesFromDatabase: subId=" + mPhone.getSubId());
        List<DataProfile> profiles = new ArrayList<>();
        if (mDataConfigManager.isConfigCarrierSpecific()) {
        Cursor cursor = mPhone.getContext().getContentResolver().query(
                Uri.withAppendedPath(Telephony.Carriers.SIM_APN_URI, "filtered/subId/"
                        + mPhone.getSubId()), null, null, null, Telephony.Carriers._ID);
        if (cursor == null) {
            loge("Cannot access APN database through telephony provider.");
                return;
            return new ArrayList<>();
        }
        boolean isInternetSupported = false;
        while (cursor.moveToNext()) {
@@ -287,8 +350,19 @@ public class DataProfileManager extends Handler {
            reportAnomaly("Carrier doesn't support internet.",
                    "9af73e18-b523-4dc5-adab-363eb6613305");
        }

        return profiles;
    }

    /**
     * Update all data profiles, including preferred data profile, and initial attach data profile.
     * Also send those profiles down to the modem if needed.
     *
     * @param forceUpdateIa If {@code true}, we should always send IA again to modem.
     */
    private void updateDataProfiles(boolean forceUpdateIa) {
        List<DataProfile> profiles = loadDataProfilesFromDatabase();

        DataProfile dataProfile;

        if (!profiles.isEmpty()) { // APN database has been read successfully after SIM loaded
@@ -426,28 +500,39 @@ public class DataProfileManager extends Handler {
    }

    /**
     * Get the preferred data profile for internet data.
     *
     * @return The preferred data profile.
     * @return The preferred data profile id. {@code -1} if not found.
     */
    private @Nullable DataProfile getPreferredDataProfileFromDb() {
        Cursor cursor = mPhone.getContext().getContentResolver().query(
    private int getPreferredDataProfileIdFromDb() {
        try (Cursor cursor = mPhone.getContext().getContentResolver().query(
                Uri.withAppendedPath(Telephony.Carriers.PREFERRED_APN_URI,
                        String.valueOf(mPhone.getSubId())), null, null, null,
                Telephony.Carriers.DEFAULT_SORT_ORDER);
        DataProfile dataProfile = null;
                Telephony.Carriers.DEFAULT_SORT_ORDER)) {
            if (cursor != null) {
                if (cursor.getCount() > 0) {
                    cursor.moveToFirst();
                int apnId = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
                dataProfile = mAllDataProfiles.stream()
                    return cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
                }
            }
        }
        return -1;
    }

    /**
     * Get the preferred data profile for internet data.
     *
     * @return The preferred data profile.
     */
    private @Nullable DataProfile getPreferredDataProfileFromDb() {
        int preferredDataProfileId = getPreferredDataProfileIdFromDb();
        if (preferredDataProfileId < 0) {
            log("getPreferredDataProfileFromDb: null");
            return null;
        }
        DataProfile dataProfile = mAllDataProfiles.stream()
                .filter(dp -> dp.getApnSetting() != null
                                && dp.getApnSetting().getId() == apnId)
                        && dp.getApnSetting().getId() == preferredDataProfileId)
                .findFirst()
                .orElse(null);
            }
            cursor.close();
        }
        log("getPreferredDataProfileFromDb: " + dataProfile);
        return dataProfile;
    }
+30 −1
Original line number Diff line number Diff line
@@ -518,7 +518,7 @@ public class DataProfileManagerTest extends TelephonyTest {

        public void setPreferredApn(String apnName) {
            for (Object apnSetting : mAllApnSettings) {
                if (apnName == ((Object[]) apnSetting)[3]) {
                if (Objects.equals(apnName, ((Object[]) apnSetting)[3])) {
                    mPreferredApnId = (int) ((Object[]) apnSetting)[0];
                    mPreferredApnSet = (int) ((Object[]) apnSetting)[28];
                    logd("mPreferredApnId=" + mPreferredApnId + " ,mPreferredApnSet="
@@ -1457,4 +1457,33 @@ public class DataProfileManagerTest extends TelephonyTest {
        assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                TelephonyManager.NETWORK_TYPE_LTE, false)).isNull();
    }

    @Test
    public void testSimLoaded() {
        mDataProfileManagerUT = new DataProfileManager(mPhone, mDataNetworkController,
                mMockedWwanDataServiceManager, Looper.myLooper(), mDataProfileManagerCallback);

        mDataProfileManagerUT.obtainMessage(1 /* EVENT_SIM_LOADED */).sendToTarget();
        processAllMessages();

        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                new TelephonyNetworkRequest(new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        .build(), mPhone),
                TelephonyManager.NETWORK_TYPE_LTE, false);

        // Because preferred APN is not set, SIM load event will not trigger loading data profiles.
        assertThat(dataProfile).isNull();

        mApnSettingContentProvider.setPreferredApn(GENERAL_PURPOSE_APN);
        mDataProfileManagerUT.obtainMessage(1 /* EVENT_SIM_LOADED */).sendToTarget();
        processAllMessages();

        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                new TelephonyNetworkRequest(new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        .build(), mPhone),
                TelephonyManager.NETWORK_TYPE_LTE, false);
        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
    }
}