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

Commit 7b13ef1d authored by Pengquan Meng's avatar Pengquan Meng
Browse files

Remove SPN & display condition override from IccRecord

IccRecord should keep the raw data of EF_SPN & its display condition.
This changed move the brandOverride & carrier config override from
IccRecord to ServiceStateTracker.

IccRecord.getServiceProviderName() will keep the raw data which come
from sim.

ServiceStateTracker.getServiceProviderName() fetch the SPN from various
source and return the one has highest priority.

Bug: 122921456
Test: atest ServiceStateTrackerTest
Change-Id: I1a036a9e446c3741e397d2aeb387ec33fee3bd95
parent 388a8015
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -3661,15 +3661,11 @@ public class GsmCdmaPhone extends Phone {

        // Refresh.
        if (status) {
            IccRecords iccRecords = mIccRecords.get();
            if (iccRecords != null) {
            TelephonyManager.from(mContext).setSimOperatorNameForPhone(
                        getPhoneId(), iccRecords.getServiceProviderName());
            }
            if (mSST != null) {
                    getPhoneId(), mSST.getServiceProviderName());
            // TODO: check if pollState is need when set operator brand override.
            mSST.pollState();
        }
        }
        return status;
    }

+112 −9
Original line number Diff line number Diff line
@@ -20,8 +20,11 @@ import static android.provider.Telephony.ServiceStateTable.getContentValuesForSe
import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionId;

import static com.android.internal.telephony.CarrierActionAgent.CARRIER_ACTION_SET_RADIO_ENABLED;
import static com.android.internal.telephony.uicc.IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN;
import static com.android.internal.telephony.uicc.IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN;

import android.Manifest.permission;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.app.AlarmManager;
@@ -96,16 +99,18 @@ import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
import com.android.internal.telephony.uicc.IccCardStatus.CardState;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.RuimRecords;
import com.android.internal.telephony.uicc.SIMRecords;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.util.NotificationChannelController;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
@@ -267,6 +272,19 @@ public class ServiceStateTracker extends Handler {
    protected static final int EVENT_CELL_LOCATION_RESPONSE            = 56;
    protected static final int EVENT_CARRIER_CONFIG_CHANGED            = 57;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"CARRIER_NAME_DISPLAY_BITMASK"},
            value = {CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN,
                    CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN},
            flag = true)
    public @interface CarrierNameDisplayBitmask {}

    // Show SPN only and only if this bit is set.
    public static final int CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN = 1 << 0;

    // Show PLMN only and only if this bit is set.
    public static final int CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN = 1 << 1;

    private List<Message> mPendingCellInfoRequests = new LinkedList<Message>();
    // @GuardedBy("mPendingCellInfoRequests")
    private boolean mIsPendingCellInfoRequest = false;
@@ -2550,7 +2568,7 @@ public class ServiceStateTracker extends Handler {
            IccRecords iccRecords = mIccRecords;
            String plmn = null;
            boolean showPlmn = false;
            int rule = (iccRecords != null) ? iccRecords.getDisplayRule(mSS) : 0;
            int rule = getCarrierNameDisplayBitmask(mSS);
            boolean noService = false;
            if (combinedRegState == ServiceState.STATE_OUT_OF_SERVICE
                    || combinedRegState == ServiceState.STATE_EMERGENCY_ONLY) {
@@ -2576,8 +2594,8 @@ public class ServiceStateTracker extends Handler {
                // In either home or roaming service
                plmn = mSS.getOperatorAlpha();
                showPlmn = !TextUtils.isEmpty(plmn) &&
                        ((rule & SIMRecords.SPN_RULE_SHOW_PLMN)
                                == SIMRecords.SPN_RULE_SHOW_PLMN);
                        ((rule & CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN)
                                == CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN);
            } else {
                // Power off state, such as airplane mode, show plmn as "No service"
                showPlmn = true;
@@ -2591,11 +2609,11 @@ public class ServiceStateTracker extends Handler {
            //    EXTRA_SHOW_SPN = depending on IccRecords rule and radio/IMS state
            //    EXTRA_SPN = spn
            //    EXTRA_DATA_SPN = dataSpn
            String spn = (iccRecords != null) ? iccRecords.getServiceProviderName() : "";
            String spn = getServiceProviderName();
            String dataSpn = spn;
            boolean showSpn = !noService && !TextUtils.isEmpty(spn)
                    && ((rule & SIMRecords.SPN_RULE_SHOW_SPN)
                    == SIMRecords.SPN_RULE_SHOW_SPN);
                    && ((rule & CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN)
                    == CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN);

            if (!TextUtils.isEmpty(spn) && !TextUtils.isEmpty(wfcVoiceSpnFormat) &&
                    !TextUtils.isEmpty(wfcDataSpnFormat)) {
@@ -3413,7 +3431,7 @@ public class ServiceStateTracker extends Handler {
                if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
                    eriText = mPhone.getCdmaEriText();
                } else if (mSS.getVoiceRegState() == ServiceState.STATE_POWER_OFF) {
                    eriText = (mIccRecords != null) ? mIccRecords.getServiceProviderName() : null;
                    eriText = getServiceProviderName();
                    if (TextUtils.isEmpty(eriText)) {
                        // Sets operator alpha property by retrieving from
                        // build-time system property
@@ -3441,12 +3459,97 @@ public class ServiceStateTracker extends Handler {
                if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF)
                        && isInHomeSidNid(mSS.getCdmaSystemId(), mSS.getCdmaNetworkId())
                        && mIccRecords != null) {
                    mSS.setOperatorAlphaLong(mIccRecords.getServiceProviderName());
                    mSS.setOperatorAlphaLong(getServiceProviderName());
                }
            }
        }
    }

    /**
     * Get the service provider name with highest priority among various source.
     * @return service provider name.
     */
    public String getServiceProviderName() {
        // BrandOverride has higher priority than the carrier config
        String operatorBrandOverride = getOperatorBrandOverride();
        if (!TextUtils.isEmpty(operatorBrandOverride)) {
            return operatorBrandOverride;
        }

        PersistableBundle config = getCarrierConfig();
        if (config != null && config.getBoolean(
                CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false)) {
            return config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
        }

        return mIccRecords != null ? mIccRecords.getServiceProviderName() : "";
    }

    /**
     * Get the resolved carrier name display condition bitmask.
     *
     * <p> Show service provider name if only if {@link #CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN}
     * is set.
     *
     * <p> Show PLMN network name if only if {@link #CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN} is set.
     *
     * @param ss service state
     * @return carrier name display bitmask.
     */
    @CarrierNameDisplayBitmask
    public int getCarrierNameDisplayBitmask(ServiceState ss) {
        PersistableBundle config = getCarrierConfig();
        if (!TextUtils.isEmpty(getOperatorBrandOverride())) {
            // If the operator has been overridden, all PLMNs will be considered HOME PLMNs, only
            // show SPN.
            return CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN;
        } else {
            boolean useRoamingFromServiceState = config != null && config.getBoolean(
                    CarrierConfigManager.KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL);
            int carrierDisplayNameConditionFromSim =
                    mIccRecords == null ? 0 : mIccRecords.getCarrierNameDisplayCondition();

            boolean isRoaming;
            if (useRoamingFromServiceState) {
                isRoaming = ss.getRoaming();
            } else {
                String[] hplmns = mIccRecords != null ? mIccRecords.getHomePlmns() : null;
                isRoaming = ArrayUtils.contains(hplmns, ss.getOperatorNumeric());
            }
            int rule;
            if (isRoaming) {
                // Show PLMN when roaming.
                rule = CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN;

                // Check if show SPN is required when roaming.
                if ((carrierDisplayNameConditionFromSim
                        & CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN)
                        == CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN) {
                    rule |= CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN;
                }
            } else {
                // Show SPN when not roaming.
                rule = CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN;

                // Check if show PLMN is required when not roaming.
                if ((carrierDisplayNameConditionFromSim
                        & CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN)
                        == CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN) {
                    rule |= CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN;
                }
            }
            return rule;
        }
    }

    private String getOperatorBrandOverride() {
        UiccCard card = mPhone.getUiccCard();
        if (card == null) return null;
        UiccProfile profile = card.getUiccProfile();
        if (profile == null) return null;
        return profile.getOperatorBrandOverride();
    }

    /**
     * Check whether the specified SID and NID pair appears in the HOME SID/NID list
     * read from NV or SIM.
+1 −1
Original line number Diff line number Diff line
@@ -441,7 +441,7 @@ public class SubscriptionInfoUpdater extends Handler {
                }

                String[] ehplmns = records.getEhplmns();
                String[] hplmns = records.getHplmns();
                String[] hplmns = records.getPlmnsFromHplmnActRecord();
                if (ehplmns != null || hplmns != null) {
                    SubscriptionController.getInstance().setAssociatedPlmns(ehplmns, hplmns, subId);
                }
+76 −38
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.telephony.uicc;

import android.annotation.IntDef;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.AsyncResult;
@@ -24,17 +25,19 @@ import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.MccTable;
import com.android.internal.util.ArrayUtils;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Objects;
@@ -155,6 +158,10 @@ public abstract class IccRecords extends Handler implements IccConstants {
    protected PlmnActRecord[] mOplmnActRecords;
    protected PlmnActRecord[] mPlmnActRecords;

    // A list of PLMN in which the SPN shall be displayed.
    // Reference: 3GPP TS 31.102 Section 4.2.66
    protected String[] mSpdi;

    protected String[] mEhplmns;
    protected String[] mFplmns;

@@ -176,9 +183,20 @@ public abstract class IccRecords extends Handler implements IccConstants {
    protected static final int UNINITIALIZED = -1;
    protected static final int UNKNOWN = 0;

    // Bitmasks for SPN display rules.
    public static final int SPN_RULE_SHOW_SPN  = 0x01;
    public static final int SPN_RULE_SHOW_PLMN = 0x02;
    // Bitmask for carrier name display condition.
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"CARRIER_NAME_DISPLAY_CONDITION_BITMASK_"},
            value = {CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN,
                    CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN},
            flag = true)
    public @interface CarrierNameDisplayConditionBitmask {}
    public static final int CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN = 1;
    public static final int CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN = 2;

    // Display both SPN & PLMN regardless the roaming state.
    public static final int DEFAULT_CARRIER_NAME_DISPLAY_CONDITION =
            CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN
                    | CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN;

    // ***** Event Constants
    public static final int EVENT_MWI = 0; // Message Waiting indication
@@ -665,28 +683,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
        if (mCarrierTestOverride.isInTestMode() && mCarrierTestOverride.getFakeSpn() != null) {
            return mCarrierTestOverride.getFakeSpn();
        }
        String providerName = mSpn;

        // Check for null pointers, mParentApp can be null after dispose,
        // which did occur after removing a SIM.
        UiccCardApplication parentApp = mParentApp;
        if (parentApp != null) {
            UiccProfile profile = parentApp.getUiccProfile();
            if (profile != null) {
                String brandOverride = profile.getOperatorBrandOverride();
                if (brandOverride != null) {
                    log("getServiceProviderName: override, providerName=" + providerName);
                    providerName = brandOverride;
                } else {
                    log("getServiceProviderName: no brandOverride, providerName=" + providerName);
                }
            } else {
                log("getServiceProviderName: card is null, providerName=" + providerName);
            }
        } else {
            log("getServiceProviderName: mParentApp is null, providerName=" + providerName);
        }
        return providerName;
        return mSpn;
    }

    protected void setServiceProviderName(String spn) {
@@ -899,20 +896,61 @@ public abstract class IccRecords extends Handler implements IccConstants {
    protected abstract void onAllRecordsLoaded();

    /**
     * Returns the SpnDisplayRule based on settings on the SIM and the
     * current service state. See TS 22.101 Annex A and TS 51.011 10.3.11
     * for details.
     * Retrieves the SPN/PLMN display condition from UICC.
     *
     * If the SPN is not found on the SIM, the rule is always PLMN_ONLY.
     * Generally used for GSM/UMTS and the like SIMs.
     * Display of service provider name is required when registered PLMN is neither HPLMN nor a PLMN
     * in the service provider PLMN list(EF_SPDI).
     *
     * Display of PLMN network name is required when registered PLMN is either HPLMN or a PLMN in
     * the service provider PLMN list(EF_SPDI).
     *
     * Reference: 3GPP TS 131.102 section 4.2.12 EF_SPN Display Condition
     *
     * @return a bitmask represent the carrier name display condition.
     */
    @CarrierNameDisplayConditionBitmask
    public abstract int getCarrierNameDisplayCondition();

    /**
     * Retrieves the service provider display information. This is a list of PLMNs in which the
     * service provider name shall be displayed.
     *
     * Reference: 3GPP TS 131.102 section 4.2.66 EF_SPDI
     *
     * @return a list of PLMN(mcc+mnc) if EF_SPDI is existed, otherwise return null.
     */
    public String[] getServiceProviderDisplayInformation() {
        return mSpdi;
    }

    /**
     * Get home PLMN list.
     *
     * @param serviceState Service state
     * @return the display rule
     * @see #getEhplmns()
     * @see #getServiceProviderDisplayInformation()
     *
     * @see #SPN_RULE_SHOW_SPN
     * @see #SPN_RULE_SHOW_PLMN
     * @return a list of HPLMN if existed, otherwise return null.
     */
    public abstract int getDisplayRule(ServiceState serviceState);
    public String[] getHomePlmns() {
        // hplmn from imsi.
        String hplmn = getOperatorNumeric();

        // hplmn from ehplmn list.
        String[] hplmns = getEhplmns();

        // plmn from ef_spdi.
        String[] spdi = getServiceProviderDisplayInformation();

        // Use the plmn from imsi as the hplmn if Ehplmn not present.
        if (ArrayUtils.isEmpty(hplmns)) {
            hplmns = new String[] {hplmn};
        }

        if (!ArrayUtils.isEmpty(spdi)) {
            hplmns = ArrayUtils.concatElements(String.class, hplmns, spdi);
        }
        return hplmns;
    }

    /**
     * Return true if "Restriction of menu options for manual PLMN selection"
@@ -996,9 +1034,9 @@ public abstract class IccRecords extends Handler implements IccConstants {
    }

    /**
     * @return String array containing HPLMNs associated with the card.
     * @return String array containing PLMN from HplmnActRecord.
     */
    public String[] getHplmns() {
    public String[] getPlmnsFromHplmnActRecord() {
        if (mHplmnActRecords == null) return null;
        String[] hplmns = new String[mHplmnActRecords.length];
        for (int i = 0; i < mHplmnActRecords.length; i++) {
+2 −4
Original line number Diff line number Diff line
@@ -22,11 +22,9 @@ import android.content.Intent;
import android.os.AsyncResult;
import android.os.Message;
import android.telephony.Rlog;
import android.telephony.ServiceState;

import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.gsm.SimTlv;
//import com.android.internal.telephony.gsm.VoiceMailConstants;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -415,8 +413,8 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
    }

    @Override
    public int getDisplayRule(ServiceState serviceState) {
        // Not applicable to Isim
    public int getCarrierNameDisplayCondition() {
        // No display rule in Isim, return 0.
        return 0;
    }

Loading