安卓系统属性persist类型prop深入剖析

背景:

近来学员朋友在群里问道了prop属性值进行持久化存储相关的问题,针对prop大部分情况下都是在代码端进行get获取读取操作,因为很多系统属性都是ro类型的,即不可以修改的,有一些debug可以修改的属性,但修改重启又变成了空,所以有是否可以持久化存储的prop,并且可读可写这种,那么就是今天要讲解的persist属性
在这里插入图片描述

persist属性源码分析:

源码位置:
system/core/init/property_service.cpp


static std::optional<uint32_t> PropertySet(const std::string& name, const std::string& value,SocketConnection* socket, std::string* error) {//省略// Don't write properties to disk until after we have read all default// properties to prevent them from being overwritten by default values.if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {(1)if (persist_write_thread) {persist_write_thread->Write(name, value, std::move(*socket));(2)return {};}WritePersistentProperty(name, value);}NotifyPropertyChange(name, value);return {PROP_SUCCESS};
}

上面代码(1)就会判断setprop的key是不是带了persist开头的属性,如果是persist开头,接下来判断persist_write_thread线程是否不为null,如果不为null则调用persist_write_thread->Write进行持久化写入。

void PersistWriteThread::Write(std::string name, std::string value, SocketConnection socket) {{std::unique_lock<std::mutex> lock(mutex_);work_.emplace_back(std::move(name), std::move(value), std::move(socket));}cv_.notify_all();//唤醒操作
}void PersistWriteThread::Work() {while (true) {std::tuple<std::string, std::string, SocketConnection> item;// Grab the next item within the lock.{std::unique_lock<std::mutex> lock(mutex_);while (work_.empty()) {//一直循环判断队列是否为空cv_.wait(lock);}item = std::move(work_.front());work_.pop_front();}std::this_thread::sleep_for(1s);// Perform write/fsync outside the lock.WritePersistentProperty(std::get<0>(item), std::get<1>(item));//写入到文件NotifyPropertyChange(std::get<0>(item), std::get<1>(item));SocketConnection& socket = std::get<2>(item);socket.SendUint32(PROP_SUCCESS);}
}

可以看到最后是在独立线程中调用WritePersistentProperty进行写入属性到文件

// Persistent properties are not written often, so we rather not keep any data in memory and read
// then rewrite the persistent property file for each update.
void WritePersistentProperty(const std::string& name, const std::string& value) {//省略if (auto result = WritePersistentPropertyFile(*persistent_properties); !result.ok()) {//真正写入到文件LOG(ERROR) << "Could not store persistent property: " << result.error();}
}

这里又是调用WritePersistentPropertyFile写入到文件

Result<void> WritePersistentPropertyFile(const PersistentProperties& persistent_properties) {const std::string temp_filename = persistent_property_filename + ".tmp";unique_fd fd(TEMP_FAILURE_RETRY(open(temp_filename.c_str(), O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0600)));std::string serialized_string;if (!persistent_properties.SerializeToString(&serialized_string)) {return Error() << "Unable to serialize properties";}if (!WriteStringToFd(serialized_string, fd)) {return ErrnoError() << "Unable to write file contents";}fsync(fd.get());fd.reset();if (rename(temp_filename.c_str(), persistent_property_filename.c_str())) {int saved_errno = errno;unlink(temp_filename.c_str());return Error(saved_errno) << "Unable to rename persistent property file";}// rename() is atomic with regards to the kernel's filesystem buffers, but the parent// directories must be fsync()'ed otherwise, the rename is not necessarily written to storage.// Note in this case, that the source and destination directories are the same, so only one// fsync() is required.auto dir = Dirname(persistent_property_filename);auto dir_fd = unique_fd{open(dir.c_str(), O_DIRECTORY | O_RDONLY | O_CLOEXEC)};if (dir_fd < 0) {return ErrnoError() << "Unable to open persistent properties directory for fsync()";}fsync(dir_fd.get());return {};
}

这里的文件路径是

std::string persistent_property_filename = "/data/property/persistent_properties";

所以persist的属性最后都可以去/data/property/persistent_properties查看

在这里插入图片描述
不过经过了序列化了,可读性不是那么好。

实战过程:

实战主要有以下几个地方修改
1、代码定义和写入

这里需要system_server进程和app进程都可以进行写入

system_server进行写入
在这里插入图片描述

系统app写入在这里插入图片描述

2、selinux部分
这个selinux部分是最核心的部分,一般写新的persist最好不要完全自己新定义一个prop,完全可以采用报现在有的prop已经定义好的selinux的大腿,这里因为persist.sys本身就是被定义好了相关的标签:

./prebuilts/api/33.0/private/property_contexts:72:persist.sys.            u:object_r:system_prop:s0

可以看到只要是persist.sys. 开头的都是定义为了system_prop,所以system_server进程写入数据等都不需要额外编写,因为直接有的。

./private/system_server.te:701:set_prop(system_server, system_prop)

唯一要额外编写的就是针对系统app这种,这个就需要额外写一点selinux,这里主要针对platform_app这种签名app
private/platform_app.te

diff --git a/private/platform_app.te b/private/platform_app.te
index 44de21c25..43d398b04 100644
--- a/private/platform_app.te
+++ b/private/platform_app.te
@@ -106,6 +106,7 @@ allow platform_app system_server:udp_socket {# allow platform apps to connect to the property serviceset_prop(platform_app, test_boot_reason_prop)
+set_prop(platform_app, system_prop)# allow platform apps to read keyguard.no_require_simget_prop(platform_app, keyguard_config_prop)
test@test:~/disk2/nx563j_aosp14/system/sepolicy

prebuilts/api/34.0/private/platform_app.te

diff --git a/prebuilts/api/34.0/private/platform_app.te b/prebuilts/api/34.0/private/platform_app.te
index 44de21c25..43d398b04 100644
--- a/prebuilts/api/34.0/private/platform_app.te
+++ b/prebuilts/api/34.0/private/platform_app.te
@@ -106,6 +106,7 @@ allow platform_app system_server:udp_socket {# allow platform apps to connect to the property serviceset_prop(platform_app, test_boot_reason_prop)
+set_prop(platform_app, system_prop)# allow platform apps to read keyguard.no_require_simget_prop(platform_app, keyguard_config_prop)

验证如下:
可以看出reboot后persist.sys.test.value1的值还是value-2
在这里插入图片描述
看看data/property/persistent_properties下面是否有保存在这里插入图片描述
在这里插入图片描述
在底部确实存在persist.sys.test.value1为value-2的prop

更多framework详细代码和资料参考如下链接
投屏专题部分:

https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg

hal+perfetto+surfaceflinger

https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

参考相关链接:
https://blog.csdn.net/zhimokf/article/details/137958615

更多framework假威风耗:androidframework007

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

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

相关文章

GC9008为什么能替代MX6208应用于红外开关,电流开关上

GC9008作为一种新型集成电路&#xff0c;具备了多个方面的优势&#xff0c;使其能够有效替代MX6208。以下是GC9008替代MX6208的主要原因及其优势&#xff1a; 1. 更低的功耗 优势&#xff1a;GC9008在设计上进行了优化&#xff0c;能够在更低的电压下运行&#xff0c;从而显著…

Android Compose 控件基本属性

本文的代码由上一篇文章的Demo进一步书写完成, 传送门:Android Compose的基本使用-CSDN博客 _____________________________________________________________________________ 以下代码分别列举了控件的: 内边距,外边距,内容居中,渐变自定义边框,宽度权重,string资源引用等…

JVM 内存模型与垃圾回收过程详解

JVM 内存模型与垃圾回收过程详解 文章目录 JVM 内存模型与垃圾回收过程详解1. JVM内存分区1.1 具体分区1.2 JVM内存分区的必要性 2. 垃圾回收2.1 CMS垃圾回收器2.2 G1垃圾回收器2.3 JVM垃圾回收从新生代到老年代 1. JVM内存分区 1.1 具体分区 Java虚拟机&#xff08;JVM&#…

Ubuntu 18.04安装storcli查看阵列信息

rootCeph03:/opt/MegaRAID/storcli# cat /etc/issue Ubuntu 18.04.5 LTS \n \l 准备好storcli的安装包 解压 解压之后可以看到 根据系统版本选择 把storcli_1.18.11_all.deb包传到服务器 使用命令dpkg -I storcli_1.18.11_all.deb ./storcli64 show ./storcli64 /c1 show …

Nuxt3哔哩哔哩移动端项目实战

Nuxt3 - 哔哩哔哩 - 项目实战 简介 Nuxt 框架提供了一种基于 Node.js 的服务端渲染方案 SSR&#xff08;Server Side Rendering&#xff09;&#xff0c;可以让 Vue 应用在服务器端进行渲染&#xff0c;从而提高页面的加载速度和 SEO。 项目预览 在线预览 https://bilibil…

室内人行与导航系统有哪些多样化的功能?

在现代化建筑的迷宫中&#xff0c;室内人行与导航系统如同一位无形的向导&#xff0c;引领我们穿梭于复杂的空间之中&#xff0c;极大地提升了人们在室内环境中的便捷性和安全性。这一技术领域的飞速发展&#xff0c;不仅体现在定位精度的提升上&#xff0c;更在于其多样化的功…

基于卷积神经网络的书法字体识别系统,resnet50,mobilenet模型【pytorch框架+python】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; 基于卷积神经网络的书法字体识别系统&#xff0c;resnet50&#xff0c;mobilenet【pytorch框架&#xff0c;python&#xff0c;tkinter】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷…

台球助教预约小程序源码开发:技术解析与示例代码

随着数字化时代的到来&#xff0c;信息技术与体育运动的融合日益紧密。台球作为一项深受大众喜爱的运动&#xff0c;其教学训练领域也迎来了技术创新的浪潮。本文将探讨台球助教预约小程序的开发过程&#xff0c;从技术选型、功能设计到示例代码展示renxb001&#xff0c;全面解…

ComfyUI | 高清出图+艺术字+文字直出工作流(附工作流)

今天给大家带来一个可以直接打字的工作流&#xff0c;非常适合设计师使用&#xff01;拒接二次修改&#xff01;轻松上手设计&#xff0c;无需Photoshop技能&#xff0c;直接输入文字即可&#xff0c;操作极为简便&#xff0c;极大提升工作效率。 以国庆海报为例 庆祝75周年国…

搭建Serverless社交媒体分析平台,Dataxet运维成本降低50%

社交媒体平台发展如火如荼&#xff0c;据相关机构统计&#xff0c;2024年全球社交媒体活跃用户已占全球人口总数约62.5%。亚洲知名智能媒体公司Dataxet意识到社交媒体数据分析潜在商业价值&#xff0c;即推出全新的社交媒体分析平台DTX360&#xff0c;用于提供媒体监测、社交网…

Canvas:AI协作的新维度

在人工智能的浪潮中&#xff0c;OpenAI的最新力作Canvas&#xff0c;不仅是一款新工具&#xff0c;它标志着人工智能协作方式的一次革命性飞跃。Canvas为写作和编程提供了一个全新的交互界面&#xff0c;让用户能够与ChatGPT进行更紧密、更直观的协作。 ​​​​​​​ Canvas的…

危房安全监测系统解决方案

一、危房产生原因 1、地基因滑移,或因承载力严重不足,或因其他特殊地质原因,导致不均匀沉降引起结构明显倾科、位移、裂缝、扭曲等,并有继续发展的趋势。 2、地基因毗邻建筑增大荷载,或因自身局部加层增大荷载,或因其他人为因素,导致不均匀沉降,引起结构明显倾料、位移、裂缝…

linux安装Go ImageMagick插件

ImageMagick安装 在程序中需要对图片转化时需要使用到gopkg.in/gographics/imagick.v2/imagick库&#xff0c;但是这个库需要在本地安装ImageMagick插件。 有些机器在软件库是有的&#xff0c;可以直接下载安装&#xff0c;没有的话推荐源码安装。 ImageMagick中文站 ImageM…

Spring Boot学习资源库:Java开发者的新篇章

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…

张驰咨询:企业管理难题?精益六西格玛培训公司有‘秘籍’!

在当今这个快速变化、竞争激烈的市场环境中&#xff0c;企业要想持续保持竞争优势&#xff0c;就必须不断追求效率与质量的双重提升。而精益六西格玛作为一种集精益生产与六西格玛管理于一体的先进管理理念和工具&#xff0c;正成为越来越多企业转型升级的首选。在这样的背景下…

Springboot3+druid+jasypt+application.yml配置文件数据库密码加密技术

说明 开发环境我们经常把数据库密码直接明文暴露在配置文件中,但是在生产环境,出于安全考虑,必须对数据库密码进行加密。 Jasypt是一个简单易用的Java加密工具库。Jasypt支持多种加密算法,如AES、SHA512、AES_256等,以适应不同的安全需求,可以轻松将加密技术应用于配置…

JavaScript 入门基础 第1章

第一部分&#xff1a;入门篇 第1章&#xff1a;JavaScript 基础 JavaScript 是什么&#xff1f; JavaScript 是一种广泛使用的脚本语言&#xff0c;主要用于Web开发&#xff0c;为网页添加交互功能。它是一种解释型语言&#xff0c;可以在客户端&#xff08;浏览器&#xff0…

重学SpringBoot3-集成Redis(九)之共享Session

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;九&#xff09;之共享Session 1. 为什么需要 Session 共享2. Spring Session 和 Redis 的集成2.1. 引入依赖2.2. 配置 Redis 连接…

猿人学— 第一届第1题(解题思路附源码)

猿人学 — 第一届第1题&#xff08;解题思路附源码&#xff09; F12进入开发者工具—> 发现停止在debugger处 —> 右键点击Never pause here后下一步 翻页&#xff0c;抓包后发现请求携带page和m两个参数&#xff0c;page应该就是页数&#xff0c;m则需要逆向 依次查…

《深度学习》循环神经网络RNN 结构及原理解析

目录 一、关于RNN 1、传统神经网络存在的问题 2、什么是循环神经网络 3、RNN特点 二、RNN基本结构 1、RNN基本结构 2、推导方式 注意&#xff1a; 3、循环的由来 4、RNN的局限性 一、关于RNN 1、传统神经网络存在的问题 无法训练出具有顺序的数据&#xff0c;模型搭…