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