Android Mokoid Open Source Project hacking

/*****************************************************************************
 *                Android Mokoid Open Source Project hacking
 *
 * 声明:
 *     1. 本文主要是为了了解Android HAL工作机制,从而决定分析mokoid开源项目;
 *     2. 源代码URL:https://code.google.com/p/mokoid/source/checkout;
 *     3. 本文通过从应用层-->HAL层逐层跟踪的方式进行代码分析,是为了得到整个
 *         Android框架的调用流程体系以及存在的原因;
 *     4. 本人在也在网上找了一些分析资料,无法从中找到连贯的思绪,于是决定
 *         自己整这个符合自己的思维习惯的代码解析,如果看你这些觉得难受,
 *         那就也自己动手分析,别人的终归是别人的,自己的才是自己的;
 *     5. Demo 1 重要的调用访问线路图:
 *         onCreate() <-- LedClient.java                      实现接口          aidl工具生成接口        接口定义
 *             _init() <-- new LedService() <-- LedService.java <== ILedService.Stub <-- ILedService.aidl <-- <interface>ILedService
 *                 hw_get_module() <-- mokoid_init() <-- com_mokoid_server_LedService.cpp
 *                     hardware.c <-- hardware.h
 *                         led.c <-- led.h
 *     6. Demo 2 重要的调用访问线路图:
 *         onCreate() <-- LedTest.java
 *             startService() <-- "com.mokoid.systemserve" <-- AndroidManifest.xml
 *                 new LedService()<-- LedSystemServer.java
 *                     hw_get_module() <-- mokoid_init() <--com_mokoid_server_LedService.cpp
 *                         hardware.c <-- hardware.h
 *                             led.c <-- led.h
 *                     ServiceManager.addService()<-- LedSystemServer.java
 *             LedManager.java
 *                 ILedService.Stub.asInterface() <-- ServiceManager.getService() <-- LedManager() <-- LedService.java <== ILedService.Stub <-- ILedService.aidl <-- <interface>ILedService
 *                     <interface>ILedService
 *                         这个接口对应上面的new LedService()实例,所以可以直接调用。
 *
 *                                   2015-6-27 晴 深圳 南山平山村 曾剑锋
 ****************************************************************************/

            \\\\\\\\\\\\\\\\\\\\\\\-*- 目录 -*-/////////////////////
            |  参考文章:
            |  一、代码工程文件架构:
            |  二、Demo 1 LedClient.java 跟踪:
            |  三、Demo 1 LedService.java 跟踪:
            |  四、Demo 1 ILedService.aidl 跟踪:
            |  五、Demo 1 Android.mk 跟踪:
            |  六、Demo 1 com_mokoid_server_LedService.cpp 跟踪:
            |  七、Demo 1 hardware.h 跟踪:
            |  八、Demo 1 led.c 跟踪:
            |  九、Demo 1 led.h 跟踪:
            |  十、Demo 2 LedTest.java 跟踪:
            |  十一、Demo 2 AndroidManifest.xml 跟踪:
            |  十二、Demo 2 LedSystemServer.java 跟踪:
            |  十三、Demo 2 LedManager.java 跟踪:
            \\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////

参考文章:
    1. Android AIDL使用详解
        http://blog.csdn.net/luoshengyang/article/details/6677029
    2. 在Ubuntu上为Android系统编写Linux内核驱动程序
        http://blog.csdn.net/luoshengyang/article/details/6568411

一、代码工程文件架构:
    .
    ├── Android.mk
    ├── apps                // 应用层软件,提供了2个Demo
    │   ├── Android.mk
    │   ├── LedClient       // Demo 1
    │   │   ├── AndroidManifest.xml
    │   │   ├── Android.mk
    │   │   └── src
    │   │       └── com
    │   │           └── mokoid
    │   │               └── LedClient
    │   │                   └── LedClient.java
    │   └── LedTest         // Demo 2
    │       ├── AndroidManifest.xml
    │       ├── Android.mk
    │       └── src
    │           └── com
    │               └── mokoid
    │                   └── LedTest
    │                       ├── LedSystemServer.java
    │                       └── LedTest.java
    ├── dma6410xp      // 这部分可以不用考虑
    │   ├── AndroidBoard.mk
    │   ├── AndroidProducts.mk
    │   ├── BoardConfig.mk
    │   ├── dma6410xp.mk
    │   ├── init.dma6410xp.rc
    │   ├── init.goldfish.sh
    │   └── init.rc
    ├── frameworks          // 框架层软件
    │   ├── Android.mk
    │   └── base
    │       ├── Android.mk
    │       ├── core
    │       │   └── java
    │       │       └── mokoid
    │       │           └── hardware
    │       │               ├── ILedService.aidl
    │       │               └── LedManager.java
    │       └── service
    │           ├── Android.mk
    │           ├── com.mokoid.server.xml
    │           ├── java
    │           │   └── com
    │           │       └── mokoid
    │           │           └── server
    │           │               └── LedService.java
    │           └── jni
    │               ├── Android.mk
    │               └── com_mokoid_server_LedService.cpp
    ├── hardware            // HAL层
    │   ├── Android.mk
    │   ├── libled
    │   │   ├── Android.mk
    │   │   └── libled.c
    │   └── modules
    │       ├── Android.mk
    │       ├── include
    │       │   └── mokoid
    │       │       └── led.h
    │       └── led
    │           ├── Android.mk
    │           └── led.c
    ├── hardware.h
    └── README.txt

二、Demo 1 LedClient.java 跟踪:
    // cat mokoid-master\apps\LedClient\src\com\mokoid\LedClient\LedClient.java
    package com.mokoid.LedClient;
    // 如果找不到类,可以通过导入的类来得知文件存在哪里
    import com.mokoid.server.LedService;       >-----------------+
                                                                 |
    import android.app.Activity;                                 |
    import android.os.Bundle;                                    |
    import android.widget.TextView;                              |
                                                                 |
    public class LedClient extends Activity {                    |
        @Override                                                |
        public void onCreate(Bundle savedInstanceState) {        |
            super.onCreate(savedInstanceState);                  |
                                                                 |
            // Call an API on the library.                       |
            // 创建Led灯服务对象,跟踪LedService类               |
            LedService ls = new LedService();     <--------------+
            ls.setOn(1);                                // 点亮第一个灯
            ls.setOff(2);                               // 关闭第二个灯

            TextView tv = new TextView(this);
            tv.setText("LED 1 is on. LED 2 is off.");   // 显示提示内容
            setContentView(tv);                         // 显示文本内容
        }
    }

三、Demo 1 LedService.java 跟踪:
    // cat mokoid-master\frameworks\base\service\java\com\mokoid\server\LedService.java
    package com.mokoid.server;

    import android.util.Config;
    import android.util.Log;
    import android.content.Context;
    import android.os.Binder;
    import android.os.Bundle;
    import android.os.RemoteException;
    import android.os.IBinder;
    import mokoid.hardware.ILedService;   >------------------------------+  // 跟踪接口
                                                                         |
    /**                                                                  |
     * ILedService.Stub就是ILedService.aidl由aidl工具自动生成的类。      |
     * Android Interface Definition Language (AIDL):                     |
     * The AIDL compiler creates an interface in the Java programming    |
     * language from your AIDL interface. This interface has an inner    |
     * abstract class named Stub that inherits the interface (and        |
     * implements a few additional methods necessary for the IPC call).  |
     * You must create a class that extends YourInterface.Stub and       |
     * implements the methods you declared in your .aidl file.           |
     */                                                                  |
    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);
        }

        private static native boolean _init();
        private static native boolean _set_on(int led);
        private static native boolean _set_off(int led);
    }

四、Demo 1 ILedService.aidl 跟踪:
    // cat mokoid-master\frameworks\base\core\java\mokoid\hardware\ILedService.aidl
    package mokoid.hardware;

    interface ILedService
    {
        boolean setOn(int led);
        boolean setOff(int led);
    }

五、Demo 1 Android.mk 跟踪:
    // cat mokoid-master\frameworks\base\service\jni\Android.mk
    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)

    # [optional, user, eng]
    # eng = required
    # optinal = no install on target
    LOCAL_MODULE_TAGS := eng

    # This is the target being built.
    LOCAL_MODULE:= libmokoid_runtime    // 共享库模块的名字

    # Target install path.
    LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)

    # All of the source files that we will compile.
    LOCAL_SRC_FILES:= \
        onload.cpp \
        com_mokoid_server_LedService.cpp

    # All of the shared libraries we link against.
    LOCAL_SHARED_LIBRARIES := \
        libandroid_runtime \
        libnativehelper \
        libcutils \
        libutils \
        libhardware

    # No static libraries.
    LOCAL_STATIC_LIBRARIES :=

    # Also need the JNI headers.
    LOCAL_C_INCLUDES += \
        $(JNI_H_INCLUDE) \
        vendor/mokoid/hardware/modules/include/

    # No specia compiler flags.
    LOCAL_CFLAGS +=

    # Don't prelink this library.  For more efficient code, you may want
    # to add this library to the prelink map and set this to true.
    LOCAL_PRELINK_MODULE := false

    include $(BUILD_SHARED_LIBRARY)

六、Demo 1 com_mokoid_server_LedService.cpp 跟踪:
    // cat mokoid-master\frameworks\base\service\jni\com_mokoid_server_LedService.cpp
    #define LOG_TAG "Mokoid"
    #include "utils/Log.h"

    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <assert.h>

    #include <jni.h>
    #include <mokoid/led.h>

    // ----------------------------------------------------------------------------

    struct led_control_device_t *sLedDevice = NULL;

    static jboolean mokoid_setOn(JNIEnv* env, jobject thiz, jint led)
    {
        LOGI("LedService JNI: mokoid_setOn() is invoked.");

        if (sLedDevice == NULL) {
            LOGI("LedService JNI: sLedDevice was not fetched correctly.");
            return -1;
        } else {
            return sLedDevice->set_on(sLedDevice, led);
        }
    }

    static jboolean mokoid_setOff(JNIEnv* env, jobject thiz, jint led)
    {
        LOGI("LedService JNI: mokoid_setOff() is invoked.");

        if (sLedDevice == NULL) {
            LOGI("LedService JNI: sLedDevice was not fetched correctly.");
            return -1;
        } else {
            return sLedDevice->set_off(sLedDevice, led);
        }
    }

    /** helper APIs */
    static inline int led_control_open(const struct hw_module_t* module,
            struct led_control_device_t** device) {
        return module->methods->open(module,
                LED_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
    }

    static jboolean mokoid_init(JNIEnv *env, jclass clazz)
    {
        led_module_t* module;

        // 接下来需要跟踪这一部分的代码,如何获取这一部分的内容
        if (hw_get_module(LED_HARDWARE_MODULE_ID, (const hw_module_t**)&module) == 0) {
            LOGI("LedService JNI: LED Stub found.");
            if (led_control_open(&module->common, &sLedDevice) == 0) {
                LOGI("LedService JNI: Got Stub operations.");
                return 0;
            }
        }

        LOGE("LedService JNI: Get Stub operations failed.");
        return -1;
    }

    // --------------------------------------------------------------------------

    /*
     * Array of methods.
     *
     * Each entry has three fields: the name of the method, the method
     * signature, and a pointer to the native implementation.
     * 这里对应class LedService中的本地方法
     * 函数register_mokoid_server_LedService会把以C/C++实现的接口注册为java可调用的接口
     */
    static const JNINativeMethod gMethods[] = {
        { "_init",          "()Z",  (void *)mokoid_init },
        { "_set_on",        "(I)Z", (void *)mokoid_setOn },
        { "_set_off",       "(I)Z", (void *)mokoid_setOff },
    };

    /**
     * 在android源代码的注册该方法frameworks/base/services/jni/onload.cpp
     *  cat frameworks/base/services/jni/onload.cpp
     *      #include "JNIHelp.h"
     *      #include "jni.h"
     *      #include "utils/Log.h"
     *      #include "utils/misc.h"
     *
     *      namespace android {
     *      int register_android_server_AlarmManagerService(JNIEnv* env);
     *      int register_android_server_BatteryService(JNIEnv* env);
     *      int register_android_server_InputApplicationHandle(JNIEnv* env);
     *      int register_android_server_InputWindowHandle(JNIEnv* env);
     *      int register_android_server_InputManager(JNIEnv* env);
     *      int register_android_server_LightsService(JNIEnv* env);
     *      int register_android_server_PowerManagerService(JNIEnv* env);
     *      int register_android_server_SerialService(JNIEnv* env);
     *      int register_android_server_UsbDeviceManager(JNIEnv* env);
     *      int register_android_server_UsbHostManager(JNIEnv* env);
     *      int register_android_server_VibratorService(JNIEnv* env);
     *      int register_android_server_SystemServer(JNIEnv* env);
     *      int register_android_server_location_GpsLocationProvider(JNIEnv* env);
     *      int register_android_server_connectivity_Vpn(JNIEnv* env);
     *      };
     *
     *      using namespace android;
     *
     *      extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
     *      {
     *          JNIEnv* env = NULL;
     *          jint result = -1;
     *
     *          if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
     *              ALOGE("GetEnv failed!");
     *              return result;
     *          }
     *          ALOG_ASSERT(env, "Could not retrieve the env!");
     *
     *          register_android_server_PowerManagerService(env);
     *          register_android_server_SerialService(env);
     *          register_android_server_InputApplicationHandle(env);
     *          register_android_server_InputWindowHandle(env);
     *          register_android_server_InputManager(env);
     *          register_android_server_LightsService(env);
     *          register_android_server_AlarmManagerService(env);
     *          register_android_server_BatteryService(env);
     *          register_android_server_UsbDeviceManager(env);
     *          register_android_server_UsbHostManager(env);
     *          register_android_server_VibratorService(env);
     *          register_android_server_SystemServer(env);
     *          register_android_server_location_GpsLocationProvider(env);
     *          register_android_server_connectivity_Vpn(env);
     *
     *          return JNI_VERSION_1_4;
     *      }
     *
     */
    int register_mokoid_server_LedService(JNIEnv* env) {
        static const char* const kClassName =
            "com/mokoid/server/LedService";
        jclass clazz;

        /* look up the class */
        clazz = env->FindClass(kClassName);
        if (clazz == NULL) {
            LOGE("Can't find class %s\n", kClassName);
            return -1;
        }

        /* register all the methods */
        if (env->RegisterNatives(clazz, gMethods,
                sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
        {
            LOGE("Failed registering methods for %s\n", kClassName);
            return -1;
        }

        /* fill out the rest of the ID cache */
        return 0;
    }

七、Demo 1 hardware.h 跟踪:
    // android 源代码里 cat hardware/libhardware/include/hardware/hardware.h
    /*
     * Copyright (C) 2008 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    #ifndef ANDROID_INCLUDE_HARDWARE_HARDWARE_H
    #define ANDROID_INCLUDE_HARDWARE_HARDWARE_H

    #include <stdint.h>
    #include <sys/cdefs.h>

    #include <cutils/native_handle.h>
    #include <system/graphics.h>

    __BEGIN_DECLS

    /*
     * Value for the hw_module_t.tag field
     * 这里提供字符合成方式
     */
    #define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))

    /**
     * 需要合成的module、device的tag
     */
    #define HARDWARE_MODULE_TAG MAKE_TAG_CONSTANT('H', 'W', 'M', 'T')
    #define HARDWARE_DEVICE_TAG MAKE_TAG_CONSTANT('H', 'W', 'D', 'T')

    /**
     * 提供硬件api版本合成方法
     */
    #define HARDWARE_MAKE_API_VERSION(maj,min) \
                ((((maj) & 0xff) << 8) | ((min) & 0xff))

    #define HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) \
                ((((maj) & 0xff) << 24) | (((min) & 0xff) << 16) | ((hdr) & 0xffff))
    #define HARDWARE_API_VERSION_2_MAJ_MIN_MASK 0xffff0000
    #define HARDWARE_API_VERSION_2_HEADER_MASK  0x0000ffff

    /*
     * The current HAL API version.   -->  当前的硬件api版本 1.0
     *
     * All module implementations must set the hw_module_t.hal_api_version field
     * to this value when declaring the module with HAL_MODULE_INFO_SYM.
     *
     * Note that previous implementations have always set this field to 0.
     * Therefore, libhardware HAL API will always consider versions 0.0 and 1.0
     * to be 100% binary compatible.
     *
     * 设置当前版本为1.0
     */
    #define HARDWARE_HAL_API_VERSION HARDWARE_MAKE_API_VERSION(1, 0)

    /*
     * Helper macros for module implementors.  -->  提供的版本生成宏
     *
     * The derived modules should provide convenience macros for supported
     * versions so that implementations can explicitly specify module/device
     * versions at definition time.
     *
     * Use this macro to set the hw_module_t.module_api_version field.
     */
    #define HARDWARE_MODULE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min)
    #define HARDWARE_MODULE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr)

    /*
     * Use this macro to set the hw_device_t.version field
     */
    #define HARDWARE_DEVICE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min)
    #define HARDWARE_DEVICE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr)

    struct hw_module_t;
    struct hw_module_methods_t;
    struct hw_device_t;

    /**
     * 每一个硬件模块都一个HAL_MODULE_INFO_SYM结构体
     * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
     * and the fields of this data structure must begin with hw_module_t
     * followed by module specific information.
     */
    typedef struct hw_module_t {
        /** tag must be initialized to HARDWARE_MODULE_TAG */
        /** 这个tag的值必须初始化为 HARDWARE_MODULE_TAG */
        uint32_t tag;

        /**
         * 对于模块实现的版本,模块开发者有责任更新版本
         * The API version of the implemented module. The module owner is
         * responsible for updating the version when a module interface has
         * changed.
         *
         * The derived modules such as gralloc and audio own and manage this field.
         * The module user must interpret the version field to decide whether or
         * not to inter-operate with the supplied module implementation.
         * For example, SurfaceFlinger is responsible for making sure that
         * it knows how to manage different versions of the gralloc-module API,
         * and AudioFlinger must know how to do the same for audio-module API.
         *
         * The module API version should include a major and a minor component.
         * For example, version 1.0 could be represented as 0x0100. This format
         * implies that versions 0x0100-0x01ff are all API-compatible.
         *
         * In the future, libhardware will expose a hw_get_module_version()
         * (or equivalent) function that will take minimum/maximum supported
         * versions as arguments and would be able to reject modules with
         * versions outside of the supplied range.
         */
        uint16_t module_api_version;
    #define version_major module_api_version
        /**
         * version_major/version_minor defines are supplied here for temporary
         * source code compatibility. They will be removed in the next version.
         * ALL clients must convert to the new version format.
         */

        /**
         * The API version of the HAL module interface. This is meant to
         * version the hw_module_t, hw_module_methods_t, and hw_device_t
         * structures and definitions.
         *
         * The HAL interface owns this field. Module users/implementations
         * must NOT rely on this value for version information.
         *
         * Presently, 0 is the only valid value.
         */
        uint16_t hal_api_version;
    #define version_minor hal_api_version

        /** Identifier of module */
        /** 模块的标识符,独一无二的,用于区分各个模块,也用于获取模块 */
        const char *id;

        /** Name of this module */
        /** 模块的名字 */
        const char *name;

        /** Author/owner/implementor of the module */
        /** 模块的实现者 */
        const char *author;

        /** Modules methods */
        struct hw_module_methods_t* methods;

        /** module's dso */
        void* dso;

        /** padding to 128 bytes, reserved for future use */
        uint32_t reserved[32-7];

    } hw_module_t;

    typedef struct hw_module_methods_t {
        /** Open a specific device */
        /** 目前唯一的方法,打开一个设备的方法 */
        int (*open)(const struct hw_module_t* module, const char* id,
                struct hw_device_t** device);

    } hw_module_methods_t;

    /**
     * Every device data structure must begin with hw_device_t
     * followed by module specific public methods and attributes.
     */
    typedef struct hw_device_t {
        /** tag must be initialized to HARDWARE_DEVICE_TAG */
        uint32_t tag;

        /**
         * Version of the module-specific device API. This value is used by
         * the derived-module user to manage different device implementations.
         *
         * The module user is responsible for checking the module_api_version
         * and device version fields to ensure that the user is capable of
         * communicating with the specific module implementation.
         *
         * One module can support multiple devices with different versions. This
         * can be useful when a device interface changes in an incompatible way
         * but it is still necessary to support older implementations at the same
         * time. One such example is the Camera 2.0 API.
         *
         * This field is interpreted by the module user and is ignored by the
         * HAL interface itself.
         */
        uint32_t version;

        /** reference to the module this device belongs to */
        /** 指向设备所属的硬件模块 */
        struct hw_module_t* module;

        /** padding reserved for future use */
        uint32_t reserved[12];

        /** Close this device */
        /** 关闭设备的方法 */
        int (*close)(struct hw_device_t* device);

    } hw_device_t;

    /**
     * Name of the hal_module_info
     */
    #define HAL_MODULE_INFO_SYM         HMI

    /**
     * Name of the hal_module_info as a string
     */
    #define HAL_MODULE_INFO_SYM_AS_STR  "HMI"

    /**
     * 通过id获取模块
     * Get the module info associated with a module by id.
     *
     * @return: 0 == success, <0 == error and *module == NULL
     */
    // jni中通过这个来获取底层的模块
    int hw_get_module(const char *id, const struct hw_module_t **module);  

    /**
     * Get the module info associated with a module instance by class 'class_id'
     * and instance 'inst'.
     *
     * Some modules types necessitate multiple instances. For example audio supports
     * multiple concurrent interfaces and thus 'audio' is the module class
     * and 'primary' or 'a2dp' are module interfaces. This implies that the files
     * providing these modules would be named audio.primary.<variant>.so and
     * audio.a2dp.<variant>.so
     *
     * @return: 0 == success, <0 == error and *module == NULL
     */
    int hw_get_module_by_class(const char *class_id, const char *inst,
                               const struct hw_module_t **module);

    __END_DECLS

    #endif  /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */

八、Demo 1 led.c 跟踪:
    // cat mokoid-master\hardware\modules\led\led.c
    #define LOG_TAG "MokoidLedStub"

    #include <hardware/hardware.h>

    #include <fcntl.h>
    #include <errno.h>

    #include <cutils/log.h>
    #include <cutils/atomic.h>

    #include <mokoid/led.h>

    /*****************************************************************************/

    int led_device_close(struct hw_device_t* device)
    {
        struct led_control_device_t* ctx = (struct led_control_device_t*)device;
        if (ctx) {
            free(ctx);
        }
        return 0;
    }

    int led_on(struct led_control_device_t *dev, int32_t led)
    {
        LOGI("LED Stub: set %d on.", led);

        return 0;
    }

    int led_off(struct led_control_device_t *dev, int32_t led)
    {
        LOGI("LED Stub: set %d off.", led);

        return 0;
    }

    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;

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

    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 */
    };

九、Demo 1 led.h 跟踪:
    // cat mokoid-master\hardware\modules\include\mokoid\led.h
    #include <hardware/hardware.h>

    #include <fcntl.h>
    #include <errno.h>

    #include <cutils/log.h>
    #include <cutils/atomic.h>

    /***************************************************************************/

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

    /***************************************************************************/

    struct led_control_context_t {
        struct led_control_device_t device;
    };

    #define LED_HARDWARE_MODULE_ID "led"

十、Demo 2 LedTest.java 跟踪:
    // cat mokoid-master\apps\LedTest\src\com\mokoid\LedTest\LedTest.java
    package com.mokoid.LedTest;
    import mokoid.hardware.LedManager;
    import com.mokoid.server.LedService;

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.TextView;
    import android.widget.Button;
    import android.content.Intent;
    import android.view.View;

    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.
            // 开启服务程序,Intent中的名字在AndroidManifest.xml中有配置
            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.");
                // 创建一个LedManager,会去获取已经注册了的一个模块
                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);
        }
    }

十一、Demo 2 AndroidManifest.xml 跟踪:
    // cat mokoid-master\apps\LedTest\AndroidManifest.xml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.mokoid.LedTest"
        android:sharedUserId="android.uid.system">

        <uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"/>
        <uses-permission android:name="android.permission.READ_USER_DICTIONARY"/>
        <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY"/>

        <application>

            <!-- This tells the system about the custom library used by the
                 application, so that it can be properly loaded and linked
                 to the app when the app is initialized. -->
            <uses-library android:name="com.mokoid.server" />

            <activity android:name=".LedTest">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
            <service android:name=".LedSystemServer"
                      android:process=".LedSystemServer" >
                <intent-filter>
                    <action android:name="com.mokoid.systemserver"/>  <!-- 启动服务名 -->
                    <category android:name="android.intent.category.DEFAULT"/>
                </intent-filter>
            </service>
        </application>
    </manifest>

十二、Demo 2 LedSystemServer.java 跟踪:
    // cat mokoid-master\apps\LedTest\src\com\mokoid\LedTest\LedSystemServer.java
    package com.mokoid.LedTest;

    import com.mokoid.server.LedService;

    import android.os.IBinder;
    import android.os.ServiceManager;
    import android.util.Log;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;

    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. */
            // 创建Led服务对象
            LedService ls = new LedService();

            try {
                // 将Led服务对象添加到系统服务管理器中去
                // 这样其他的进程、线程就可以通过系统服务管理器获取Led服务对象
                ServiceManager.addService("led", ls);
            } catch (RuntimeException e) {
                Log.e("LedSystemServer", "Start LedService failed.");
            }
        }
    }

十三、Demo 2 LedManager.java 跟踪:
    // cat mokoid-master\frameworks\base\core\java\mokoid\hardware\LedManager.java
    package mokoid.hardware;

    import android.content.Context;
    import android.os.Binder;
    import android.os.Bundle;
    import android.os.Parcelable;
    import android.os.ParcelFileDescriptor;
    import android.os.Process;
    import android.os.RemoteException;
    import android.os.Handler;
    import android.os.Message;
    import android.os.ServiceManager;
    import android.util.Log;
    import mokoid.hardware.ILedService;

    /**
     * Class that lets you access the Mokoid LedService.
     */
    public class LedManager
    {
        private static final String TAG = "LedManager";
        private ILedService mLedService;

        public LedManager() {

            // 从系统服务管理中获取ledservice实例
            // ILedService.Stub.asInterface,目前对这个部分还是不是很了解
            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;
        }
    }

 

时间: 2024-08-20 21:08:17

Android Mokoid Open Source Project hacking的相关文章

Android GPS GPSBasics project hacking

一.参考源码: GPS Basic Example - Android Example http://androidexample.com/GPS_Basic__-__Android_Example/index.php?view=article_discription&aid=68&aaid=93 二.Permission: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"

Android中 Gradle “xxx” project refresh failed问题

环境(2014.03.13最新): 问题: Gradle "xxx" project refresh failed 描述: 这是一个很常见的问题, 比如之前可以使用, 新建工作, 或重新启动, 则不可使用, 显示无法构建, Gradle无法使用 解决: 清除缓存, 重启Gradle, File->Invalidate Caches / Restart... ; 即可; Gradle是构建Android项目的必备程序, Android Studio的基础, 有很多优势, 使构建变得

android studio-Android studio gradle project sync 这是怎么回事?

问题描述 Android studio gradle project sync 这是怎么回事? 就是把一台电脑64位的Android studio 的project 复制到另一台32位的Android studio 上,使用import project 进行导入,然后就提示gradle project sync 什么的,然后就只剩下基本的编辑的功能了,新建acticity也不行,这是因为什么? 解决方案 应该是环境没有配好,包括各种studio需要的插件,包括gradle版本,sdk等 解决方案

A Deep Insight of Alibaba Open Source Project - Pouch

By Allen Sun, Senior Engineer at Alibaba Group Pouch's vision is to advance container ecosystem and promote container standards OCI (Open Container Initiative), so that container technologies could become the foundation for application development in

open source project&amp;amp;amp;tool I concern

1.ethereal: (http://www.ethereal.com ) The world's most popular network protocol analyzer.Ethereal is used by network professionals around the world for troubleshooting, analysis, software and protocol development, and education. It has all of the st

Python Open Source Project List

http://www.simple-is-better.com/sites/http://www.oschina.net/project/lang/25/pythonhttps://github.com/languages/Python

Android HAL(硬件抽象层)介绍以及调用

Android 的 HAL(Hardware Abstract Layer硬件抽象层)是Google因应厂商「希望不公开源码」的要求下,所推出的新观念,其架构如下图.虽然 HAL 现在的「抽象程度」还不足,现阶段实作还不是全面符合 HAL的架构规划,不过也确实给了我们很好的思考空间. 图1:Android HAL 架构规划 这是 Patrick Brady (Google) 在2008 Google I/O 所发表的演讲「Anatomy & Physiology of an Android」中,

I.MX6 android BatteryService jni hacking

/**************************************************************************** * I.MX6 android BatteryService jni hacking * 声明: * 本文主要是为了知道Android的获取的电源管理的数据的jni是从Linux系统的 * 什么位置获取的,获取的机制是什么. * * 2016-2-22 深圳 南山平山村 曾剑锋 ********************************

Cocos2d-x Visual Studio Android Project

In the world of game development , Cocos2d is one of the biggest names out there. The open source Cocos2d framework has been the backbone of a vast number of top selling apps and games, provides support for a number of programming languages, and targ