CarrierConfig 加载流程和配置覆盖问题

news2025/1/12 23:01:14

问题

有的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 = readConfigFromXm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1635526.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

服务器数据恢复—异常断电导致RAID模块故障的数据恢复案例

服务器数据恢复环境: 某品牌ProLiant DL380系列服务器,服务器中有一组由6块SAS硬盘组建的RAID5阵列,WINDOWS SERVER操作系统,作为企业内部文件服务器使用。 服务器故障: 机房供电几次意外中断,服务器出现故…

Socket编程--TCP连接以及并发处理

流程图 网络传输流程: TCP连接: api 客户端: socket: 创建套接字 domain: AF_INET :IPv4 type: SOCK_STREAM(tcp)、SOCK_DGRAM(udp) protocol: 0 默认协议 返回值:成功返回一个新的套接字…

RakSmart站群服务器租用注意事项科普

随着互联网的飞速发展,站群运营成为越来越多企业和个人的选择。而RakSmart作为知名的服务器提供商,其站群服务器租用服务备受关注。在租用RakSmart站群服务器时,源库建议有一些关键的注意事项需要特别留意,以确保服务器的稳定运行…

ThinkPHP5 SQL注入漏洞敏感信息泄露漏洞

1 漏洞介绍 ThinkPHP是在中国使用极为广泛的PHP开发框架。在其版本5.0&#xff08;<5.1.23&#xff09;中,开启debug模式&#xff0c;传入的某参数在绑定编译指令的时候又没有安全处理&#xff0c;预编译的时候导致SQL异常报错。然而thinkphp5默认开启debug模式&#xff0c…

【代码问题】【Pytorch】训练模型时Loss为NaN或INF

解决方法或者问题排查&#xff1a; 加归一化层&#xff1a; 我的问题是我新增的一个模块与原来的模块得到的张量相加&#xff0c;原张量是归一化后的&#xff0c;我的没有&#xff1a; class Module(nn.Module):def __init__(self,dim,):super().__init__()# 新增一个LayerNo…

OpenAI发布GPT-4.0使用指南

大家好&#xff0c;ChatGPT 自诞生以来&#xff0c;凭借划时代的创新&#xff0c;被无数人一举送上生成式 AI 的神坛。在使用时&#xff0c;总是期望它能准确理解我们的意图&#xff0c;却时常发现其回答或创作并非百分之百贴合期待。这种落差可能源于我们对于模型性能的过高期…

ElasticSearch总结2

一、创建索引库&#xff1a;PUT ES中通过Restful请求操作索引库、文档。请求内容用DSL语句来表示。创建索引库和mapping的DSL语法如下&#xff1a; 整个jason 里边&#xff0c;它有一个叫mapping的属性&#xff0c;代表的是映射。映射里边有properties代表就是字段。可以看到这…

Android Studio入门级教程(详细)【小白必看】[通俗易懂]

Android Studio如何使用 本文主要讲解一下Android Studio使用方法 步骤&#xff1a; 1.建立项目 首先点击new——new project新建项目 选择想要创建的Android 的模板&#xff0c;建议选择empty activity&#xff08;空模板&#xff09;&#xff0c;然后next Name&#xff1…

(附源码)超级简单的SSM大学生创新创业管理系统,包含架构图、设计图、论文。

下面一大堆图和步骤看起来复杂&#xff0c;但是只要跟着教程走&#xff0c;都能部署成功。数据库设计简单明了&#xff0c;代码注释完整&#xff0c;小白也能看得懂&#xff0c;纯小白需要费点功夫。 项目结构图 内容截图&#xff1a; 用到软件 Jdk1.8 Mysql IntelliJ IDEA…

Python urllib 爬虫入门(1)

本文主要为Python urllib类库函数和属性介绍及一些简单示例。 目录 urllib爬取网页 简单示例 写入文件 其他读取方法 readline函数 readlines函数 response属性 当前环境信息 返回状态码 返回url地址 对url进行编码与解码 写入文件 总结 urllib爬取网页 通过pyth…

form1弹出子窗体form2,拖动子窗体判断是否离开父窗体区域,含源码(学习笔记)

一、效果&#xff08;进入和离开&#xff09; 子窗体到达父窗体边缘时变色。 二、代码分析 判断父窗体的目的&#xff0c;可以控制子窗体要随父窗体走。上面代码需要加以处理。 如&#xff1a;this.Location new Point(parentPoint.X distanceFromEdge, this.Location.Ydis…

NCC导入导出开发

&#x1f4e3;NCC导入导出开发 ✨1. 导入流程图 ✨2. 实现步骤 &#x1f434;1. 前端代码实现。 &#x1f434;2. 配置文件创建与设置。 &#x1f434;3. 后端代码实现。 &#x1f434;4. 注册后端代码类。

力扣---二叉树的右视图

给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,null,3] 输出: [1,3]示例 3: 输入: [] 输出: []实现方法&…

双非本科自述: 无竞赛国奖,怎么逆袭腾讯字节

写在前面 大家好&#xff0c;我是青玉白露。 在这个充斥着精英主义色彩的社会里&#xff0c;"双一流"大学和耀眼奖项似乎成了走向职业成功、大厂的不二法门及必备之物。 然而&#xff0c;今天我要分享的&#xff0c;是一个打破常规的故事&#xff0c;是一个关于普…

AQS共享模式之CyclicBarrier

概念&#xff1a;CyclicBarrier翻译为循环(屏障/栅栏)&#xff0c;当一组线程到达一个屏障&#xff08;同步点&#xff09;时被阻塞&#xff0c;直到最后一个线程到达屏障时&#xff0c;屏障才会打开&#xff0c;所有被屏障拦截的线程才会继续工作。 设计目的&#xff1a;和Co…

什么牌子的洗地机质量比较好?四大热门品牌实测,快看过来

随着科技的发展&#xff0c;各种智能家居产品层出不穷&#xff0c;为我们的生活带来了诸多便利。近年来&#xff0c;在家庭清洁领域&#xff0c;洗地机成为了热门选择&#xff0c;可是什么牌子的洗地机质量比较好呢&#xff1f;我们一起来看看吧。 洗地机选购技巧&#xff1a;…

大数据中的项目数据采集

Datax介绍 官网&#xff1a; DataX/introduction.md at master alibaba/DataX GitHub DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。 DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS…

【漏洞复现】若依druid 未授权访问漏洞

0x01 产品简介 若依&#xff08;Ruoyi&#xff09;框架是一款基于Spring Boot、Spring Cloud、OAuth2与JWT鉴权等核心技术的快速开发平台。它支持多种安全框架和持久化框架&#xff0c;并采用前后端分离的模式进行开发&#xff0c;具备高度的灵活性和可扩展性。若依框架提供了…

VTK 的可视化方法:颜色映射

VTK 的可视化方法&#xff1a;颜色映射 VTK 的可视化方法&#xff1a;颜色映射颜色映射过程vtkDataSetvtkDataSetAttributesvtkLookUpTablevtkScalarBarActor实例参考 VTK 的可视化方法&#xff1a;颜色映射 颜色映射的操作对象是数据集中的标量属性。它是一种常用的标量算法。…

.net core ef 连表查询

Information和TypeInfo连表查询 类似&#xff1a; select st.Title1,si.* from [Star_Information] si left join Star_TypeInfo st on si.typeId2st.id 先在EfCoreDbContext.cs配置 protected override void OnModelCreating(ModelBuilder builder){base.OnModelCreating(b…