zoukankan      html  css  js  c++  java
  • 【原创】Android HAL的理解Mokoid代码走读

    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);
        }
    }
     
     
     
  • 相关阅读:
    leetcode刷题29
    leetcode刷题28
    leetcode刷题27
    leetcode刷题23
    leetcode刷题22
    leetcode刷题21
    leetcode刷题20
    Unity中通过DoTween实现转盘效果
    U3D工作注意事项,不要再犯!
    Unity中String字符串的优化
  • 原文地址:https://www.cnblogs.com/hengfeng/p/2988505.html
Copyright © 2011-2022 走看看