Android 11.0 动态修改SystemProperties中ro开头系统属性的值
需求: 在11.0的产品开发中,对于定制功能的需求很多,有些机型要求可以修改系统属性值,对于系统本身在10.0以后为了系统安全性,不允许修改ro开头的SystemProperties的值,所以如果要求修改ro的相关系统属性,就得看在设置SystemProperties的相关值的要求,修改这部分要求就可以了
动态修改SystemProperties中ro开头系统属性的值的核心代码
frameworks/base/core/java/android/os/SystemProperties.java/system/core/init/property_service.cpp
2.动态修改SystemProperties中ro开头系统属性的值的功能分析和实现功能
2.1 关于系统属性SystemProperty分析
系统属性,肯定对整个系统全局共享。通常程序的执行以进程为单位各自相互独立,如何实现全局共享呢?属性系统是android的一个重要特性。它作为一个服务运行,管理系统配置和状态。所有这些配置和状态都是属性。SystemProperties.java每个属性是一个键值对(key/value pair),其类型都是字符串
接下来看下SystemProperties.java相关方法
private static native String native_get(String key);private static native String native_get(String key, String def);private static native int native_get_int(String key, int def);@UnsupportedAppUsageprivate static native long native_get_long(String key, long def);private static native boolean native_get_boolean(String key, boolean def);private static native void native_set(String key, String def);/*** Get the String value for the given {@code key}.** @param key the key to lookup* @param def the default value in case the property is not set or empty* @return if the {@code key} isn't found, return {@code def} if it isn't null, or an empty* string otherwise* @hide*/@NonNull@SystemApi@TestApipublic static String get(@NonNull String key, @Nullable String def) {if (TRACK_KEY_ACCESS) onKeyAccess(key);return native_get(key, def);}/*** Get the value for the given {@code key}, and return as an integer.** @param key the key to lookup* @param def a default value to return* @return the key parsed as an integer, or def if the key isn't found or* cannot be parsed* @hide*/@SystemApipublic static int getInt(@NonNull String key, int def) {if (TRACK_KEY_ACCESS) onKeyAccess(key);return native_get_int(key, def);}/*** Get the value for the given {@code key}, and return as a long.** @param key the key to lookup* @param def a default value to return* @return the key parsed as a long, or def if the key isn't found or* cannot be parsed* @hide*/@SystemApipublic static long getLong(@NonNull String key, long def) {if (TRACK_KEY_ACCESS) onKeyAccess(key);return native_get_long(key, def);}@SystemApi@TestApipublic static boolean getBoolean(@NonNull String key, boolean def) {if (TRACK_KEY_ACCESS) onKeyAccess(key);return native_get_boolean(key, def);}/*** Set the value for the given {@code key} to {@code val}.** @throws IllegalArgumentException if the {@code val} exceeds 91 characters* @hide*/@UnsupportedAppUsagepublic static void set(@NonNull String key, @Nullable String val) {if (val != null && !val.startsWith("ro.") && val.length() > PROP_VALUE_MAX) {throw new IllegalArgumentException("value of system property '" + key+ "' is longer than " + PROP_VALUE_MAX + " characters: " + val);}if (TRACK_KEY_ACCESS) onKeyAccess(key);native_set(key, val);}
通过上述get()和set()发现 最终是通过jni的方法设置相关的值
最终通过查阅资料发现是在property_service.cpp中来设置系统相关属性的 接下来看下property_service.cpp
设置属性的相关代码
static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) {size_t valuelen = value.size();if (!IsLegalPropertyName(name)) {*error = "Illegal property name";return PROP_ERROR_INVALID_NAME;}if (auto result = IsLegalPropertyValue(name, value); !result.ok()) {*error = result.error().message();return PROP_ERROR_INVALID_VALUE;}prop_info* pi = (prop_info*) __system_property_find(name.c_str());if (pi != nullptr) {// ro.* properties are actually "write-once".// 判断是否ro开头的属性 这只为读的属性 不能修改值if (StartsWith(name, "ro.")) {*error = "Read-only property was already set";return PROP_ERROR_READ_ONLY_PROPERTY;}__system_property_update(pi, value.c_str(), valuelen);} else {int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);if (rc < 0) {*error = "__system_property_add failed";return PROP_ERROR_SET_FAILED;}}// Don't write properties to disk until after we have read all default// properties to prevent them from being overwritten by default values.if (persistent_properties_loaded && StartsWith(name, "persist.")) {WritePersistentProperty(name, value);}// If init hasn't started its main loop, then it won't be handling property changed messages// anyway, so there's no need to try to send them.auto lock = std::lock_guard{accept_messages_lock};if (accept_messages) {PropertyChanged(name, value);}return PROP_SUCCESS;}// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.uint32_t HandlePropertySet(const std::string& name, const std::string& value,const std::string& source_context, const ucred& cr,SocketConnection* socket, std::string* error) {if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) {return ret;}if (StartsWith(name, "ctl.")) {return SendControlMessage(name.c_str() + 4, value, cr.pid, socket, error);}// sys.powerctl is a special property that is used to make the device reboot. We want to log// any process that sets this property to be able to accurately blame the cause of a shutdown.if (name == "sys.powerctl") {std::string cmdline_path = StringPrintf("proc/%d/cmdline", cr.pid);std::string process_cmdline;std::string process_log_string;if (ReadFileToString(cmdline_path, &process_cmdline)) {// Since cmdline is null deliminated, .c_str() conveniently gives us just the process// path.process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());}LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid<< process_log_string;if (value == "reboot,userspace" && !is_userspace_reboot_supported().value_or(false)) {*error = "Userspace reboot is not supported by this device";return PROP_ERROR_INVALID_VALUE;}}// If a process other than init is writing a non-empty value, it means that process is// requesting that init performs a restorecon operation on the path specified by 'value'.// We use a thread to do this restorecon operation to prevent holding up init, as it may take// a long time to complete.if (name == kRestoreconProperty && cr.pid != 1 && !value.empty()) {static AsyncRestorecon async_restorecon;async_restorecon.TriggerRestorecon(value);return PROP_SUCCESS;}return PropertySet(name, value, error);}uint32_t InitPropertySet(const std::string& name, const std::string& value) {uint32_t result = 0;ucred cr = {.pid = 1, .uid = 0, .gid = 0};//获取cr参数std::string error;result = HandlePropertySet(name, value, kInitContext, cr, nullptr, &error);if (result != PROP_SUCCESS) {LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error;}return result;}
在进入property_service修改系统属性时,先调用InitPropertySet(const std::string& name, const std::string& value)
在通过HandlePropertySet(name, value, kInitContext, cr, nullptr, &error) 来获取返回值
在HandlePropertySet()中根据参数name的值分别调用相关的方法来设置值ro 开头的值 最终是由
PropertySet(name, value, error);来设置值时会判断ro开头的值 只读不让修改 所以要修改就去了这个限制
具体修改为:
static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) {size_t valuelen = value.size();if (!IsLegalPropertyName(name)) {*error = "Illegal property name";return PROP_ERROR_INVALID_NAME;}if (auto result = IsLegalPropertyValue(name, value); !result.ok()) {*error = result.error().message();return PROP_ERROR_INVALID_VALUE;}prop_info* pi = (prop_info*) __system_property_find(name.c_str());if (pi != nullptr) {// ro.* properties are actually "write-once".// 判断是否ro开头的属性 这只为读的属性 不能修改值// 修改开始 注释掉这部分代码/* if (StartsWith(name, "ro.")) {*error = "Read-only property was already set";return PROP_ERROR_READ_ONLY_PROPERTY;}*/// 修改完毕__system_property_update(pi, value.c_str(), valuelen);} else {int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);if (rc < 0) {*error = "__system_property_add failed";return PROP_ERROR_SET_FAILED;}}// Don't write properties to disk until after we have read all default// properties to prevent them from being overwritten by default values.if (persistent_properties_loaded && StartsWith(name, "persist.")) {WritePersistentProperty(name, value);}// If init hasn't started its main loop, then it won't be handling property changed messages// anyway, so there's no need to try to send them.auto lock = std::lock_guard{accept_messages_lock};if (accept_messages) {PropertyChanged(name, value);}return PROP_SUCCESS;}
相关文章:
Android 11.0 动态修改SystemProperties中ro开头系统属性的值
需求: 在11.0的产品开发中,对于定制功能的需求很多,有些机型要求可以修改系统属性值,对于系统本身在10.0以后为了系统安全性,不允许修改ro开头的SystemProperties的值,所以如果要求修改ro的相关系统属性&am…...

为什么分库分表
系列文章目录 文章目录系列文章目录前言一、什么是分库分表二、分库分表的原因分库分表三、如何分库分表3.1 垂直拆分1.垂直分库2、垂直分表3.2 水平拆分水平分库水平分表水平分库分表的策略hash取模算法range范围rangehash取模混合地理位置分片预定义算法四、分库分表的问题分…...

1625_MIT 6.828 stabs文档信息整理_下
全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 继续之前的学习笔记,整理一下最近看过的一点stabs资料。 这一页中有一半的信息是Fortran专用的,直接跳过。参数的符号修饰符是p,…...

论文阅读 | Rethinking Coarse-to-Fine Approach in Single Image Deblurring
前言:ICCV2021图像单帧运动去糊论文 论文地址:【here】 代码地址:【here】 Rethinking Coarse-to-Fine Approach in Single Image Deblurring 引言 图像去糊来自与物体或相机的运动。现有的deblur领域的深度学习方法大多都是coarse-to-fin…...

Mysql 增删改查(二)—— 增(insert)、删(delete)、改(update)
目录 一、插入 1、insert 2、replace(插入否则更新) 二、更新(update) 三、删除 1、delete 2、truncate(截断表,慎用) 一、插入 1、insert (1) 单行 / 多行插入 全列插入:…...
JSD2212复习串讲
1. Java语言基础阶段 这一部分主要是练,给一些题目还有讲解一些最基础的语法,做一些额外的补充 1.1 基本概念 1.2 变量 1.2.1 数据类型 4类8种 基本类型:整形、浮点型、字符型、布尔型 整形:byte -》short-》int-》long 浮点…...
sphinx 升级到6.x后的Jquery问题
sphinx 升级到6.0 后,以前对于jquery的默认引用方式发生了改变以前在编译后的html中jquery是如下引用的:<script src"_static/jquery.js"></script>而升级到6.0后,对于jquery 是一个googleapi的远程jquery调用…...

NSSCTF Round#8 Basic
from:http://v2ish1yan.top MyDoor 使用php伪协议读取index.php的代码 php://filter/readconvert.base64-encode/resourceindex.php<?php error_reporting(0);if (isset($_GET[N_S.S])) {eval($_GET[N_S.S]); }if(!isset($_GET[file])) {header(Location:/index.php?fi…...

多传感器融合定位十二-基于图优化的建图方法其一
多传感器融合定位十二-基于图优化的建图方法其一1. 基于预积分的融合方案流程1.1 优化问题分析1.2 预积分的作用1.3 基于预积分的建图方案流程2. 预积分模型设计3. 预积分在优化中的使用3.1 使用方法3.2 残差设计3.3 残差雅可比的推导3.3.1 姿态残差的雅可比3.3.2 速度残差的雅…...

RockChip MPP编码
概述瑞芯微提供的媒体处理软件平台(Media Process Platform,简称 MPP)是适用于瑞芯微芯片系列的通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理,其目的是为了屏蔽不同芯片的差异,为使用者提供统…...
【学习笔记】NOIP暴零赛2
细思极恐,我的能力已经退步到这个地步了吗? 数据结构 这题的修改是强行加进去迷惑你的。 考虑怎么求树的带权重心。 完了我只会树形dp 完了完了 结论:设uuu的子树和为szusz_uszu,所有点权值和为sss,那么树的带…...

linux基本功系列之hostname实战
文章目录前言一. hostname命令介绍二. 语法格式及常用选项三. 参考案例3.1 显示本机的主机名3.2 临时修改主机名3.3 显示短格式的主机名3.4 显示主机的ip地址四. 永久修改主机名4.1 centos6 修改主机名的方式4.2 centos7中修改主机名永久生效总结前言 大家好,又见面…...

Easy-Es框架实践测试整理 基于ElasticSearch的ORM框架
文章目录介绍(1)Elasticsearch java 客户端种类(2)优势和特性分析(3)性能、安全、拓展、社区(2)ES版本及SpringBoot版本说明索引处理(一)索引别名策略&#x…...

【数据结构】双向链表的模拟实现(无头)
目录 前言: 1、认识双向链表中的结点 2、认识并创建无头双向链表 3、实现双向链表当中的一些方法 3.1、遍历输出方法(display) 3.2、得到链表的长度(size) 3.3、查找关键字key是否包含在双链表中(contains) 3.…...
vue自定义指令---处理加载图片失败时出现的碎图,onerror事件
目录 一、自定义指令 1、局部注册和使用 2、全局注册和使用 二、自定义指令处理图片加载失败(碎图) 一、自定义指令 vue中除v-model、v-show等内置指令之外,还允许注册自定义指令,获取DOM元素,扩展额外的功能。 1、局…...

加盟管理系统挑选法则,看完不怕被坑!
经营服装连锁店铺究竟有多难?小编已经不止一次听到身边的老板,抱怨加盟连锁店铺难以管理了,但同时呢,也听到了很多作为加盟商的老板,抱怨总部给的支持和管理不到位。服装加盟店铺管理,到底有哪些难点呢&…...
alertmanager笔记
1 prometheus的思想 所有告警都应该立刻处理掉,不应该存在长时间未解决的告警。所以具体的表现就是高频的数据采集,和告警的自动恢复(默认5分钟) 2 alertmanager API调用 使用如下命令即可手工制造告警,注意startsA…...

Android Jetpack组件之WorkManager后台任务管理的介绍与使用(二)
一、介绍 通过上一篇文,Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)_蜗牛、Z的博客-CSDN博客 我们可以弄清楚workmanager从接入到使用的基本流程。基本可以满足我们日常。那只是简单的入门。如果遇到更复杂的功能,那简单的就无法满…...
【MySQL】第十七部分 约束
【MySQL】第十七部分 约束 文章目录【MySQL】第十七部分 约束17. 约束17.1 约束的分类17.2 非空约束17.3 唯一性约束17.4 主键约束17.5 自增列约束17.6 外键约束17.7 默认约束17.8 check约束总结17. 约束 约束: 可以在创建表的时候规定约束,也可以在表创建之后添加,约束顾名思…...

java ssm集装箱码头TOS系统调度模块的设计与实现
由于历史和经济体制的原因,国内码头物流企业依然保持大而全的经营模式。企业自己建码头、场地、经营集装箱运输车辆。不过近几年来随着经济改革的进一步深入和竞争的激烈,一些大型的码头物流企业逐步打破以前的经营模式,其中最明显的特征就是…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...

nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...