Android 驱动之旅 第五章: 在Android 系统的应用程序框架层增加硬件服务接口

时间:2021-02-27 03:39:53

在数字科技日新月异的今天,软件和硬件的完美结合,造就了智能移动设备的流行。今天大家对iOS 和Android 系统的趋之若鹜,一定程度上是由于这两个系统上有着丰富多彩的各种应用软件。因此,软件和硬件的关系,在一定程度上可以说,硬件是为软件服务的。硬件工程师研发出一款硬件设备,自然少了软件工程师为其编写驱动程序;而驱动程序的最终目的,是为了使得最上层的应用程序能够使用这些硬件提供的服务来为用户提供软件功能。对Android 系统上的应用软件来说,就是要在系统的Application Frameworks 层为其提供硬件服务。在前面的几篇文章中,我们着重介绍了Linux 内核层、硬件抽象层和运行时库层提供的自定义硬件服务接口,这些接口都是通过C 或者C++语言来实现的。在这一篇文章中,我们将介绍如何在Android 系统的Application Frameworks 层提供Java 接口的硬件服务。

一. 参照在Ubuntu 为Android 硬件抽象层(HAL)模块编写JNI 方法提供Java 访问硬件服务接口一文所示,为硬件抽象层模块

准备好JNI 方法调用层。

二. 在Android 系统中,硬件服务一般是运行在一个独立的进程中为各种应用程序提供服务。因此,调用这些硬件服务的应用

程序与这些硬件服务之间的通信需要通过代理来进行。为此, 我们要先定义好通信接口。

step1: 进入到frameworks/base/core/java/android/os 目录,新增IHelloService.aidl 接口定义文件:

package Android.os;

interface IHelloService
{
void setVal(int val);
int getVal();
}

step2: 返回到frameworks/base 目录,打开Android.mk 文件,修改LOCAL_SRC_FILES 变量的值,增加IHelloService.aidl 源文件

LOCAL_SRC_FILES += /
core
/java/Android/os/IVibratorService.aidl /
core
/java/Android/os/IHelloService.aidl /
core
/java/Android/service/urlrenderer/IUrlRendererService.aidl /

step3: 编译IHelloService.aidl 接口:

linuxidc@www.linuxidc.com:~/Android$ mmm frameworks/base。 这样,就会根据IHelloService.aidl 生成相应的IHelloService.Stub 接口

step4: 进入到frameworks/base/services/java/com/Android/server 目录,新增HelloService.java 文件:

package com.Android.server;

import Android.content.Context;
import Android.os.IHelloService;
import Android.util.Slog;

public class HelloService extends IHelloService.Stub {
private static final String TAG = "HelloService";

HelloService()
{
init_native();
}

public void setVal(int val)
{
setVal_native(val);
}

public int getVal()
{
return getVal_native();
}

private static native boolean init_native();
private static native void setVal_native(int val);
private static native int getVal_native();

};

HelloService 主要是通过调用JNI 方法init_native、setVal_native 和getVal_native(见在Ubuntu 为Android 硬件抽象层(HAL)模块编写JNI 方法提供Java 访问硬件服务接口一文)来提供硬件服务。

step5: 修改同目录的SystemServer.java 文件,在ServerThread::run 函数中增加加载HelloService 的代码

 

 

@Override
public void run() {
try {
Slog.i(TAG,
"DiskStats Service");
ServiceManager.addService(
"diskstats", new DiskStatsService(context));
}
catch (Throwable e) {
Slog.e(TAG,
"Failure starting DiskStats Service", e);
}
try {
Slog.i(TAG,
"Hello Service");
ServiceManager.addService(
"hello", new HelloService());
}
catch (Throwable e) {
Slog.e(TAG,
"Failure starting Hello Service", e);
}
}

 

 

step6: 编译HelloService 和重新打包system.img:

linuxidc@www.linuxidc.com:~/Android$ mmm frameworks/base/services/java

linuxidc@www.linuxidc.com:~/Android$ make -j16

这样,重新打包后的system.img 系统镜像文件就在Application Frameworks 层中包含了我们自定义的硬件服务HelloService了,并且会在系统启动的时候,自动加载HelloService。这时,应用程序就可以通过Java 接口来访问Hello 硬件服务了。我们将 在下一篇文章http://www.linuxidc.com/Linux/2011-07/38983.htm中描述如何编写一个Java 应用程序来调用这个HelloService接口来访问硬件。