您的位置:首页 > 移动开发 > Android开发

【原创】Android HAL的理解-----Mokoid代码走读

2013-03-29 11:14 591 查看
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: