【日志分析】CarrierConfig 加载流程和配置覆盖问题(以SPN为例)

问题

有的MVNO卡没有配置过 CarrierConfig及相关 overlay,但是实际运行的时候功能被override了 ,此时可能是因为CarrierConfig用了父类(同MCCMNC等情况)的配置,因此在直接查找对应卡cid或mccmnc+mvno属性时候的CarrierConfig是没办法找到影响功能的配置项的。

代码逻辑 

fw/opt/telephony

frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java

AOSP源码getServiceProviderName接口,从CarrierConfig中读取配置是否覆写运营商名称,两个KEY共同控制

  • KEY_CARRIER_NAME_OVERRIDE_BOOL
  • KEY_CARRIER_NAME_STRING
//Android S version example
//frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java
    /**
     * 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;
        }

        String carrierName = mIccRecords != null ? mIccRecords.getServiceProviderName() : "";
        PersistableBundle config = getCarrierConfig();
        if (config.getBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL)
                || TextUtils.isEmpty(carrierName)) {
            return config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
        }

        return carrierName;
    }

CarrierConfig APP 

packages/apps/CarrierConfig/src/com/android/carrierconfig/

DefaultCarrierConfigService.java 中通过loadConfig接口加载出对应卡的配置

  • loadConfig -> readConfigFromXml

加载先后,越后加载的会覆盖前面的

  1. id.getSpecificCarrierId()
  2. id.getCarrierId()
  3. mccmncCarrierId

※然后会有优先级加载配置,所以会

public class DefaultCarrierConfigService extends CarrierService {

    private static final String CARRIER_ID_PREFIX = "carrier_config_carrierid_";
    private static final String MCCMNC_PREFIX = "carrier_config_mccmnc_";
    private static final String NO_SIM_CONFIG_FILE_NAME = "carrier_config_no_sim.xml";//无卡配置的文件名

    private XmlPullParserFactory mFactory;

    public DefaultCarrierConfigService() {
        Log.d(TAG, "Service created");
        mFactory = null;
    }

    PersistableBundle loadConfig(XmlPullParser parser, @Nullable CarrierIdentifier id) {
        PersistableBundle config = new PersistableBundle();
        // OEM customizable filter for carrier requirements not related to hardware/vendor SKU.
        String sku = getApplicationContext().getResources().getString(R.string.sku_filter);

        if (id == null) {
            try {
                // Load no SIM config if carrier id is not set.
                parser.setInput(getApplicationContext().getAssets().open(
                        NO_SIM_CONFIG_FILE_NAME), "utf-8");
                config = readConfigFromXml(parser, null, sku);

                // Treat vendor_no_sim.xml as if it were appended to the no sim config file.
                XmlPullParser vendorInput =
                        getApplicationContext().getResources().getXml(R.xml.vendor_no_sim);
                PersistableBundle vendorConfig = readConfigFromXml(vendorInput, null, sku);
                config.putAll(vendorConfig);
            }
            catch (IOException|XmlPullParserException e) {
                Log.e(TAG, "Failed to load config for no SIM", e);
            }

            return config;
        }

        try {
            if (id.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID) {
                PersistableBundle configByCarrierId = new PersistableBundle();
                PersistableBundle configBySpecificCarrierId = new PersistableBundle();
                PersistableBundle configByMccMncFallBackCarrierId = new PersistableBundle();
                TelephonyManager telephonyManager = getApplicationContext()
                        .getSystemService(TelephonyManager.class);
                int mccmncCarrierId = telephonyManager
                        .getCarrierIdFromMccMnc(id.getMcc() + id.getMnc());
                for (String file : getApplicationContext().getAssets().list("")) {
                    if (file.startsWith(CARRIER_ID_PREFIX + id.getSpecificCarrierId() + "_")) {
                        parser.setInput(getApplicationContext().getAssets().open(file), "utf-8");
                        configBySpecificCarrierId = readConfigFromXml(parser, null, sku);
                        break;
                    } else if (file.startsWith(CARRIER_ID_PREFIX + id.getCarrierId() + "_")) {
                        parser.setInput(getApplicationContext().getAssets().open(file), "utf-8");
                        configByCarrierId = readConfigFromXml(parser, null, sku);
                    } else if (file.startsWith(CARRIER_ID_PREFIX + mccmncCarrierId + "_")) {
                        parser.setInput(getApplicationContext().getAssets().open(file), "utf-8");
                        configByMccMncFallBackCarrierId = readConfigFromXml(parser, null, sku);
                    }
                }

                // priority: specific carrier id > carrier id > mccmnc fallback carrier id
                if (!configBySpecificCarrierId.isEmpty()) {
                    config = configBySpecificCarrierId;
                } else if (!configByCarrierId.isEmpty()) {
                    config = configByCarrierId;
                } else if (!configByMccMncFallBackCarrierId.isEmpty()) {
                    config = configByMccMncFallBackCarrierId;
                }
            }
            if (config.isEmpty()) {
                // fallback to use mccmnc.xml when there is no carrier id named config found.
                parser.setInput(getApplicationContext().getAssets().open(
                        MCCMNC_PREFIX + id.getMcc() + id.getMnc() + ".xml"), "utf-8");
                config = readConfigFromXml(parser, id, sku);
            }
        }
        catch (IOException | XmlPullParserException e) {
            Log.d(TAG, e.toString());
            // We can return an empty config for unknown networks.
            config = new PersistableBundle();
        }

        // Treat vendor.xml as if it were appended to the carrier config file we read.
        XmlPullParser vendorInput = getApplicationContext().getResources().getXml(R.xml.vendor);
        try {
            PersistableBundle vendorConfig = readConfigFromXml(vendorInput, id, sku);
     
  • 29
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值