Android CarrierConfig 参数项和正则匹配逻辑

news2024/12/23 9:10:37

背景

在编写CarrierConfig的时候经常出现配置不生效的情况,比如运营商支持大范围的imsi,或者是测试人员写卡位数的问题等等,因此就需要模式匹配(包含但不限于正则表达式)。

  1. 基本概念:

    • 模式匹配涉及定义一个“模式”,该模式可以是一个字符串、正则表达式或其他结构。系统将此模式应用于目标数据,找出符合该模式的部分。
  2. 应用场景:

    • 字符串匹配: 查找特定字符序列或模式,例如在文本中查找单词或短语。
    • 数据解析: 分析和提取数据,例如从 JSON 或 XML 文档中提取信息。
    • 正则表达式: 使用正则表达式进行复杂的字符串匹配和替换操作。
    • 逻辑匹配: 例如在函数式编程中,使用模式匹配来简化条件语句。
  3. 编程语言中的模式匹配实现:

    很多编程语言都支持模式匹配的特性,例如:
    • Haskell: 强大的模式匹配功能,可用于列表、元组等数据结构。        
    • Scala: 提供内置的模式匹配语法,用于匹配类型和结构。
    • Java: 使用 Pattern 和 Matcher 类进行正则表达式匹配。
    • Python: 使用 re 模块进行正则表达式匹配。

解析逻辑

packages/apps/CarrierConfig/src/com/android/carrierconfig/DefaultCarrierConfigService.java

详细代码

  1. 参数解析:

    • xmlImsi: 这是从 XML 资源中获取的 IMSI 表达式,它可能是一个正则表达式。
    • id: 这是一个 CarrierIdentifier 对象,提供了当前的 IMSI。
  2. 获取当前 IMSI:

    • String currentImsi = id.getImsi();: 该行代码从 CarrierIdentifier 对象中获取当前的 IMSI 字符串。
  3. 正则表达式匹配:

    • Pattern imsiPattern = Pattern.compile(xmlImsi, Pattern.CASE_INSENSITIVE);: 这行代码将 XML 中的 IMSI 表达式编译成正则表达式模式,并设置为不区分大小写(尽管在 IMSI 字符串中通常不涉及大小写问题)。
    • Matcher matcher = imsiPattern.matcher(currentImsi);: 这行代码创建一个 Matcher 对象,用于比较当前 IMSI。
  4. 执行匹配:

    • matchFound = matcher.matches();: 这个方法检查当前 IMSI 是否与正则表达式匹配。

参数检查 

checkFilters检查的参数包含:

如下代码可见,支持正则匹配的只有imsi和sp。

    /**
     * Checks to see if an XML node matches carrier filters.
     *
     * <p>This iterates over the attributes of the current tag pointed to by {@code parser} and
     * checks each one against {@code id} or {@link Build.DEVICE} or {@link R.string#sku_filter} or
     * {@link Build.BOARD}. Attributes that are not specified in the node will not be checked, so a
     * node with no attributes will always return true. The supported filter attributes are,
     * <ul>
     *   <li>mcc: {@link CarrierIdentifier#getMcc}</li>
     *   <li>mnc: {@link CarrierIdentifier#getMnc}</li>
     *   <li>gid1: {@link CarrierIdentifier#getGid1}</li>
     *   <li>gid2: {@link CarrierIdentifier#getGid2}</li>
     *   <li>spn: {@link CarrierIdentifier#getSpn}</li>
     *   <li>imsi: {@link CarrierIdentifier#getImsi}</li>
     *   <li>device: {@link Build.DEVICE}</li>
     *   <li>vendorSku: {@link SystemConfig.VENDOR_SKU_PROPERTY}</li>
     *   <li>hardwareSku: {@link SystemConfig.SKU_PROPERTY}</li>
     *   <li>board: {@link Build.BOARD}</li>
     *   <li>cid: {@link CarrierIdentifier#getCarrierId()}
     *   or {@link CarrierIdentifier#getSpecificCarrierId()}</li>
     *   <li>sku: {@link R.string#sku_filter} "sku_filter" that OEM customizable filter</li>
     * </ul>
     * </p>
     *
     * <p>
     * The attributes imsi and spn can be expressed as regexp to filter on patterns.
     * The spn attribute can be set to the string "null" to allow matching against a SIM
     * with no spn set.
     * </p>
     *
     * @param parser an XmlPullParser pointing at a START_TAG with the attributes to check.
     * @param id the carrier details to check against.
     * @param sku a filter to be customizable.
     * @return false if any XML attribute does not match the corresponding value.
     */
    static boolean checkFilters(XmlPullParser parser, @Nullable CarrierIdentifier id, String sku) {
        String vendorSkuProperty = SystemProperties.get(
            "ro.boot.product.vendor.sku", "");
        String hardwareSkuProperty = SystemProperties.get(
            "ro.boot.product.hardware.sku", "");
        for (int i = 0; i < parser.getAttributeCount(); ++i) {
            boolean result = true;
            String attribute = parser.getAttributeName(i);
            String value = parser.getAttributeValue(i);
            switch (attribute) {
                case "mcc":
                    result = (id == null) || value.equals(id.getMcc());
                    break;
                case "mnc":
                    result = (id == null) || value.equals(id.getMnc());
                    break;
                case "gid1":
                    result = (id == null) || value.equalsIgnoreCase(id.getGid1());
                    break;
                case "gid2":
                    result = (id == null) || value.equalsIgnoreCase(id.getGid2());
                    break;
                case "spn":
                    result = (id == null) || matchOnSP(value, id);
                    break;
                case "imsi":
                    result = (id == null) || matchOnImsi(value, id);
                    break;
                case "device":
                    result = value.equalsIgnoreCase(Build.DEVICE);
                    break;
                case "vendorSku":
                    result = value.equalsIgnoreCase(vendorSkuProperty);
                    break;
                case "hardwareSku":
                    result = value.equalsIgnoreCase(hardwareSkuProperty);
                    break;
                case "board":
                    result = value.equalsIgnoreCase(Build.BOARD);
                    break;
                case "cid":
                    result = (id == null) || (Integer.parseInt(value) == id.getCarrierId())
                                || (Integer.parseInt(value) == id.getSpecificCarrierId());
                    break;
                case "name":
                    // name is used together with cid for readability. ignore for filter.
                    break;
                case "sku":
                    result = value.equalsIgnoreCase(sku);
                    break;
                default:
                    Log.e(TAG, "Unknown attribute " + attribute + "=" + value);
                    result = false;
                    break;
            }

            if (!result) {
                return false;
            }
        }
        return true;
    }

IMSI的匹配逻辑

  1. 参数解析:

    • xmlImsi: 这是从 XML 资源中获取的 IMSI 表达式,它可能是一个正则表达式。
    • id: 这是一个 CarrierIdentifier 对象,提供了当前的 IMSI。
  2. 获取当前 IMSI:

    • String currentImsi = id.getImsi();: 该行代码从 CarrierIdentifier 对象中获取当前的 IMSI 字符串。
  3. 正则表达式匹配:

    • Pattern imsiPattern = Pattern.compile(xmlImsi, Pattern.CASE_INSENSITIVE);: 这行代码将 XML 中的 IMSI 表达式编译成正则表达式模式,并设置为不区分大小写(尽管在 IMSI 字符串中通常不涉及大小写问题)。
    • Matcher matcher = imsiPattern.matcher(currentImsi);: 这行代码创建一个 Matcher 对象,用于比较当前 IMSI。
  4. 执行匹配:

    • matchFound = matcher.matches();: 这个方法检查当前 IMSI 是否与正则表达式匹配。
    /**
     * Check to see if the IMSI expression from the XML matches the IMSI of the
     * Carrier.
     *
     * @param xmlImsi IMSI expression fetched from the resource XML
     * @param id Id of the evaluated CarrierIdentifier
     * @return true if the XML IMSI matches the IMSI of CarrierIdentifier, false
     *         otherwise.
     */
    static boolean matchOnImsi(String xmlImsi, CarrierIdentifier id) {
        boolean matchFound = false;

        String currentImsi = id.getImsi();
        // If we were able to retrieve current IMSI, see if it matches.
        if (currentImsi != null) {
            //使用 Pattern 和 Matcher 接口,
            //使用正则表达式来匹配 xmlImsi 与 currentImsi。
            //这允许 xmlImsi 采用正则表达式的形式,从而支持更复杂的匹配逻辑,比如匹配特定模式的 IMSI 字符串。
            Pattern imsiPattern = Pattern.compile(xmlImsi, Pattern.CASE_INSENSITIVE);
            Matcher matcher = imsiPattern.matcher(currentImsi);
            matchFound = matcher.matches();
        }
        return matchFound;
    }

资料

  • 展讯平台参考:CarrierConfig配置使用和加载流程简介-CSDN博客
  • AOSP:【Telephony】CarrierConfig加载流程解析&运营商ims配置增删查改(AOSP)-CSDN博客

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

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

相关文章

Golang | Leetcode Golang题解之第557题反转字符串中的单词III

题目&#xff1a; 题解&#xff1a; func reverseWords(s string) string {length : len(s)ret : []byte{}for i : 0; i < length; {start : ifor i < length && s[i] ! {i}for p : start; p < i; p {ret append(ret, s[start i - 1 - p])}for i < le…

运行WHTools批量启动游戏房间工具提示要安装.Net Framework3.5解决

确认电脑能正常上网 点击下载并安装此功能&#xff0c;开始安装.Net Framework 3.5 安装成功 成功启动WHTools

Xcode 16 使用 pod 命令报错解决方案

原文请点击这个跳转 一、问题现象&#xff1a; 有人会遇到 Xcode 升级到 16 后&#xff0c;新建应用然后使用 pod init 命令会报错如下&#xff1a; Stack Ruby : ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [x86_64-darwin23]RubyGems : 3.5.22Host : macOS 15.0 (24A335…

STM32WB55RG开发(1)----开发板测试

STM32WB55RG开发----1.开发板测试 概述硬件准备视频教学样品申请源码下载产品特性参考程序生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32WB55 & SENSOR是一款基于STM32WB55系列微控制器的评估套件。该套件采用先进的无线通信技术&#xff0c;支…

【广西】《广西壮族自治区本级政务信息化建设和运维项目预算支出标准》(桂财建〔2023〕102号)-省市费用标准解读系列09

《广西壮族自治区本级政务信息化建设和运维项目预算支出标准》&#xff08;桂财建〔2023〕102号&#xff09;是广西壮族自治区财政厅于2023年9月26日发布的费用标准&#xff08;了解更多可直接关注我们咨询&#xff09;。我司基于专业第三方信息化项目造价机构角度&#xff0c;…

前端学习笔记-Ajax篇

第1章:原生AJAX 1.1Ajax简介 AAX 全称为 Asynchronous JavaScript And XML&#xff0c;就是异步的 JS 和 XML。 通过 AAX 可以在浏览器中向服务器发送异步请求&#xff0c;最大的优势:无刷新获取数据。 AAX 不是新的编程语言&#xff0c;而是一种将现有的标准组合在一起使用…

HarmonyOS Next 实战卡片开发 02

HarmonyOS Next 实战卡片开发 02 卡片开发中&#xff0c;还有一个难点是显示图片。其中分为显示本地图片和显示网络图片 显示本地图片 卡片可以显示本地图片&#xff0c;如存放在应用临时目录下的图片。路径比如 /data/app/el2/100/base/你的项目boundleName/temp/123.png 以…

将文字转换为运动:使用AMD GPU生成视频指南

Transforming Words into Motion: A Guide to Video Generation with AMD GPU — ROCm Blogs 发布日期: 2024年4月24日 作者: Douglas Jia 本博客介绍了通过增强稳定扩散模型在文本到视频生成方面的进展&#xff0c;并展示了使用阿里巴巴的ModelScopeT2V模型在AMD GPU上生成视频…

快速入门Zookeeper

Zookeeper ZooKeeper作为一个强大的开源分布式协调服务&#xff0c;扮演着分布式系统中至关重要的角色。它提供了一个中心化的服务&#xff0c;用于维护配置信息、命名、提供分布式同步以及提供组服务等。通过其高性能和可靠的特性&#xff0c;ZooKeeper能够确保在复杂的分布式…

服务器上安装Orcale数据库以及PL SQL工具(中文)

一、前期准备 1、oracle数据库安装包–>Oracle下载地址&#xff0c;版本根据当时情况就下最新的就行&#xff0c;下载时间可能有点长&#xff0c;耐心点。 2、PL SQL工具下载地址–>PL SQL下载地址&#xff0c;百度网盘可以共享【限速&#xff0c;没办法&#xff01;&am…

协程6 --- HOOK

文章目录 HOOK 概述链接运行时动态链接 linux上的常见HOOK方式修改函数指针用户态动态库拦截getpidmalloc 第一版malloc 第二版malloc/free通过指针获取到空间大小malloc 第三版strncmp 内核态系统调用拦截堆栈式文件系统 协程的HOOK HOOK 概述 原理&#xff1a;修改符号指向 …

[0342].第12节:加载与存储指令及算数指令

我的后端学习大纲 JVM学习大纲 一、加载与存储指令&#xff1a; 加载&#xff1a;主要是指的将数据压入到操作数栈中&#xff0c;那么这个数据可能来源于常量池也可能来自于局部变量表 1.iload_0占1个字节。iload 0 占3个字节。 2.因为操作码数量有限&#xff0c;只有256个&…

spark的学习-06

SparkSQL读写数据的方式 1&#xff09;输入Source 方式一&#xff1a;给定读取数据源的类型和地址 spark.read.format("json").load(path) spark.read.format("csv").load(path) spark.read.format("parquet").load(path) 方式二&#xff1a…

ODOO学习笔记(5):ODOO开发规范

一、代码结构与布局 模块结构&#xff1a; 每个ODOO模块应具有清晰的结构&#xff0c;通常包含以下目录和文件&#xff1a; models&#xff1a;存放业务逻辑相关的模型类定义&#xff0c;如定义数据库表结构、业务规则等。views&#xff1a;用于放置各种视图文件&#xff0c;包…

【性能测试】linux服务器性能监控常用命令

CPU 性能监控指令 top 命令 基本功能&#xff1a;top 命令是 Linux 系统中最常用的性能监控工具之一。它可以实时显示系统中各个进程的资源占用情况&#xff0c;包括 CPU 使用率、内存使用量、进程状态等信息。在性能测试监控服务器性能时&#xff0c;通过 top 命令可以快速查…

ROS2humble版本使用colcon构建包

colcon与与catkin相比&#xff0c;没有 devel 目录。 创建工作空间 首先&#xff0c;创建一个目录 ( ros2_example_ws ) 来包含我们的工作区: mkdir -p ~/ros2_example_ws/src cd ~/ros2_example_ws 此时&#xff0c;工作区包含一个空目录 src : . └── src1 directory, …

VUE使用TS开发打包时发现校验问题无法打包

解决办法&#xff1a; 找到 tsconfig.app.json 这个文件&#xff0c;把他的include改为一个实际存在的空文件即可

vscode+EIDE开发环境搭建

嵌入式知识框架目录篇章&#xff1a;返回请点我 热门优质文章 文章标题等级&#xff1a;低中高推荐指数5√最佳vscode安装配置使用调试【保姆级教程】中√√√[VSCODE]基于EIDE插件搭建vscode下的STM32单片机开发环境中√√√官方安装高√√√√VScode利用EIDE和cortex-debug…

kafka面试题解答(四)

5、消费者组和分区数之间的关系是怎样的&#xff1f; 消费者组数小于等于分区数&#xff0c;消费者组内每个消费者负责消费不同分区的数据&#xff0c;一个分区只能由一个组内消费者消费。 6、kafka如何知道哪个消费者消费哪个分区&#xff1f; 生产者把数据发送给各个分区&…

C#入门 020 事件(类型成员)

初步了解事件 定义:单词Event&#xff0c;译为“事件” 《牛津词典》中的解释是“a thing that happens, especially something important通顺的解释就是“能够发生的什么事情” 角色:使对象或类具备通知能力的成员 事件(event)是一种使对象或类能够提供通知的成员对象O拥有…