Android system property运作流程源码分析

news/2024/10/22 16:50:23/

一.序

前文分析了build.prop这个系统属性文件的生成,每个属性都有一个名称和值,他们都是字符串格式。属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性,这里主要记录在java层或者c++层如果使用,以及整个system_property运作流程。

二.java层调用

源码位于/frameworks/base/core/java/android/os/SystemProperties.java中:

Get属性:
在这里插入图片描述

Set属性:
在这里插入图片描述

都会调用本地接口:
在这里插入图片描述

该接口类在初始化运行环境中注册对应的cpp接口android_os_SystemProperties.cpp,实际操作通过JNI调用的是cpp文件对应的接口:/frameworks/base/core/jni/AndroidRuntime.cpp中:
在这里插入图片描述

/frameworks/base/core/jni/android_os_SystemProperties.cpp中JNI:
在这里插入图片描述

以set属性为例,调用:
在这里插入图片描述
调用到/system/core/libcutils/properties.c中的property_set(key, val)。以java层的理解到这里就OK!

三.c++层的调用

/system/core/libcutils/properties.c中的:
在这里插入图片描述

到/bionic/libc/bionic/system_properties.c中:
在这里插入图片描述

通过一个普通的TCP(SOCK_STREAM)套接字进行通讯:
在这里插入图片描述
以上是作为client端,通过socket向service发送消息。

四.property_service服务的启动

property_service 服务的启动是在android初始化的时候在/system/core/init/init.c时建立:
在这里插入图片描述

由init守护进程分配一个共享内存区来存储这些属性:
property_init()
property_load_boot_defaults()

进程在启动时,会加载动态库bionic libc库
__libc_preinit在bionic libc库加载的时候会被调用
并且通过__libc_preinit(…)——> __libc_init_common(…)——>__system_properties_init();
由/bionic/libc/bionic/system_properties.c中的__system_properties_init()来初始化属性系统的共享内存。
在这里插入图片描述

从property_service_init_action调用到/system/core/init/property_service.c中的启动函数:
在这里插入图片描述

可以看到,在这里加载了系统属性文件到共享内存,文件定义在/bionic/libc/include/sys/_system_properties.h:
在这里插入图片描述

五.property_service服务消息处理

/system/core/init/property_service.c
handle_property_set_fd():
在这里插入图片描述
接收socket请求连接,接收属性请求数,处理信息:
可以看到如果接收到的信息是以“ctl”开头,进行check_control_perms(msg.value, cr.uid, cr.gid, source_ctx)鉴权处理。
这里的传入消息值,发送消息进程的uid以及gid。
在/system/core/include/private/android_filesystem_config.h中有各种权限的定义。
有权限 就执行/system/core/init/init.c中的:
在这里插入图片描述

这个是用来 开启和关闭或者重启服务!

else有权限则执行 /system/core/init/init.c中的:
property_set():
可以看到会判断是否以“ro”字符串开头,如果接收到的消息值,也就是要set的属性值以这个作为开头,就代表只读,不能被改变.
如果共享内存中有则update_prop_info(pi, value, valuelen);没有就保存到内存中。

如果属性是有“net.”字符串开头,当设置这种属性的时候,“net.change”这条属性也会被自动设置,其内容设为最后更新过的属性名,用来记录net.*属性上面的变化。
如果属性是有“persist.”字符串开头,那么就认为是驻留属性,当修改的时候同时也会写进/data/property文件中。
最后调用property_changed(name, value),通知属性已经改变,更新属性,仅仅在运行时可用的属性不需要调用这个方法,除非它们能被数据绑定。
到这里property_service服务已经大体分析完!

六.adb shell 命令

adb shell getprop 列出系统所有属性
adb shell getprop | grep lcd 列出包含lcd的属性
adb shell setprop 修改指定的系统属性

七.属性系统设计

属性系统的上层架构如下图所示:
在这里插入图片描述
Property Service运行在init进程中,开机从属性文件中加载到共享内存中;设置系统属性通过socket与Property Service通信。
Property Consumer进程将存储系统属性值的共享内存,加载到当前进程虚拟空间中,实现对系统属性值的读取。
Property Setter进程修改系统属性,通过socket向Property Service发送消息,更改系统属性值。
属性系统设计的关键就是:跨进程共享内存的实现。

觉得本文对您有用,麻烦点赞、关注、收藏,您的肯定是我创作的无限动力,谢谢!!!


http://www.ppmy.cn/news/1455040.html

相关文章

【企业动态】爱尔兰客户到访东胜物联,共拓能源管理等解决方案

近日,来自爱尔兰的房屋数据监测客户莅临东胜物联(杭州黄龙国际中心)进行参观考察,双方就未来的广泛合作进行了深入的沟通交流。 来访期间,东胜物联CEO支江峰先生热情接待了客户,并陪同他们参观了产品展厅&…

欢乐钓鱼大师脚本,游戏托管一键操作!

欢迎来到《钓鱼大师乐趣无穷》!这里是一片充满了乐趣和挑战的钓鱼天地。不论你是刚刚入门的小白,还是已经成为老手的大神,本攻略将为你揭示如何在游戏中获得成功,并针对稀有鱼类的钓鱼技巧进行详细介绍。 一、初探钓鱼的乐趣 在《…

数据结构 栈实现队列

题目描述: 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): 实现 MyQueue 类: void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素i…

Costas-Barker序列模糊函数仿真

文章目录 前言一、Costas 序列二、Barker 码三、Costas-Barker 序列模糊函数仿真1、MATLAB 核心代码2、仿真结果①、Costas-Barker 模糊函数图②、Costas-Barker 距离模糊函数图③、Costas-Barker 速度模糊函数图 四、资源自取 前言 Costas 码是一种用于载波同步的频率调制序列…

深入探讨SOCKS5代理:安全、隐私与技术实现

在当今的数字化世界中,网络安全和隐私已成为热门话题。企业和个人都在寻求更安全的方式来保护其数据和通信。在众多解决方案中,SOCKS5代理因其独特的功能和强大的灵活性而脱颖而出。本文将深入探讨SOCKS5代理的工作原理,其与HTTP代理的区别&a…

Java二维码、条码生成及解码工具类

功能描述 生成二维码、条码解码使用谷歌的zxing依赖 引入依赖 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version> </dependency><dependency><groupId>…

集合定义和使用方法

一.集合的长度 集合的长度,可以添加和删除,长度也会跟着去发生改变,数组一旦创建完成他的长度就不会发生改变。 二.集合的定义方式 ArrayList<String> list new ArrayList(); 三.集合能存储的数据类型 集合能够存储引用数据类型,存储基本数据类型需要使用包装类: 四…

Golang | Leetcode Golang题解之第70题爬楼梯

题目&#xff1a; 题解&#xff1a; func climbStairs(n int) int {sqrt5 : math.Sqrt(5)pow1 : math.Pow((1sqrt5)/2, float64(n1))pow2 : math.Pow((1-sqrt5)/2, float64(n1))return int(math.Round((pow1 - pow2) / sqrt5)) }