当前位置 主页 > 服务器问题 > Linux/apache问题 >
注册后, 如果你在App里面通过 getSystemService(SystemEventManager.SERVICE); 获取Manager并调用接口, 会发现又会出错, 又是Selinux权限问题:
E SELinux : avc: denied { find } for service=test_systemevent pid=4123 uid=10035 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:test_systemevent_service:s0 tclass=service_manager permissive=0
说是没有 find 权限, 因此又要加权限, 修改代码如下:
system/sepolicy/untrusted_app.te
# 允许 untrusted_app 查找 test_systemevent_service allow untrusted_app test_systemevent_service:service_manager find;
这个 Selinux 的知识有兴趣自己去学一下, 报了什么权限, 就按照错误信息去对应文件添加权限.
至此, 系统代码修改完成了, 编译系统刷机, 下面通过App调用.
七、App调用
文件拷贝和准备:
我们需要复制三个文件到App中, 两个AIDL文件, 一个Manager文件:
IEventCallback.aidl
ISystemEvent.aidl
SystemEventManager.java
所有AIDL文件和java文件, 在App工程中的包名和路径都需要和系统保持一致, 这三个文件App不能做任何修改, 除非系统源码中也做对应修改, 总的来说, 这三个文件App和系统中要完全保持一致, 类名包名和包路径都需一致, 复制这三个文件到工程中后, 编译后, 调用方式如下.
获取服务:
SystemEventManager eventManager = (SystemEventManager) context.getSystemService(SystemEventManager.SERVICE);
这里Android Studio可能会报 getSystemService() 参数不是Context里面的某个服务的错误, 可以直接忽略, 不影响编译.
注册/取消注册:
eventManager.register(eventCallback); eventManager.unregister(eventCallback); private IEventCallback.Stub eventCallback = new IEventCallback.Stub() { @Override public void onSystemEvent(int type, String value) throws RemoteException { Log.d("SystemEvent", "type:" + type + " value:" + value); } };
调用:
eventManager.sendEvent(1, "test string");
测试Log如下:
D SystemEventManager: SystemEventManager init
D SystemEventService: register pid:3944 uid:10035 result:true
D SystemEventService: remote callback count:1
D SystemEvent: type:1 value:test string remote
D SystemEventService: unregister pid:3944 uid:10035 result:true
可以看到调用了服务端并成功收到服务端拼接的字符串.
八、添加JNI部分代码
我们一般添加系统服务, 可能是为了调用驱动里面的代码, 所有一般要用JNI部分代码, 这里不是讲怎么编写JNI代码, 而是说下系统服务中已有的JNI代码, 我们可以直接在这基础上增加我们的功能.
JNI部分代码位置为:
frameworks/base/services/core/jni/
编译对应mk为:
frameworks/base/services/Android.mk
frameworks/base/services/core/jni/Android.mk
此部分代码直接编译为 libandroid_servers 动态库, 在SystemServer进行加载:
frameworks/base/services/java/com/android/server/SystemServer.java