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 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的更多相关文章
- Android开发工具全面转向Android Studio(3)——AS project/module的目录结构(与Eclipse对比)
如果AS完全还没摸懂的,建议先看下Android开发工具全面转向Android Studio(2)——AS project/module的CRUD. 注:以下以Windows平台为标准,AS以目前最新 ...
- 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 ...
- Unable to locate Android SDK used by project
Unable to locate Android SDK used by project: DJIgojava.lang.RuntimeException: Unable to locate Andr ...
- Eclipse / Android : “Errors running builder 'Android Pre Compiler' on project…”
Errors occurred during the build. Errors running builder 'Android Resource Manager' on project 'hell ...
- Android Studio中关于Project与Module
在Android Studio中一个Project和Eclipse中的WorkSpace是相似的,而一个Module与Eclipse中的Project是相似的(大致可以这么的认为) 若在Android ...
- 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 ...
- 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 ...
- Android出现:Your project path contains non-ASCII characters.
导入Project的出现: Error:(1, 0) Your project path contains non-ASCII characters. This will most likely ca ...
- open source project for recommendation system
原文链接:http://blog.csdn.net/cserchen/article/details/14231153 目前互联网上所能找到的知名开源推荐系统(open source project ...
随机推荐
- WZY社区
WZY社区是我自己做的一个网站,后面会详细更新,敬请关注!
- XML_CPP_资料_libXml2_01_Code_ZC(?.pro)
ZC:最下面有 ?.pro文件的设置写法 ZC: Win7x64,qt-opensource-windows-x86-msvc2010_opengl-5.3.2.exe,cn_visual_studi ...
- 远程SqlServer服务器
①,安装net framework3.5. ②,安装sqlserver2014(例). ③,基本配置. 安装sqlserver2014时,开启混合认证模式.当然,也可以在安装后,通过sqlserver ...
- 2018年全国多校算法寒假训练营练习比赛(第一场)G 圆圈
https://www.nowcoder.com/acm/contest/67/G 思路: 分形. 记录中间左边点的坐标,然后推出另外3个点的坐标,递归到最简单的情况. 代码: #include< ...
- 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 ...
- rsync+inotify文件同步
rsync+inotify文件同步 在服务器中,通常结合计划任务.shell脚本来执行本地备份.为了进一步提高备份的可靠性,使用异地备份也是非常重要的,利用rsync工具,可以实现快速.高效的异地备份 ...
- C#正则过滤HTML标签并保留指定标签的方法
本文实例讲述了C#正则过滤html标签并保留指定标签的方法.分享给大家供大家参考,具体如下: 这边主要看到一个过滤的功能: public static string FilterHtmlTag(str ...
- 20170706wdVBA正则表达式提取题目
Public Sub GetContents() Dim Reg As Object Dim Matches As Object Dim OneMatch As Object Dim Index As ...
- Android设计模式之工厂模式
定义 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.因为工厂模式就相当于创建实例 ...
- Lunar New Year and Red Envelopes CodeForces - 1106E (dp)
大意: 总共$n$的时间, $k$个红包, 红包$i$只能在时间$[s_i,t_i]$范围内拿, 并且拿完后时间跳到$d_i+1$,Bob采用贪心策略,每个时间点若有红包能取则取钱数$w_i$最大的, ...