failed to set system property

Android SystemProperties


概述

  在对Android操作系统进行开发的过程中,经常需要使用到Android的隐藏API SystemProperties.set(String key, String value) 这个接口,写入一些属性值存放到系统共享内存,配合SystemProperties.get(String key) 这个接口可以很方便的实现某些功能。由于是android:sharedUserId=“android.uid.system” 的系统级应用,有权限操作类似的隐藏接口。比如可以定义一个persist.test.meid 的属性来保存系统的MEID号,以方便第三方应用开发者获取。

  在Android5.0之前,系统级应用可以很方便的写入规范(比如属性key、value的长度有一定限制等)的属性,在这之后,Android系统引入了SELinux,所有的操作都有相应的权限组,任意写入一个属性也会抛出错误,即使是系统级应用。

  关于Android SystemProperty 的分析文章,网上一搜一大堆,推荐一篇分析的很全的博客:https://blog.csdn.net/yangwen123/article/details/8936555 ,这里我只分析SystemProperties.set(String key, String value) 失败的原因以及解决办法。

错误信息

就以persist.test.meid 这个属性做实验,在android:sharedUserId=“android.uid.system” 的进程中调用接口:

import android.os.SystemProperties;

SystemProperties.set("persist.test.meid", "test value");

运行程序,写入属性失败,查看log发现抛出如下异常:

12-06 14:22:19.254  2870  2887 W libc    : Unable to set property "persist.test.meid" to "test value": error code: 0x18
12-06 14:22:19.255  2870  2887 E JavaBinder: *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
12-06 14:22:19.255  2870  2887 E JavaBinder: java.lang.RuntimeException: failed to set system property
12-06 14:22:19.255  2870  2887 E JavaBinder: 	at android.os.SystemProperties.native_set(Native Method)
12-06 14:22:19.255  2870  2887 E JavaBinder: 	at android.os.SystemProperties.set(SystemProperties.java:155)
12-06 14:22:19.255  2870  2887 E JavaBinder: 	at com.action.tool.mdm.provider.ActionMdmProvider.tv(:251)
12-06 14:22:19.255  2870  2887 E JavaBinder: 	at com.action.tool.mdm.provider.ActionMdmProvider.call(:109)
12-06 14:22:19.255  2870  2887 E JavaBinder: 	at android.content.ContentProvider$Transport.call(ContentProvider.java:401)
12-06 14:22:19.255  2870  2887 E JavaBinder: 	at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:272)
12-06 14:22:19.255  2870  2887 E JavaBinder: 	at android.os.Binder.execTransact(Binder.java:697)
12-06 14:22:19.256  3882  3882 D AndroidRuntime: Shutting down VM

原因分析

错误日志中提示Uncaught remote exception! (Exceptions are not yet supported across processes.),这是一个常见的跨进程通讯失败信息,没什么卵用。后来发现系统中工厂测试这个系统级应用能写persist.sys.xxx这样的属性,于是在我的应用中也写了这条属性,发现是能成功的,而persist.test.meid 还是写入失败。
那么这两条属性有什么区别呢?唯一的却别就是persist.sys.xxx这样的属性是系统里预先定义好的,而persist.test.meid 是自己随手定义的,那么persist.sys.xxx肯定是在系统某个地方做了某些设定。
有了这个推测后就是查找了,使用grep “persist.sys.” -rn . 搜索整个代码,最后定位到SELinux
property_contexts文件中的代码片段:

persist.netd.stable_secret      u:object_r:netd_stable_secret_prop:s0
persist.sys.            u:object_r:system_prop:s0
persist.sys.safemode    u:object_r:safemode_prop:s0

解决方案

只需要在property_contexts文件中添加权限声明即可

persist.test.       u:object_r:system_prop:s0

由于我们应用进程是属于 system uid的系统级应用,所有声明的属性所属域为system_prop
当然也可以自定义一个域,然后将persist.test.定义到这个新的域中,最后自己的应用程序就不能是android:sharedUserId=“android.uid.system” 了,而是要定义成自己的所属域。


上一篇 一键设置DeviceOwner
发布了25 篇原创文章 · 获赞 31 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/visionliao/article/details/84881233