zhilu.zhang
zhilu.zhang
发布于 2019-12-31 / 23 阅读 / 0 评论 / 0 点赞

Android硬件访问服务

Android硬件访问服务

一. 流程概要

二. 开发流程

1.编写ILedService.aidl生成ILedService.java文件

(1).编写AIDL文件:ILedService.aidl

package android.os;

/** {@hide} */
interface ILedService
{
        int ledCtrl(int which, int status);
}

(2).生成ILedService.java文件

修改ILedService.aidl文件对应的Android.mk文件添加一行:

core/java/android/os/IledService.aidl \

执行mmm命令,由IledService.aidl文件自动生成ILedService.java文件

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: frameworks/base/./core/java/android/os/ILedService.aidl
 */
package android.os;
/** {@hide} */
public interface ILedService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.ILedService
{
private static final java.lang.String DESCRIPTOR = "android.os.ILedService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an android.os.ILedService interface,
 * generating a proxy if needed.
 */
public static android.os.ILedService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.ILedService))) {
return ((android.os.ILedService)iin);
}
return new android.os.ILedService.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_ledCtrl:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.ledCtrl(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.os.ILedService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public int ledCtrl(int which, int status) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(which);
_data.writeInt(status);
mRemote.transact(Stub.TRANSACTION_ledCtrl, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_ledCtrl = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int ledCtrl(int which, int status) throws android.os.RemoteException;
}

2.编写LedService.java文件

(1)编写LedService.java文件

package com.android.server;
import android.os.ILedService;

public class LedService extends ILedService.Stub {
    private static final String TAG = "LedService";

        /* 调用本地C函数去操作硬件 */
        public int ledCtrl(int which, int status) throws android.os.RemoteException
        {
                return native_ledCtrl(which, status);
        }
        /* 在构造函数里实现open函数 */
        public LedService() {
                native_ledOpen();
        }

        public static native int native_ledOpen();
        public static native void native_ledClose();
        public static native int native_ledCtrl(int which, int status);
}

(4)修改SystemServer.java文件

添加内容:

Slog.i(TAG, "Led Service");
ServiceManager.addService("led", new LedService());

3.编写com_android_server_LedService.cpp文件,供SystemServer.java使用

(1)编写com_android_server_LedService.cpp文件

#define LOG_TAG "LedService"

#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"

#include <utils/misc.h>
#include <utils/Log.h>

#include <stdio.h>

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <hardware/led_hal.h>


namespace android
{

static led_device_t* led_device;

jint ledOpen(JNIEnv *env, jobject cls)
{
        jint err;
    hw_module_t* module;
        hw_device_t* device;

        ALOGI("native ledOpen ...");

        /* 1. hw_get_module */
    err = hw_get_module("led", (hw_module_t const**)&module);
    if (err == 0) {
                /* 2. get device : module->methods->open */
            err = module->methods->open(module, NULL, &device);
            if (err == 0) {
                        /* 3. call led_open */
                led_device = (led_device_t *)device;
                        return led_device->led_open(led_device);
            } else {
                return -1;
            }
    }
        
    return -1;        
}

void ledClose(JNIEnv *env, jobject cls)
{
        //ALOGI("native ledClose ...");
        //close(fd);
}


jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
        ALOGI("native ledCtrl %d, %d", which, status);
        return led_device->led_ctrl(led_device, which, status);
}


static const JNINativeMethod methods[] = {
        {"native_ledOpen", "()I", (void *)ledOpen},
        {"native_ledClose", "()V", (void *)ledClose},
        {"native_ledCtrl", "(II)I", (void *)ledCtrl},
};
        

int register_android_server_LedService(JNIEnv *env)
{
    return jniRegisterNativeMethods(env, "com/android/server/LedService",
            methods, NELEM(methods));
}

}

4.修改onload.cpp文件

(1)在onload.cpp文件中添加函数声明和函数调用。

namespace android {
    /* 添加一行函数声明 */
    int register_android_server_LedService(JNIEnv *env);
}
using namespace android;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    /* 添加一行函数调用 */
    register_android_server_LedService(env);
}

5.编写HAL文件

  1. 实现一个名为HMI的hw_module_t结构体 。

  1. 实现一个open函数, 它返回led_device_t结构体。

  1. 实现led_device_t结构体 。

led_hal.h:

 #ifndef ANDROID_LED_INTERFACE_H

 #define ANDROID_LED_INTERFACE_H

 #include <stdint.h>

 #include <sys/cdefs.h>

 #include <sys/types.h>

 #include <hardware/hardware.h>

 __BEGIN_DECLS

 struct led_device_t {

 struct hw_device_t common;

 int (*led_open)(struct led_device_t* dev);

 int (*led_ctrl)(struct led_device_t* dev, int which, int status);

 };

 __END_DECLS

 #endif // ANDROID_LED_INTERFACE_H

led_hal.c:

#define LOG_TAG "LedHal"
/* 参考 hardware\libhardware\modules\vibrator\vibrator.c
 */

#include <hardware/vibrator.h>
#include <hardware/hardware.h>

#include <cutils/log.h>

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include <hardware/led_hal.h>

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <utils/Log.h>


static int fd;


/** Close this device */
static int led_close(struct hw_device_t* device)
{
        close(fd);
        return 0;
}

static int led_open(struct led_device_t* dev)
{
        fd = open("/dev/leds", O_RDWR);
        ALOGI("led_open : %d", fd);
        if (fd >= 0)
                return 0;
        else
                return -1;
}

static int led_ctrl(struct led_device_t* dev, int which, int status)
{
        int ret = ioctl(fd, status, which);
        ALOGI("led_ctrl : %d, %d, %d", which, status, ret);
        return ret;
}




static struct led_device_t led_dev = {
        .common = {
                .tag   = HARDWARE_DEVICE_TAG,
                .close = led_close,
        },
        .led_open  = led_open,
        .led_ctrl  = led_ctrl,
};

static int led_device_open(const struct hw_module_t* module, const char* id,
        struct hw_device_t** device)
{
        *device = &led_dev;
        return 0;
}


static struct hw_module_methods_t led_module_methods = {
    .open = led_device_open,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
        .tag = HARDWARE_MODULE_TAG,
    .id = "led",
    .methods = &led_module_methods,
};

HAL部分参考:

[Android硬件抽象层HAL总结](https://www.jianshu.com/p/0d155f267589)。

[Android HAL(硬件抽象层)介绍以及调用](https://blog.csdn.net/k229650014/article/details/5801397)