Framework提供接口访问硬件

上一章,我们理解了如何写一个JNI方法来访问HAL层的接口,这个JNI的方法最终是被Android Framework来进行调用,Android Framework最终又被Android的应用软件进行调用,从而实现从可视应用程序访问驱动寄存器的通路。本章我们一起来学习如何在Android Framework层来写接口供可视应用程序访问,并且访问JNI的接口。

1.新建AIDI代理

服务一般是运行在一个独立的进程中来为各个应用程序提供服务,因此应用程序需要访问服务的接口,就需要通过代理来试下,Android中主要通过AIDI代理实现。
创建方法:

cd /frameworks/base/core/java/android/os
vim IHelloService.aidl

IHelloService.aidl定义了IHelloService接口:

1
2
3
4
5
6
package android.os;

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

这个接口定义了setVal\getVal两个函数,用来读写设备的寄存器的值。

2.修改编译环境

cd framework/base
修改Android.mk

在下面一行后面添加黑体内容:

1
2
3
...
core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
core/java/android/os/IHelloService.aidl \

3.编译aidl

mmm framework/base

系统会根据IHelloService.aidl来生成IHelloService.Stub接口

4.新增服务java文件

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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来提供硬件服务。

5.修改service启动

修改frameworks/base/services/java/com/android/server目录,新增HelloService的SystemServer.java文件,在ServerThread::run函数中增加加载HelloService的代码:

1
2
3
4
5
6
7
...
try {
Slog.i(TAG, "DiskStats Service");
ServiceManager.addService("diskstats", new DiskStatsService(context));
} catch (Throwable e) {
reportWtf("starting DiskStats Service", e);
}

在这个代码后面添加如下代码:

1
2
3
4
5
6
try {
Slog.i(TAG, "Hello Service");
ServiceManager.addService("hello", new HelloService());
} catch (Throwable e) {
reportWtf("starting Hello Service", e);
}

6.编译和打包

mmm frameworks/base/services/java
make snod

重新生成后的system.img中就包含了我们自定义的HelloService,可以供JAVA的可视应用程序调用,最终访问Hello驱动,并实现寄存器值的读写。

注:代码程序主要参考《老罗的Android之旅》来完成。

Tianger Ge wechat
如果您喜欢这篇文章,欢迎扫一扫我的微信公众号!