Mokoid是一个简洁的开源项目,从中可以学到android HAL/JNI/framework的实现。
一, HAL层 (hardware\modules\led\Led.c & Led.h)
在HAL最重要的是要有2个结构体:hw_module_t 和 hw_device_t
某个具体的module需要封装这2个结构体,生产自己的结构体:
struct led_module_t {
struct hw_module_t common;
};
struct led_control_device_t {
struct hw_device_t common;
/* attributes */
int fd;
/* supporting control APIs go here */
int (*set_on)(struct led_control_device_t *dev, int32_t led);
int (*set_off)(struct led_control_device_t *dev, int32_t led);
};
----------------------------------
定义自己的模块信息: 这里主要是要定义这个模块支持的一些方法(比如open方法,打开模块,获取相关的操作)
static struct hw_module_methods_t led_module_methods = {
open: led_device_open
};
const struct led_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: LED_HARDWARE_MODULE_ID,
name: "Sample LED Stub",
author: "The Mokoid Open Source Project",
methods: &led_module_methods,
}
/* supporting APIs go here */
};
---------------------------------
static int led_device_open(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
struct led_control_device_t *dev; // 注意这里定义的是led_control_device_t 而led_control_device_t 里面包含了hw_device_t
dev = (struct led_control_device_t *)malloc(sizeof(*dev));
memset(dev, 0, sizeof(*dev));
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = module;
dev->common.close = led_device_close;
dev->set_on = led_on;
dev->set_off = led_off;
*device = &dev->common;
success:
return 0;
}
==================================================
二. JNI层(frameworks\base\service\jni)
1. 暴露给JAVA层的接口定义(framework层可以调用_init, 就是对于到jni层的mokoid_init)
static const JNINativeMethod gMethods[] = {
{ "_init", "()Z",(void *)mokoid_init },
{ "_set_on", "(I)Z", (void *)mokoid_setOn },
{ "_set_off", "(I)Z", (void *)mokoid_setOff },
};
在mokoid_init中, 通过hw_get_module 函数来获取module ( led_module_t* module;), 由于hw_module_t是led_module_t的第一个成员,所以可以强制类型转换。
然后调用module->methods->open(module,
LED_HARDWARE_MODULE_ID, (struct hw_device_t**)device); 来调用HAL层的OPEN函数,获取device
注意, device是一个全局变量:struct led_control_device_t *sLedDevice = NULL;
这样获取到sLedDevice后, 就可以通过这个变量来调用相应的方法(ledOn, ledOff等)。
=====================================================
三,framework层的实现:
public final class LedService extends ILedService.Stub {
static {
System.load("/system/lib/libmokoid_runtime.so");
}
public LedService() {
Log.i("LedService", "Go to get LED Stub...");
_init();
}
/*
* Mokoid LED native methods.
*/
public boolean setOn(int led) {
Log.i("MokoidPlatform", "LED On");
return _set_on(led);
}
public boolean setOff(int led) {
Log.i("MokoidPlatform", "LED Off");
return _set_off(led);
}
// 本地JNI的接口
private static native boolean _init();
private static native boolean _set_on(int led);
private static native boolean _set_off(int led);
}
-------------------
还要实现一个LedManager的管理类
public class LedManager
{
private static final String TAG = "LedManager";
private ILedService mLedService;
public LedManager() {
mLedService = ILedService.Stub.asInterface(
ServiceManager.getService("led"));
if (mLedService != null) {
Log.i(TAG, "The LedManager object is ready.");
}
}
public boolean LedOn(int n) {
boolean result = false;
try {
result = mLedService.setOn(n);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in LedManager.LedOn:", e);
}
return result;
}
public boolean LedOff(int n) {
boolean result = false;
try {
result = mLedService.setOff(n);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in LedManager.LedOff:", e);
}
return result;
}
=============================================
四, 应用层中有一个服务类 , 现实一个framework的LedService实例。
public class LedSystemServer extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onStart(Intent intent, int startId) {
Log.i("LedSystemServer", "Start LedService...");
/* Please also see SystemServer.java for your interests. */
LedService ls = new LedService();
try {
ServiceManager.addService("led", ls);
} catch (RuntimeException e) {
Log.e("LedSystemServer", "Start LedService failed.");
}
}
}
================================================
五, 最上层APP的实现:
public class LedTest extends Activity implements View.OnClickListener {
private LedManager mLedManager = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Start LedService in a seperated process.
startService(new Intent("com.mokoid.systemserver")); // 启动后台服务!!!
Button btn = new Button(this);
btn.setText("Click to turn LED 1 On");
btn.setOnClickListener(this);
setContentView(btn);
}
public void onClick(View v) {
// Get LedManager.
if (mLedManager == null) {
Log.i("LedTest", "Creat a new LedManager object.");
mLedManager = new LedManager(); // 获取一个可以和后台服务通信的管理类
}
if (mLedManager != null) {
Log.i("LedTest", "Got LedManager object.");
}
/** Call methods in LedService via proxy object
* which is provided by LedManager.
*/
mLedManager.LedOn(1); // 通过管理类来具体的操作。
TextView tv = new TextView(this);
tv.setText("LED 1 is On.");
setContentView(tv);
}
}