4、第一种方法:直接调用service方法的实现过程
下面分析第一种方法中,各层的关键代码。
(1)HAL层
一般来说HAL moudle需要涉及的是三个关键结构体:
struct hw_module_t;
struct hw_module_methods_t;
struct hw_device_t;
下面结合代码说明这3个结构的用法。部分代码经过修改,后面的章节会给出修改的原因。
文件:mokoid-read-only/hardware/modules/include/mokoid/led.h
- struct led_module_t {
- struct hw_module_t common;
- };
-
- struct led_control_device_t {
-
- struct hw_device_t common;
-
- int fd;
-
- int (*set_on)(struct led_control_device_t *dev, int32_t led);
- int (*set_off)(struct led_control_device_t *dev, int32_t led);
- };
- #define LED_HARDWARE_MODULE_ID "led"
-
文件:mokoid-read-only/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 "../include/mokoid/led.h"
-
- int fd;
- #define GPG3DAT2_ON 0x4800 //ioctl控制命令
- #define GPG3DAT2_OFF 0x4801
- 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);
- }
- close(fd);
- return 0;
- }
- int led_on(struct led_control_device_t *dev, int32_t led)
- {
- LOGI("LED Stub: set %d on.", led);
- ioctl(fd,GPG3DAT2_ON,NULL);
- 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;
-
- if((fd=open("/dev/led",O_RDWR))==-1)
- {
- LOGE("LED open error");
- }
- else
- LOGI("open ok");
- 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,
-
- }
-
- };
(2)JNI层
文件:mokoid-read-only/frameworks/base/service/jni/com_mokoid_server_LedService.cpp
- 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);
- }
- }
-
-
- 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;
- LOGI("jni init-----------------------.");
- 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;
- }
-
-
-
-
-
-
- static const JNINativeMethod gMethods[] = {
- { "_init", "()Z", (void *)mokoid_init },
- { "_set_on", "(I)Z", (void *)mokoid_setOn },
- { "_set_off", "(I)Z", (void *)mokoid_setOff },
- };
-
-
-
-
-
-
- static int registerMethods(JNIEnv* env) {
- static const char* const kClassName =
- "com/mokoid/server/LedService";
- jclass clazz;
-
- clazz = env->FindClass(kClassName);
- if (clazz == NULL) {
- LOGE("Can't find class %s/n", kClassName);
- return -1;
- }
-
- if (env->RegisterNatives(clazz, gMethods,
- sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
- {
- LOGE("Failed registering methods for %s/n", kClassName);
- return -1;
- }
-
- return 0;
- }
- jint JNI_OnLoad(JavaVM* vm, void* reserved) {
- JNIEnv* env = NULL;
- jint result = -1;
- LOGI("JNI_OnLoad LED");
- if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- LOGE("ERROR: GetEnv failed/n");
- goto fail;
- }
- assert(env != NULL);
- if (registerMethods(env) != 0) {
- LOGE("ERROR: PlatformLibrary native registration failed/n");
- goto fail;
- }
-
- result = JNI_VERSION_1_4;
- fail:
- return result;
- }
(3)service (属于Framework层)
文件: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;
- 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();
- }
-
-
-
- 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);
- }
(4)APP 测试程序 (属于APP层)
文件: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);
-
- 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);
- }
- }