当前位置: 首页 > news >正文

Android 11.0 动态修改SystemProperties中ro开头系统属性的值

需求: 在11.0的产品开发中,对于定制功能的需求很多,有些机型要求可以修改系统属性值,对于系统本身在10.0以后为了系统安全性,不允许修改ro开头的SystemProperties的值,所以如果要求修改ro的相关系统属性,就得看在设置SystemProperties的相关值的要求,修改这部分要求就可以了

  1. 动态修改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开头系统属性的值

需求&#xff1a; 在11.0的产品开发中&#xff0c;对于定制功能的需求很多&#xff0c;有些机型要求可以修改系统属性值&#xff0c;对于系统本身在10.0以后为了系统安全性&#xff0c;不允许修改ro开头的SystemProperties的值&#xff0c;所以如果要求修改ro的相关系统属性&am…...

为什么分库分表

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

1625_MIT 6.828 stabs文档信息整理_下

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

论文阅读 | Rethinking Coarse-to-Fine Approach in Single Image Deblurring

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

Mysql 增删改查(二)—— 增(insert)、删(delete)、改(update)

目录 一、插入 1、insert 2、replace&#xff08;插入否则更新&#xff09; 二、更新&#xff08;update&#xff09; 三、删除 1、delete 2、truncate&#xff08;截断表&#xff0c;慎用&#xff09; 一、插入 1、insert (1) 单行 / 多行插入 全列插入&#xff1a;…...

JSD2212复习串讲

1. Java语言基础阶段 这一部分主要是练&#xff0c;给一些题目还有讲解一些最基础的语法&#xff0c;做一些额外的补充 1.1 基本概念 1.2 变量 1.2.1 数据类型 4类8种 基本类型&#xff1a;整形、浮点型、字符型、布尔型 整形&#xff1a;byte -》short-》int-》long 浮点…...

sphinx 升级到6.x后的Jquery问题

sphinx 升级到6.0 后&#xff0c;以前对于jquery的默认引用方式发生了改变以前在编译后的html中jquery是如下引用的&#xff1a;<script src"_static/jquery.js"></script>而升级到6.0后&#xff0c;对于jquery 是一个googleapi的远程jquery调用&#xf…...

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编码

概述瑞芯微提供的媒体处理软件平台&#xff08;Media Process Platform&#xff0c;简称 MPP&#xff09;是适用于瑞芯微芯片系列的通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理&#xff0c;其目的是为了屏蔽不同芯片的差异&#xff0c;为使用者提供统…...

【学习笔记】NOIP暴零赛2

细思极恐&#xff0c;我的能力已经退步到这个地步了吗&#xff1f; 数据结构 这题的修改是强行加进去迷惑你的。 考虑怎么求树的带权重心。 完了我只会树形dp 完了完了 结论&#xff1a;设uuu的子树和为szusz_uszu​&#xff0c;所有点权值和为sss&#xff0c;那么树的带…...

linux基本功系列之hostname实战

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

Easy-Es框架实践测试整理 基于ElasticSearch的ORM框架

文章目录介绍&#xff08;1&#xff09;Elasticsearch java 客户端种类&#xff08;2&#xff09;优势和特性分析&#xff08;3&#xff09;性能、安全、拓展、社区&#xff08;2&#xff09;ES版本及SpringBoot版本说明索引处理&#xff08;一&#xff09;索引别名策略&#x…...

【数据结构】双向链表的模拟实现(无头)

目录 前言&#xff1a; 1、认识双向链表中的结点 2、认识并创建无头双向链表 3、实现双向链表当中的一些方法 3.1、遍历输出方法&#xff08;display&#xff09; 3.2、得到链表的长度&#xff08;size&#xff09; 3.3、查找关键字key是否包含在双链表中(contains) 3.…...

vue自定义指令---处理加载图片失败时出现的碎图,onerror事件

目录 一、自定义指令 1、局部注册和使用 2、全局注册和使用 二、自定义指令处理图片加载失败&#xff08;碎图&#xff09; 一、自定义指令 vue中除v-model、v-show等内置指令之外&#xff0c;还允许注册自定义指令&#xff0c;获取DOM元素&#xff0c;扩展额外的功能。 1、局…...

加盟管理系统挑选法则,看完不怕被坑!

经营服装连锁店铺究竟有多难&#xff1f;小编已经不止一次听到身边的老板&#xff0c;抱怨加盟连锁店铺难以管理了&#xff0c;但同时呢&#xff0c;也听到了很多作为加盟商的老板&#xff0c;抱怨总部给的支持和管理不到位。服装加盟店铺管理&#xff0c;到底有哪些难点呢&…...

alertmanager笔记

1 prometheus的思想 所有告警都应该立刻处理掉&#xff0c;不应该存在长时间未解决的告警。所以具体的表现就是高频的数据采集&#xff0c;和告警的自动恢复&#xff08;默认5分钟&#xff09; 2 alertmanager API调用 使用如下命令即可手工制造告警&#xff0c;注意startsA…...

Android Jetpack组件之WorkManager后台任务管理的介绍与使用(二)

一、介绍 通过上一篇文&#xff0c;Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)_蜗牛、Z的博客-CSDN博客 我们可以弄清楚workmanager从接入到使用的基本流程。基本可以满足我们日常。那只是简单的入门。如果遇到更复杂的功能&#xff0c;那简单的就无法满…...

【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系统调度模块的设计与实现

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

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...