Android 13 配置默认DN
需求:
如果存在用户配置的DNS服务器,则切面拦截运行商下发的DNS,替换为用户自己配置的DNS.
实现:
直接上代码:
1:TelephonyProperties 内新增属性保存用户设置的dns
//QSSI.13/frameworks/base/telephony/java/com/android/internal/telephony/TelephonyProperties.java/*** PROPERTY_SIM_DEFAULT_DNS is to set the default DNS*/static String PROPERTY_SIM_DEFAULT_DNS = "sim.default.dns";
这里我们注意下TelephonyProperties 为接口类,系统未找到相关的实现类,其实此处的用法类似于aidl文件到java文件的转换,是编译脚本进行转换(build/soong/sysprop/sysprop_library.go)
即会将libsysprop目录下的.sysprop文件编译成对应的.jar给系统调用,即会编译为:PlatformProperties.jar,我们可以把以下目录中的源码文件拖到AS看下
目录:QSSI.13\out\soong\.intermediates\system\libsysprop\srcs\PlatformProperties\android_common\javac\PlatformProperties.jar
我们截取部分TelephonyProperties.class代码看下
public static Optional<Boolean> airplane_mode_on() {String value = SystemProperties.get("persist.radio.airplane_mode_on");return Optional.ofNullable(tryParseBoolean(value));
}public static void airplane_mode_on(Boolean value) {SystemProperties.set("persist.radio.airplane_mode_on", value == null ? "" : (value ? "1" : "0"));
}
从这个反编译出来的文件可以看到,实际上就是对SystemProperties做了一层封装。
2:在TelephonyProperties.sysprop 中定义属性
//QSSI.13/system/libsysprop/srcs/android/sysprop/TelephonyProperties.sysprop
# set default dns list
prop {api_name: "sim_default_dns"type: StringListscope: Publicaccess: ReadWriteprop_name: "sim.default.dns"
}
注意我们新增了属性,需要执行如下指令,更新api文件,具体的详见脚本文件:/build/soong/scripts/freeze-sysprop-api-files.sh
m PlatformProperties-dump-api && rm -rf system/libsysprop/srcs/api/PlatformProperties-current.txt && cp -f out/soong/.intermediates/system/libsysprop/srcs/PlatformProperties_sysprop_library/api-dump.txt system/libsysprop/srcs/api/PlatformProperties-current.txt
执行上述指令以后会更新如下文件
//QSSI.13/system/libsysprop/srcs/api/PlatformProperties-current.txt
prop {api_name: "sim_default_dns"type: StringListaccess: ReadWriteprop_name: "sim.default.dns"}
3:我们新增了属性为sim.default.dns,我们还需要增加selinux权限,即为此属性配置上下文,可直接使用之前系统定义好的上下文
//QSSI.13/system/sepolicy/private/property_contexts
sim.default.dns u:object_r:telephony_status_prop:s0 exact string
//QSSI.13/system/sepolicy/prebuilts/api/33.0/private/property_contexts
sim.default.dns u:object_r:telephony_status_prop:s0 exact string
4:经过上述步骤,我们即可在TelephonyManager内对属性sim.default.dns进行读写
//QSSI.13/frameworks/base/telephony/java/android/telephony/TelephonyManager.java/*** Set TelephonyProperties.default_dns for dns.** @hide*/public void setSimDnsServers(int phoneId, String dnsStr) {if (SubscriptionManager.isValidPhoneId(phoneId)) {List<String> newList = new ArrayList();if (!TextUtils.isEmpty(dnsStr)) {List<String> tList = updateTelephonyProperty(TelephonyProperties.sim_default_dns(), phoneId, dnsStr);newList.addAll(tList);}for (int i = 0; i < newList.size(); i++) {Log.e(TAG, "setSimDns...." + newList.get(i));}Log.e(TAG, "setSimDnsList...." + dnsStr + ":" + newList);TelephonyProperties.sim_default_dns(newList);}}/*** get TelephonyProperties.default_dns** @hide*/public String getSimDnsServers(int phoneId) {return getTelephonyProperty(phoneId, TelephonyProperties.sim_default_dns(), "");}
5:我们在建立datacall的时候,就可以读取配置的dns服务器,然后更新,我是在DataNetwork 中处理的,当然也可以在ConnectivityService内处理
//QSSI.13/frameworks/opt/telephony/src/java/com/android/internal/telephony/data/DataNetwork.java/*** Update data network based on the latest {@link DataCallResponse}.** @param response The data call response from data service.*/private void updateDataNetwork(@NonNull DataCallResponse response) {.......//phoebe add for set default dns// Set DNS serversList<InetAddress> defaultDns = getDefaultDns(mPhone.getPhoneId());if (defaultDns != null && defaultDns.size() > 0) {loge("set default dns:" + defaultDns);linkProperties.setDnsServers(defaultDns);} else {if (response.getDnsAddresses().size() > 0) {for (InetAddress dns : response.getDnsAddresses()) {if (!dns.isAnyLocalAddress()) {linkProperties.addDnsServer(dns);}}} else {loge("Empty dns response");}}....}public List<InetAddress> getDefaultDns(int phoneId) {String dnsStr = mTelephonyManager.getSimDnsServers(phoneId);logl("zmm add for getDefaultDns..." + dnsStr);String[] split = TextUtils.isEmpty(dnsStr) ? null : dnsStr.trim().split(",");if (split == null || split.length == 0) {return null;}List<InetAddress> dnsService = new ArrayList<>();try {for (String str : split) {if (!str.trim().isEmpty()) {InetAddress dns = InetAddress.parseNumericAddress(str);logl("zmm add for default dns..." + dns);dnsService.add(dns);}}} catch (Exception e) {e.printStackTrace();loge("zmm add for default dns..." + e.getMessage());}return dnsService;}
6:设置客户自定义的dns,我是在SIMRecords中设置默认的dns的,当然也可在别的地方通过mTelephonyManager.setSimDnsServers()方法设置不同sim卡的不同dns
当然需要再setdatacall建立成功之前,就设置到属性中去。
//QSSI.13/frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/SIMRecords.java
多个dns服务器用逗号隔开
mTelephonyManager.setSimDnsServers(mPhoneId(), "dns1,dns2");
相关文章:
Android 13 配置默认DN
需求: 如果存在用户配置的DNS服务器,则切面拦截运行商下发的DNS,替换为用户自己配置的DNS. 实现: 直接上代码: 1:TelephonyProperties 内新增属性保存用户设置的dns //QSSI.13/frameworks/base/telephony/java/com/android/in…...

系统开发与运行知识
系统开发与运行知识 导航 文章目录 系统开发与运行知识导航一、软件工程二、软件生命周期三、开发模型四、开发方法五、需求分析结构化分析 六、数据流图分层数据流图的画法设计注意事项 七、数据字典数据字典的内容 八、系统设计九、结构化设计常用工具十、面向对象十一、UML…...
算法训练 | 二叉树Part1 | 递归遍历、迭代遍历、统一迭代
目录 递归遍历 前序遍历 迭代遍历 前序遍历(迭代法) 中序遍历(迭代法) 后序遍历(迭代法) 统一迭代法 统一迭代 嵌入式学习分享个人主页:Orion嵌入式随想录 - 小红书 (xiaohongshu.com) …...
AcWing 2568:树链剖分 ← 线段树+DFS
【题目来源】https://www.acwing.com/problem/content/2570/【题目描述】 给定一棵树,树中包含 n 个节点(编号 1∼n),其中第 i 个节点的权值为 ai。 初始时,1 号节点为树的根节点。 现在要对该树进行 m 次操作…...

PCIe协议之-DLLP详解
✨前言: 🌟数据链路层的功能 数据链路层将从物理层中获得报文, 并将其传递给事务层; 同时接收事务层的报文, 并将其转发到物理层; 核心的功能有以下三点 1.保证TLP在 PCIe 链路中的正确传递; 2.数据链路层使用了容错…...

Jmeter+prometheus+grafana性能测试
文章目录 Jmeterprometheusgrafana性能测试背景目标设计思路原理案例启发 Jmeterprometheusgrafana性能测试 背景 在现代社会中,人们对于应用程序的响应速度和性能体验提出了越来越高的要求。无论是电子商务网站、社交媒体平台还是企业级软件系统,都…...

Hololens 2 新建自定义按钮
官方链接地址 1、创建Cube 2、添加PressableButton脚本,并点击AddNearin… 3、把Cube拖入到MovingButtonVisuals变量中 4、点击NearInteractionTouchable组件(这个组件是添加和上一个脚本绑定的,自动添加上来的)上的Fix… 5、…...

景源畅信:抖音小店新手小白如何做好运营?
在数字时代的浪潮中,抖音小店成为了众多创业者和商家的新宠。但面对激烈的市场竞争和不断变化的平台规则,新手小白如何才能在抖音小店的海洋里稳健航行,捕捉到属于自己的商机呢?接下来的内容将为你揭晓答案。 一、精准定位,明确目…...
力扣 42. 接雨水 python AC
双指针 class Solution:def trap(self, heights):l, r 0, len(heights) - 1maxl, maxr 0, 0ans 0while l < r:maxl, maxr max(maxl, heights[l]), max(maxr, heights[r])if maxl < maxr:ans maxl - heights[l]l 1else:ans maxr - heights[r]r - 1return ans单调栈…...
The 2022 ICPC Asia Nanjing Regional Contest - External D
G题 赛题补充 D题的题目来源 https://codeforces.com/gym/104128/problem/D 文章目录 题意思路代码 题意 给一个长度为n的数组,问对一段区间添加等差数列后的最大的第 k 大是多少 思路 通过观察题目可以发现答案的范围符合单调性,因此我们可以考虑二分…...

2024年蓝桥杯B组C++——复盘
1、握手问题 知识点:模拟 这道题很简单。但是不知道考试的时候有没有写错。一开始的43个人握手,仅需要两两握手,也就是从42个握手开始,而非43.很可惜。这道题没有拿稳这5分。也很有可能是这5分导致没有进决赛。 总结:…...

微调Llama3实现在线搜索引擎和RAG检索增强生成功能
视频中所出现的代码 Tavily SearchRAG 微调Llama3实现在线搜索引擎和RAG检索增强生成功能!打造自己的perplexity和GPTs!用PDF实现本地知识库_哔哩哔哩_bilibili 一.准备工作 1.安装环境 conda create --name unsloth_env python3.10 conda activate …...

【软件工程】【23.04】p1
关键字: 软件模型、提炼、加工表达工具、通信内聚、访问依赖、边界类交互分析、RUP核心工作流、首先测试数据流、软件验证过程、CMMI过程域分类工程类; 软件工程目的、功能需求是需求的主体、结构化方法、耦合、详细设计工具、类、类图、RUP采用用例技…...
Flutter 中的 ColoredBox 小部件:全面指南
Flutter 中的 ColoredBox 小部件:全面指南 在 Flutter 的世界中,ColoredBox 是一个用于填充颜色的简单而强大的小部件。它是一个不透明的矩形,可以用来创建颜色块,作为布局的占位符,或者简单地改变某个区域的背景色。…...

【LeetCode 随笔】面试经典 150 题【中等+困难】持续更新中。。。
文章目录 12.【中等】整数转罗马数字151.【中等】反转字符串中的单词6.【中等】Z 字形变换68.【困难】文本左右对齐167.【中等】两数之和 II - 输入有序数组 🌈你好呀!我是 山顶风景独好 💝欢迎来到我的博客,很高兴能够在这里和您…...

SwiftUI中AppStorage的介绍使用
在Swift中,AppStorage是SwiftUI中引入的一个属性包装器,在这之前我们要存储一些轻量级的数据采用UserDefaults进行存取。而AppStorage用于从UserDefaults中读取值,当值改变时,它会自动重新调用视图的body属性。也就是说࿰…...

iCloud 照片到 Android 指南:帮助您快速将照片从 iCloud 传输到安卓手机
概括 iOS 和 Android 之间的传输是一个复杂的老问题。将 iCloud 照片传输到 Android 似乎是不可能的。放心。现在的高科技已经解决了这个问题。尽管 Apple 和 Android 不提供传输工具,但您仍然有其他有用的选项。这篇文章与您分享了 5 个技巧。因此,…...

知识点总结
1、Uboot的流程调用: 1.1、cmd_process函数是怎么被调用到的: cmd_process在common/command.c 1.2、uboot阶段断电,后续起不来,可能要换线去使用,也许和电源线有关 2、git 相关使用 2.1 .gitignore相关的使用 1、…...
Python并发与异步编程
Python的并发与异步编程是两个不同的概念,但它们经常一起使用,以提高程序的性能和响应能力。以下是对这两个概念的详细讲解: 并发编程 (Concurrency) 并发编程是指在程序中同时执行多个任务的能力。Python提供了几种实现并发的机制ÿ…...

动态内存管理—C语言通讯录
目录 一,动态内存函数的介绍 1.1 malloc和free 1.2 calloc 1.3 realloc 1.4C/C程序的内存开辟 二,通讯录管理系统 动态内存函数的介绍 malloc free calloc realloc 一,动态内存函数的介绍 1.1 malloc和free void* malloc (…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...