/*****************************************************************************
* 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 LedClient.java 跟踪:
| 三、Demo LedService.java 跟踪:
| 四、Demo ILedService.aidl 跟踪:
| 五、Demo Android.mk 跟踪:
| 六、Demo com_mokoid_server_LedService.cpp 跟踪:
| 七、Demo hardware.h 跟踪:
| 八、Demo led.c 跟踪:
| 九、Demo led.h 跟踪:
| 十、Demo LedTest.java 跟踪:
| 十一、Demo AndroidManifest.xml 跟踪:
| 十二、Demo LedSystemServer.java 跟踪:
| 十三、Demo LedManager.java 跟踪:
\\\\\\\\\\\\\\\\\\\\\\\\\\\///////////////////////////// 参考文章:
. Android AIDL使用详解
http://blog.csdn.net/luoshengyang/article/details/6677029
. 在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 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(); // 点亮第一个灯
ls.setOff(); // 关闭第二个灯 TextView tv = new TextView(this);
tv.setText("LED 1 is on. LED 2 is off."); // 显示提示内容
setContentView(tv); // 显示文本内容
}
} 三、Demo 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 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 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 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 -;
} 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 -;
} 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) == ) {
LOGI("LedService JNI: LED Stub found.");
if (led_control_open(&module->common, &sLedDevice) == ) {
LOGI("LedService JNI: Got Stub operations.");
return ;
}
} LOGE("LedService JNI: Get Stub operations failed.");
return -;
} // -------------------------------------------------------------------------- /*
* 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 -;
} /* register all the methods */
if (env->RegisterNatives(clazz, gMethods,
sizeof(gMethods) / sizeof(gMethods[])) != JNI_OK)
{
LOGE("Failed registering methods for %s\n", kClassName);
return -;
} /* fill out the rest of the ID cache */
return ;
} 七、Demo 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) << ) | ((min) & 0xff)) #define HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) \
((((maj) & 0xff) << ) | (((min) & 0xff) << ) | ((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[-]; } 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[]; /** 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 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 ;
} int led_on(struct led_control_device_t *dev, int32_t led)
{
LOGI("LED Stub: set %d on.", led); return ;
} int led_off(struct led_control_device_t *dev, int32_t led)
{
LOGI("LED Stub: set %d off.", led); return ;
} 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, , sizeof(*dev)); dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = ;
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 ;
} 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: ,
version_minor: ,
id: LED_HARDWARE_MODULE_ID,
name: "Sample LED Stub",
author: "The Mokoid Open Source Project",
methods: &led_module_methods,
}
/* supporting APIs go here */
}; 九、Demo 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 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(); TextView tv = new TextView(this);
tv.setText("LED 1 is On.");
setContentView(tv);
}
} 十一、Demo 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 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 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;
}
}

Android Mokoid Open Source Project hacking的更多相关文章

  1. Android开发工具全面转向Android Studio(3)——AS project/module的目录结构(与Eclipse对比)

    如果AS完全还没摸懂的,建议先看下Android开发工具全面转向Android Studio(2)——AS project/module的CRUD. 注:以下以Windows平台为标准,AS以目前最新 ...

  2. Android编译报Errors running builder 'Android Pre Compiler' on project 'XXX' java.lang.NullPointerException

    编译android时,遇到报错:Errors occurred during the build.Errors running builder 'Android Pre Compiler' on pr ...

  3. Unable to locate Android SDK used by project

    Unable to locate Android SDK used by project: DJIgojava.lang.RuntimeException: Unable to locate Andr ...

  4. Eclipse / Android : “Errors running builder 'Android Pre Compiler' on project…”

    Errors occurred during the build. Errors running builder 'Android Resource Manager' on project 'hell ...

  5. Android Studio中关于Project与Module

    在Android Studio中一个Project和Eclipse中的WorkSpace是相似的,而一个Module与Eclipse中的Project是相似的(大致可以这么的认为) 若在Android ...

  6. Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conflict with dependency 'com.android.support:support-annotations' in project ':app'. Resolved versions for app (26.1.0) and test app

    出现的问题: Error:Execution failed for task ':app:preDebugAndroidTestBuild'.> Conflict with dependency ...

  7. Conflict with dependency 'com.android.support:support-annotations' in project ':xxx'. Resolved versions for app (25.4.0) and test app (27.1.1) differ 问题解决

    Conflict with dependency 'com.android.support:support-annotations' in project ':xxx'. Resolved versi ...

  8. Android出现:Your project path contains non-ASCII characters.

    导入Project的出现: Error:(1, 0) Your project path contains non-ASCII characters. This will most likely ca ...

  9. open source project for recommendation system

    原文链接:http://blog.csdn.net/cserchen/article/details/14231153 目前互联网上所能找到的知名开源推荐系统(open source project ...

随机推荐

  1. WZY社区

    WZY社区是我自己做的一个网站,后面会详细更新,敬请关注!

  2. XML_CPP_资料_libXml2_01_Code_ZC(?.pro)

    ZC:最下面有 ?.pro文件的设置写法 ZC: Win7x64,qt-opensource-windows-x86-msvc2010_opengl-5.3.2.exe,cn_visual_studi ...

  3. 远程SqlServer服务器

    ①,安装net framework3.5. ②,安装sqlserver2014(例). ③,基本配置. 安装sqlserver2014时,开启混合认证模式.当然,也可以在安装后,通过sqlserver ...

  4. 2018年全国多校算法寒假训练营练习比赛(第一场)G 圆圈

    https://www.nowcoder.com/acm/contest/67/G 思路: 分形. 记录中间左边点的坐标,然后推出另外3个点的坐标,递归到最简单的情况. 代码: #include< ...

  5. IIS中发布后出现Could not load file or assembly'System.Data.SQLite.dll' or one of its depedencies

    [问题]在我本机的开发环境c#连接sqlite3没有问题,可是release版本移植到其他的机器就提示Could not load file or assembly'System.Data.SQLit ...

  6. rsync+inotify文件同步

    rsync+inotify文件同步 在服务器中,通常结合计划任务.shell脚本来执行本地备份.为了进一步提高备份的可靠性,使用异地备份也是非常重要的,利用rsync工具,可以实现快速.高效的异地备份 ...

  7. C#正则过滤HTML标签并保留指定标签的方法

    本文实例讲述了C#正则过滤html标签并保留指定标签的方法.分享给大家供大家参考,具体如下: 这边主要看到一个过滤的功能: public static string FilterHtmlTag(str ...

  8. 20170706wdVBA正则表达式提取题目

    Public Sub GetContents() Dim Reg As Object Dim Matches As Object Dim OneMatch As Object Dim Index As ...

  9. Android设计模式之工厂模式

    定义 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.因为工厂模式就相当于创建实例 ...

  10. Lunar New Year and Red Envelopes CodeForces - 1106E (dp)

    大意: 总共$n$的时间, $k$个红包, 红包$i$只能在时间$[s_i,t_i]$范围内拿, 并且拿完后时间跳到$d_i+1$,Bob采用贪心策略,每个时间点若有红包能取则取钱数$w_i$最大的, ...