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

Commit ae079e69 authored by Zoey Chen's avatar Zoey Chen
Browse files

[Telephony] Fix the display name cannot be updated after OTA

- After OTA, if the priority of the name source is lower,
    the displayName cannot be updated.
- If the carrier would like to display name from PNN but the value of carrier config
    is removed in the next version, the display name cannot be updated correctly since
    the priority is lower than carrier config.

Bug: 159232126
Test: Manual and atest
Change-Id: Ia1824a684af388682718263fc6154b4f5fb27b33
parent a18296c9
Loading
Loading
Loading
Loading
+72 −5
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
import android.os.RegistrantList;
import android.os.RemoteException;
import android.os.TelephonyServiceManager.ServiceRegisterer;
@@ -69,6 +70,7 @@ import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;
import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.telephony.util.TelephonyUtils;
@@ -1796,6 +1798,66 @@ public class SubscriptionController extends ISub.Stub {
        return (index < 0) ? 0 : index;
    }

    /**
     * Validate whether the NAME_SOURCE_SIM_PNN, NAME_SOURCE_SIM_SPN and
     * NAME_SOURCE_CARRIER exist or not.
     */
    @VisibleForTesting
    public boolean isExistingNameSourceStillValid(SubscriptionInfo subInfo) {

        int subId = subInfo.getSubscriptionId();
        int phoneId = getPhoneId(subInfo.getSubscriptionId());

        Phone phone = PhoneFactory.getPhone(phoneId);
        if (phone == null) {
            return true;
        }

        String spn;

        switch (subInfo.getNameSource()) {
            case SubscriptionManager.NAME_SOURCE_SIM_PNN:
                String pnn = phone.getPlmn();
                return !TextUtils.isEmpty(pnn);
            case SubscriptionManager.NAME_SOURCE_SIM_SPN:
                spn = getServiceProviderName(phoneId);
                return !TextUtils.isEmpty(spn);
            case SubscriptionManager.NAME_SOURCE_CARRIER:
                // Can not validate eSIM since it should not override with a lower priority source
                // if the name is actually coming from eSIM and not from carrier config.
                if (subInfo.isEmbedded()) {
                    return true;
                }
                CarrierConfigManager configLoader =
                        mContext.getSystemService(CarrierConfigManager.class);
                PersistableBundle config =
                        configLoader.getConfigForSubId(subId);
                if (config == null) {
                    return true;
                }
                boolean isCarrierNameOverride = config.getBoolean(
                        CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
                String carrierName = config.getString(
                        CarrierConfigManager.KEY_CARRIER_NAME_STRING);
                spn = getServiceProviderName(phoneId);
                return isCarrierNameOverride
                        || (TextUtils.isEmpty(spn) && !TextUtils.isEmpty(carrierName));
            case SubscriptionManager.NAME_SOURCE_CARRIER_ID:
            case SubscriptionManager.NAME_SOURCE_USER_INPUT:
                return true;
        }
        return false;
    }

    @VisibleForTesting
    public String getServiceProviderName(int phoneId) {
        UiccProfile profile = mUiccController.getUiccProfileForPhone(phoneId);
        if (profile == null) {
            return null;
        }
        return profile.getServiceProviderName();
    }

    /**
     * Set display name by simInfo index with name source
     * @param displayName the display name of SIM card
@@ -1821,12 +1883,17 @@ public class SubscriptionController extends ISub.Stub {
            // if there is no sub in the db, return 0 since subId does not exist in db
            if (allSubInfo == null || allSubInfo.isEmpty()) return 0;
            for (SubscriptionInfo subInfo : allSubInfo) {
                int subInfoNameSource = subInfo.getNameSource();
                boolean isHigherPriority = (getNameSourcePriority(subInfoNameSource)
                        > getNameSourcePriority(nameSource));
                boolean isEqualPriorityAndName = (getNameSourcePriority(subInfoNameSource)
                        == getNameSourcePriority(nameSource))
                        && (TextUtils.equals(displayName, subInfo.getDisplayName()));
                if (subInfo.getSubscriptionId() == subId
                        && (getNameSourcePriority(subInfo.getNameSource())
                                > getNameSourcePriority(nameSource)
                        || (displayName != null && displayName.equals(subInfo.getDisplayName())))) {
                    logd("Name source " + subInfo.getNameSource() + "'s priority "
                            + getNameSourcePriority(subInfo.getNameSource()) + " is greater than "
                        && isExistingNameSourceStillValid(subInfo)
                        && (isHigherPriority || isEqualPriorityAndName)) {
                    logd("Name source " + subInfoNameSource + "'s priority "
                            + getNameSourcePriority(subInfoNameSource) + " is greater than "
                            + "name source " + nameSource + "'s priority "
                            + getNameSourcePriority(nameSource) + ", return now.");
                    return 0;
+2 −0
Original line number Diff line number Diff line
@@ -295,6 +295,8 @@ public class ContextFixture implements TestFixture<Context> {
                return Context.ACTIVITY_SERVICE;
            } else if (serviceClass == LocationManager.class) {
                return Context.LOCATION_SERVICE;
            } else if (serviceClass == CarrierConfigManager.class){
                return Context.CARRIER_CONFIG_SERVICE;
            }
            return super.getSystemServiceName(serviceClass);
        }
+250 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.Manifest;
import android.app.AppOpsManager;
@@ -46,8 +47,10 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.UiccSlotInfo;
@@ -76,6 +79,7 @@ import java.util.UUID;
public class SubscriptionControllerTest extends TelephonyTest {
    private static final int SINGLE_SIM = 1;
    private static final int DUAL_SIM = 2;
    private static final int FAKE_SUBID = 123;
    private String mCallingPackage;
    private String mCallingFeature;
    private SubscriptionController mSubscriptionControllerUT;
@@ -91,6 +95,9 @@ public class SubscriptionControllerTest extends TelephonyTest {
    private ISetOpportunisticDataCallback mSetOpptDataCallback;
    @Mock
    private Handler mHandler;
    @Mock
    private SubscriptionInfo mMockSubscriptionInfo;
    private PersistableBundle mCarrierConfigs;

    private static final String MAC_ADDRESS_PREFIX = "mac_";
    private static final String DISPLAY_NAME_PREFIX = "my_phone_";
@@ -98,6 +105,7 @@ public class SubscriptionControllerTest extends TelephonyTest {
    private static final String UNAVAILABLE_ICCID = "";
    private static final String UNAVAILABLE_NUMBER = "";
    private static final String DISPLAY_NUMBER = "123456";
    private static final String DISPLAY_NAME = "testing_display_name";

    @Before
    public void setUp() throws Exception {
@@ -118,6 +126,10 @@ public class SubscriptionControllerTest extends TelephonyTest {
        mCallingFeature = mContext.getAttributionTag();

        doReturn(1).when(mProxyController).getMaxRafSupported();

        // Carrier Config
        mCarrierConfigs = mContextFixture.getCarrierConfigBundle();

        mContextFixture.putIntArrayResource(com.android.internal.R.array.sim_colors, new int[]{5});

        setupMocksForTelephonyPermissions(Build.VERSION_CODES.R);
@@ -244,6 +256,244 @@ public class SubscriptionControllerTest extends TelephonyTest {

    }

    private void setSimEmbedded(boolean isEmbedded) throws Exception {
        ContentValues values = new ContentValues();
        values.put(SubscriptionManager.IS_EMBEDDED, isEmbedded ? 1 : 0);
        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + getFirstSubId(),
                null);
    }

    @Test @SmallTest
    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithEmbeddedSim()
            throws Exception {
        testInsertSim();

        // Set values of DB
        setSimEmbedded(true);
        int subId = getFirstSubId();
        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);

        // Update with new value
        String newDisplayName = "display_name_pnn";
        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_PNN;

        // Save to DB after updated
        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);

        SubscriptionInfo subInfo = mSubscriptionControllerUT
                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);

        assertNotNull(subInfo);
        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
        assertEquals(nameSource, subInfo.getNameSource());
    }

    @Test @SmallTest
    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithConfigIsNull()
            throws Exception {
        testInsertSim();

        // Set values of DB
        setSimEmbedded(false);
        int subId = getFirstSubId();
        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);

        // Update with new value
        String newDisplayName = "display_name_spn";
        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
        when(mCarrierConfigManager.getConfigForSubId(subId)).thenReturn(null);

        // Save to DB after updated
        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);

        SubscriptionInfo subInfo = mSubscriptionControllerUT
                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);

        assertNotNull(subInfo);
        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
        assertEquals(nameSource, subInfo.getNameSource());
    }

    @Test @SmallTest
    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithCarrierNameOverride()
            throws Exception {
        testInsertSim();

        // Set values of DB
        setSimEmbedded(false);
        int subId = getFirstSubId();
        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);

        // Update with new value
        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
        String newDisplayName = "display_name_spn";
        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, true);

        // Save to DB after updated
        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);

        SubscriptionInfo subInfo = mSubscriptionControllerUT
                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);

        assertNotNull(subInfo);
        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
        assertEquals(nameSource, subInfo.getNameSource());
    }

    @Test @SmallTest
    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithSpnAndCarrierName()
            throws Exception {
        testInsertSim();

        // Set values of DB
        setSimEmbedded(false);
        int subId = getFirstSubId();
        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);

        // Update with new value
        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
        String carrierName = "testing_carrier_name";
        String newDisplayName = "display_name_spn";
        when(mUiccController.getUiccProfileForPhone(anyInt())).thenReturn(mUiccProfile);
        when(mUiccProfile.getServiceProviderName()).thenReturn(null);
        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
        mCarrierConfigs.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, carrierName);

        // Save to DB after updated
        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);

        SubscriptionInfo subInfo = mSubscriptionControllerUT
                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);

        assertNotNull(subInfo);
        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
        assertEquals(nameSource, subInfo.getNameSource());
    }

    @Test @SmallTest
    public void testSetGetDisplayNameSrc_updateNameSourcePnnToNameSourceCarrierId()
            throws Exception {
        testInsertSim();

        // Set values of DB
        int subId = getFirstSubId();
        int nameSource = SubscriptionManager.NAME_SOURCE_SIM_PNN;
        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);

        // Update with new value
        String newDisplayName = "display_name_carrier_id";
        int newNameSource = SubscriptionManager.NAME_SOURCE_CARRIER_ID;
        when(mPhone.getPlmn()).thenReturn("testing_pnn");

        // Save to DB after updated
        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);

        SubscriptionInfo subInfo = mSubscriptionControllerUT
                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);

        assertNotNull(subInfo);
        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
        assertEquals(nameSource, subInfo.getNameSource());
    }

    @Test @SmallTest
    public void testSetGetDisplayNameSrc_updateNameSourceUserInputToNameSourceSpn()
            throws Exception {
        testInsertSim();

        // Set values of DB
        int subId = getFirstSubId();
        int nameSource = SubscriptionManager.NAME_SOURCE_USER_INPUT;
        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);

        // Update with new value
        String newDisplayName = "display_name_spn";
        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;

        // Save to DB after updated
        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);

        SubscriptionInfo subInfo = mSubscriptionControllerUT
                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);

        assertNotNull(subInfo);
        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
        assertEquals(nameSource, subInfo.getNameSource());
    }

    @Test @SmallTest
    public void testIsExistingNameSourceStillValid_pnnIsNotNull_returnTrue() {
        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
        when(mMockSubscriptionInfo.getNameSource())
                .thenReturn(SubscriptionManager.NAME_SOURCE_SIM_PNN);
        when(mPhone.getPlmn()).thenReturn("testing_pnn");

        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
    }

    @Test @SmallTest
    public void testIsExistingNameSourceStillValid_spnIsNotNull_returnTrue() {
        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
        when(mMockSubscriptionInfo.getNameSource())
                .thenReturn(SubscriptionManager.NAME_SOURCE_SIM_SPN);
        when(mUiccController.getUiccProfileForPhone(anyInt())).thenReturn(mUiccProfile);
        when(mUiccProfile.getServiceProviderName()).thenReturn("testing_spn");

        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
    }

    @Test @SmallTest
    public void testIsExistingNameSourceStillValid_simIsEmbedded_returnTrue() {
        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(true);
        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
        when(mMockSubscriptionInfo.getNameSource())
                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);

        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
    }

    @Test @SmallTest
    public void testIsExistingNameSourceStillValid_carrierConfigIsNull_returnTrue() {
        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(false);
        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
        when(mMockSubscriptionInfo.getNameSource())
                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);
        when(mCarrierConfigManager.getConfigForSubId(FAKE_SUBID)).thenReturn(null);

        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
    }

    @Test @SmallTest
    public void testIsExistingNameSourceStillValid_carrierNameOverrideIsTrue_returnTrue() {
        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(false);
        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
        when(mMockSubscriptionInfo.getNameSource())
                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);
        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, true);

        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
    }

    @Test @SmallTest
    public void testIsExistingNameSourceStillValid_spnIsNullAndCarrierNameIsNotNull_returnTrue() {
        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(false);
        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
        when(mMockSubscriptionInfo.getNameSource())
                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);
        when(mUiccController.getUiccProfileForPhone(anyInt())).thenReturn(mUiccProfile);
        when(mUiccProfile.getServiceProviderName()).thenReturn(null);
        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
        mCarrierConfigs.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING,
                "testing_carrier_name");

        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
    }

    @Test @SmallTest
    public void testCleanUpSIM() {
        testInsertSim();