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

Commit 5a2e8293 authored by Nathan Harold's avatar Nathan Harold
Browse files

Update the usage setting in SubInfoUpdater

Update the usage setting in the subscription DB
based on the carrier config and the device capability.

Bug: 210023167
Test: atest SubscriptionInfoUpdaterTest#testCalculateUsageSetting
Change-Id: I2f6ff8b1dc6de28ae123a8f636ffd70464fd4196
parent 4ff0aa6a
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.AsyncResult;
import android.os.Build;
import android.os.Handler;
@@ -44,6 +45,7 @@ import android.service.euicc.GetEuiccProfileInfoListResult;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.UsageSetting;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager.SimState;
import android.telephony.UiccAccessRule;
@@ -629,6 +631,62 @@ public class SubscriptionInfoUpdater extends Handler {
        updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED);
    }

    /**
     * Calculate the usage setting based on the carrier request.
     *
     * @param currentUsageSetting the current setting in the subscription DB
     * @param preferredUsageSetting provided by the carrier config
     * @return the calculated usage setting.
     */
    @VisibleForTesting
    @UsageSetting public int calculateUsageSetting(
            @UsageSetting int currentUsageSetting, @UsageSetting int preferredUsageSetting) {
        int defaultUsageSetting;
        int[] supportedUsageSettings;

        //  Load the resources to provide the device capability
        try {
            defaultUsageSetting = sContext.getResources().getInteger(
                com.android.internal.R.integer.config_default_cellular_usage_setting);
            supportedUsageSettings = sContext.getResources().getIntArray(
                com.android.internal.R.array.config_supported_cellular_usage_settings);
            // If usage settings are not supported, return the default setting, which is UNKNOWN.
            if (supportedUsageSettings == null
                    || supportedUsageSettings.length < 1) return currentUsageSetting;
        } catch (Resources.NotFoundException nfe) {
            loge("Failed to load usage setting resources!");
            return currentUsageSetting;
        }

        // If the current setting is invalid, including the first time the value is set,
        // update it to default (this will trigger a change in the DB).
        if (currentUsageSetting < SubscriptionManager.USAGE_SETTING_DEFAULT
                || currentUsageSetting > SubscriptionManager.USAGE_SETTING_DATA_CENTRIC) {
            logd("Updating usage setting for current subscription");
            currentUsageSetting = SubscriptionManager.USAGE_SETTING_DEFAULT;
        }

        // Range check the inputs, and on failure, make no changes
        if (preferredUsageSetting < SubscriptionManager.USAGE_SETTING_DEFAULT
                || preferredUsageSetting > SubscriptionManager.USAGE_SETTING_DATA_CENTRIC) {
            loge("Invalid usage setting!" + preferredUsageSetting);
            return currentUsageSetting;
        }

        // Default is always allowed
        if (preferredUsageSetting == SubscriptionManager.USAGE_SETTING_DEFAULT) {
            return preferredUsageSetting;
        }

        // Forced setting must be explicitly supported
        for (int i = 0; i < supportedUsageSettings.length; i++) {
            if (preferredUsageSetting == supportedUsageSettings[i]) return preferredUsageSetting;
        }

        // If the preferred setting is not possible, just keep the current setting.
        return currentUsageSetting;
    }

    private void restoreSimSpecificSettingsForPhone(int phoneId) {
        SubscriptionManager subManager = SubscriptionManager.from(sContext);
        subManager.restoreSimSpecificSettingsForIccIdFromBackup(sIccId[phoneId]);
@@ -1166,6 +1224,33 @@ public class SubscriptionInfoUpdater extends Handler {
                }
            }
        }

        final int preferredUsageSetting =
                config.getInt(
                        CarrierConfigManager.KEY_CELLULAR_USAGE_SETTING_INT,
                        SubscriptionManager.USAGE_SETTING_UNKNOWN);

        @UsageSetting int newUsageSetting = calculateUsageSetting(
                currentSubInfo.getUsageSetting(),
                preferredUsageSetting);

        if (newUsageSetting != currentSubInfo.getUsageSetting()) {
            cv.put(SubscriptionManager.USAGE_SETTING, newUsageSetting);
            if (DBG) {
                logd("UsageSetting changed,"
                        + " oldSetting=" + currentSubInfo.getUsageSetting()
                        + " preferredSetting=" + preferredUsageSetting
                        + " newSetting=" + newUsageSetting);
            }
        } else {
            if (DBG) {
                logd("UsageSetting unchanged,"
                        + " oldSetting=" + currentSubInfo.getUsageSetting()
                        + " preferredSetting=" + preferredUsageSetting
                        + " newSetting=" + newUsageSetting);
            }
        }

        if (cv.size() > 0 && sContext.getContentResolver().update(SubscriptionManager
                    .getUriForSubscriptionId(currentSubId), cv, null, null) > 0) {
            mSubscriptionController.refreshCachedActiveSubscriptionInfoList();
+129 −0
Original line number Diff line number Diff line
@@ -859,6 +859,103 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        assertEquals(3, cvCaptor.getValue().size());
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigPreferredUsageSettingDataCentric() throws Exception {
        testUpdateFromCarrierConfigPreferredUsageSetting(
                SubscriptionManager.USAGE_SETTING_UNKNOWN,
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigPreferredUsageSettingDataCentric2() throws Exception {
        testUpdateFromCarrierConfigPreferredUsageSetting(
                SubscriptionManager.USAGE_SETTING_DEFAULT,
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigPreferredUsageSettingDefault() throws Exception {
        testUpdateFromCarrierConfigPreferredUsageSetting(
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
                SubscriptionManager.USAGE_SETTING_DEFAULT,
                SubscriptionManager.USAGE_SETTING_DEFAULT);
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigPreferredUsageSettingNoChange() throws Exception {
        testUpdateFromCarrierConfigPreferredUsageSetting(
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigPreferredUsageSettingInvalid() throws Exception {
        testUpdateFromCarrierConfigPreferredUsageSetting(
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
                SubscriptionManager.USAGE_SETTING_UNKNOWN,
                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
    }

    private PersistableBundle getCarrierConfigForSubInfoUpdateUsageSetting(
            @SubscriptionManager.UsageSetting int usageSetting) {
        PersistableBundle p = new PersistableBundle();
        p.putString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, "");
        p.putBoolean(CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, false);
        p.putInt(CarrierConfigManager.KEY_CELLULAR_USAGE_SETTING_INT, usageSetting);
        return p;
    }

    private void testUpdateFromCarrierConfigPreferredUsageSetting(
            int initialSetting, int requestedSetting, int expectedSetting) throws Exception {
        final String carrierPackageName = "FakeCarrierPackageName";
        final int phoneId = mPhone.getPhoneId();

        // Install fixtures, ensure the test will hit the right code path
        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
        ((MockContentResolver) mContext.getContentResolver()).addProvider(
                SubscriptionManager.CONTENT_URI.getAuthority(),
                new FakeSubscriptionContentProvider());

        // Setup overlay
        setupUsageSettingResources();

        // Setup subscription
        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
        doReturn(null).when(mSubInfo).getGroupUuid();
        doReturn(false).when(mSubInfo).isOpportunistic();
        doReturn(initialSetting).when(mSubInfo).getUsageSetting();

        // Get a config bundle for that prefers data centric
        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdateUsageSetting(
                requestedSetting);

        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
                carrierPackageName, carrierConfig);

        ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class);
        verify(mContentProvider, times(1)).update(
                eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)),
                cvCaptor.capture(), eq(null), eq(null));

        if (initialSetting != expectedSetting) {
            assertEquals(expectedSetting,
                    (int) cvCaptor.getValue().getAsInteger(SubscriptionManager.USAGE_SETTING));
        } else {
            // If the content value was not set, the captor value will be null
            assertNull(cvCaptor.getValue().getAsInteger(SubscriptionManager.USAGE_SETTING));
        }
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigCarrierCertificates() {
@@ -942,4 +1039,36 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
                eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
    }

    private void setupUsageSettingResources() {
        // The most common case, request a voice-centric->data-centric change
        mContextFixture.putIntResource(
                com.android.internal.R.integer.config_default_cellular_usage_setting,
                SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC);
        mContextFixture.putIntArrayResource(
                com.android.internal.R.array.config_supported_cellular_usage_settings,
                new int[]{
                        SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
                        SubscriptionManager.USAGE_SETTING_DATA_CENTRIC});
    }

    @Test
    @SmallTest
    public void testCalculateUsageSetting() throws Exception {
        setupUsageSettingResources();
        assertEquals(SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
                mUpdater.calculateUsageSetting(
                    SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
                    SubscriptionManager.USAGE_SETTING_DATA_CENTRIC));

        // Test that a voice-centric-only device only allows voice-centric configuration
        mContextFixture.putIntArrayResource(
                com.android.internal.R.array.config_supported_cellular_usage_settings,
                new int[]{SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC});

        assertEquals(SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
                mUpdater.calculateUsageSetting(
                    SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
                    SubscriptionManager.USAGE_SETTING_DATA_CENTRIC));
    }
}