/*****************************************************************************
* 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. vue饿了么学习笔记(1)vue-cli开启项目

    一.vue-cli介绍 vue-cli是vue的脚手架工具 ---->  帮助写好vue.js基础代码的工具: ① 搭建目录结构 ② 进行本地调试 ③ 进行代码部署 ④ 热加载 ⑤ 进行单元测试 ...

  2. Codeforces 447C - DZY Loves Sequences

    447C - DZY Loves Sequences 思路:dp 代码: #include<bits/stdc++.h> using namespace std; #define ll l ...

  3. C#中一个简单的匹配16进制颜色的正则测试

    using System; using System.Text.RegularExpressions; namespace Test { class Program { //匹配16进制颜色代码的正则 ...

  4. Redis之列表类型命令

    Redis 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素到列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (4294967 ...

  5. vysor 破解 (插件 V1.7.8 客户端2.1.0)

    0.环境 mac os ===19年更新-客户端破解=== 换了个电脑,老的Chrome 插件各种问题,就换了客户端,然后就是一片模糊... 参考文档:https://www.sdbeta.com/w ...

  6. LINQ 系列

    C#图解教程 第十九章 LINQ   LINQ 什么是LINQLINQ提供程序 匿名类型 方法语法和查询语法查询变量查询表达式的结构 from子句join子句什么是联结查询主体中的from…let…w ...

  7. Analysis of single cell RNA-seq data(单细胞终极课程)

    业界良心啊,开源的单细胞课程. 随便看了几章,课程写得非常用心,非常适合新手. 课程地址:Analysis of single cell RNA-seq data 源码地址:hemberg-lab/s ...

  8. 很实用且容易忘记的小命令 for Linux(更新中...)

    系统相关 # 系统安装日期 sudo tune2fs -l /dev/sda1 |grep create # 查看centos版本命令 rpm -q centos-release #查看centos版 ...

  9. oracle使用(1)

    纯粹是记录工作中使用的分析函数或是语法点,不做其他用处. (1) with as 先举个例子吧: 有两张表,分别为A.B,求得一个字段的值先在表A中寻找,如果A表中存在数据,则输出A表的值:如果A表中 ...

  10. python-day53--前端js

    一.基本语法(ECMA) 单行注释 // /* 多行注释 */ 变量赋值 默认以换行符作为结束符,有分好以分号作为结束符号 JS的引入方式: 1. <script> </script ...