HengFeng

--博观而约取,厚积而薄发
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

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

Posted on 2013-03-29 11:14  hengfeng  阅读(753)  评论(0编辑  收藏  举报

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);
    }
}