开发Android硬件访问服务

来源:互联网 发布:mysql select offset 编辑:程序博客网 时间:2024/05/17 05:17

在http://blog.csdn.net/getnextwindow/article/details/47731597中,为Android系统添加了HAL模块,开发好一个硬件抽象层以后,我们通常还需要在应用程序框架中实现一个硬件访问服务。硬件访问服务通过硬件抽象层(HAL)模块来为应用程序提供读写操作。由于硬件抽象层使用c++开发,而应用程序框架中的硬件访问服务是Java语言开发的,因此,硬件访问服务必须通过JNI来调用抽象层模块的接口。

Android系统的硬件访问服务通常运行在系统进程System中,而使用这些硬件访问服务的应用程序运行在另外的进程,所以需要Binder机制实现进程通信。

接下来要开发一个硬件访问服务FregService,它实现了硬件访问服务接口IFregService。首先介绍硬件访问服务接口IFregService的定义,然后介绍硬件访问服务FregService的实现,包括它的内部实现以及调用HAL模块的JNI实现,最后介绍如何在系统进程System中启动硬件访问服务FregService。

1.硬件访问服务接口定义
Android系统使用AIDL定义跨进程访问能力的服务接口,接口文件后缀是aidl,编译系统会将AIDL文件转换成一个Java文件,然后在对他进行编译。本小节将使用AIDL定义IFregService。
在Android4.0+系统中,硬件访问服务接口定义在下面目录中:

 frameworks/base/core/java/android/os/IFregService.aidl

IFregService.aidl定义如下:

1 package android.os;23 interface IFregService {4 void setVal(int val);5 int getVal();6 }

由于服务接口IFregService是使用AIDL语言描述的,因此,我们需要将其添加到编译脚本文件中,这样编译系统才能将其转换成Java文件,然后再对它进行编译。修改的Android.mk文件位于frameworks/base目录下面,对其中的LOCAL_SRC_FILES变量添加如下值:

services/instaboot/java/com/droidlogic/instaboot/IInstabootManager.aidl
LOCAL_SRC_FILES+=\    services/instaboot/java/com/droidlogic/instaboot/IInstabootManager.aidl \    ....

修改完编译脚本之后,我们就可以对服务接口IFregService进行编译了,命令如下:

mmm ./frameworks/base/

编译结果如下:

target Dex: frameworkCopying: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.dextarget Jar: framework (out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/javalib.jar)Install: out/target/product/MagicBox_M13/system/framework/framework.jar

我们看到最终编译出framework.jar文件,这个JAR包中就包含IFregService接口,它继承了android.os.IInterface接口。在IFregService内部定义了一个Binder本地对象Stub,实现了IFregService接口,并且继承了android.os.Binder类。此外,在IFregService.Stub类内部,还定义了一个Binder代理对象proxy,同样实现了IFregService接口。如何确定framework.jar内部是否包含IFregService接口?很简单,android的framework.jar通过反编译工具可以清楚的看到源码,反编译的具体过程在文章http://blog.csdn.net/GetNextWindow/article/details/47748493介绍了。
反编译结果如下:
这里写图片描述

2.实现硬件访问服务
FregService从IFregService.Stub类继承下来,并且实现IFregService接口的成员函数setVal和getVal。
硬件访问服务通常实现在如下目录:

 base/services/java/com/android/server/FregService.java

编译方式:
mmm ./frameworks/base/service/

结果:生成的services.jar文件就包含FregService类。

3.实现硬件访问服务的JNI方法
在Android系统中,硬件访问服务的JNI方法实现在如下目录中:

frameworks/base/services/core/jni/com_android_server_FregService.cpp

完成JNI代码编写以后,我们需要修改:

frameworks/base/services/core/jni/onload.cpp

在里面增加register_android_FregService的声明和调用,onload.cpp文件实现在libandroid_servers模块中,当系统加载libandroid_servers模块的时候,就会调用onload.cpp文件中的JNI_OnLoad函数,这样就将JNI方法注册到了虚拟机当中。

最后还需要修改:

frameworks/base/services/core/jni/Android.mk

修改变量LOCAL_SRC_FILES的值,增加com_android_server_FregService.app。
编译方式:
mmm ./frameworks/base/services
结果:生成的libandroid_servers.so文件中包含了JNI方法

4:启动硬件服务
将硬件服务运行在系统进程System中,需要修改如下文件:

frameworks/base/services/java/com/android/server/SystemServe                   r.java

在其中添加如下代码:

            try {                        Slog.i(TAG, "Freg Service");                        ServiceManager.addService("freg", new FregService());                } catch (Throwable e) {                        Slog.e(TAG, "Failure starting Freg Service", e);                }

编译方式:
mmm ./frameworks/base/services
结果:生成了services.jar文件就包含硬件访问服务FregService,并且在系统启动时,将它运行在系统进程System中。

1 0
原创粉丝点击