Android的硬件访问服务运行在system中,而使用硬件访问服务的应用程序运行在另外的进程中,所以应用程序要通过进程间通信机制(Binder进程间通信机制)来访问这些硬件访问服务;Binder进程间通信机制要求提供服务的一方必须实现一个具有跨进程访问能力的服务接口。
AIDL:Android系统通过接口描述语言(AIDL)来定义具有具有跨进程访问能力的服务接口,后缀名为aidl,编译时会将它转换成Java文件,然后再进行编译。所以我们将使用AIDL来定义硬件访问接口
frameworks/base/core/java/android/os/IDemoService.aidl
package android.os;
interface IDemoService{
void setVal(int val);
int getVal();
}
注意:该方法中注意要添加/** @hide */,否则编译会报错,提示更新更新API(如下).加了hide相当于不对外公开,就不需要更新API
You have tried to change the API from what has been previously approved.
To make these errors go away, you have two choices:
-
You can add “@hide” javadoc comments to the methods, etc. listed in the
errors above. -
You can update current.txt by executing the following command:
make update-apiTo submit the revised current.txt to the main Android repository,
you will need approval.
把IDemoService.aidl添加到脚本文件中
frameworks/base/Android.mk
LOCAL_SRC_FILES += \
...
core/java/android/os/IDemoService.aidl \
编译:mmm frameworks/base/
添加系统服务代码
frameworks/base/services/core/java/com/android/server/DemoService.java:
package com.android.server;
import android.content.Context;
import android.os.IDemoService;
import android.util.Slog;
public final class DemoService extends IDemoService.Stub {
private static final String TAG = "DemoService";
private int mPtr = 0;
DemoService() {
mPtr = init_native();
if(mPtr == 0){
Slog.e(TAG, "failed to init IDemoService");
}
}
public void setval(int val) {
if(mPtr == 0){
Slog.e(TAG, "IDemoService is not inited ");
return;
}
setVal_native(mPtr , val);
}
public int getval() {
if(mPtr == 0){
Slog.e(TAG, "IDemoService is not inited ");
return;
}
return getVal_native(mPtr);
}
private static native int init_native();
private static native void setVal_native(int Ptr , int val);
private static native int getVal_native(int Ptr);
}
调用native方法,实现对dev/demo的读写操作.
编译:mmm frameworks/base/services/core/java/com/android/server/
配置selinux权限
在device.te文件中添加:
type demo_device, dev_type;
在domain.te文件中添加
allow domain demo_device:chr_file rw_file_perms;
在file_contexts文件中添加
/dev/demo u:object_r:freg_device:s0
在service.te中文件中添加
type demo_service, system_api_service, system_server_service, service_manager_type;
在service_contexts文件中添加
demo u:object_r:demo_service:s0
在system_server.te文件中添加
allow system_server demo_device:chr_file rw_file_perms;
在untrusted_app.te文件中添加
allow untrusted_app freg_service:service_manager find;
在system_app.te文件中添加
allow system_app demo_service:service_manager find;
参考blog:在/dev下添加新设备驱动下Selinux相关设置
启动硬件访问服务
在’frameworks/base/services/java/com/android/server/SystemServer.java’中的startOtherServices()添加如下代码:
try {
Slog.i(TAG, "Demo service");
ServiceManager.addService("demo", new DemoService());
} catch (Throwable e) {
Slog.e(TAG, "failure starting Demo service", e);
}
把new的实例DemoService注册到ServiceManager,取名:demo
最后重新编译Service,打包镜像:
mmm frameworks/base/services/
make snod