Android 6.0中添加硬件访问服务

来源:互联网 发布:域名米表 编辑:程序博客网 时间:2024/05/16 05:28

1. 添加硬件访问服务接口

在目录frameworks/base/core/java/android/os中添加IFregService.aidl接口文件

IFregService.aidl文件如下

package android.os;/** * {@hide} */interface IFregService{    void setVal(int val);    int getVal();}

注: 注释中需要添加{@hide},不然会出现编译问题


同时,修改frameworks/base目录下的Android.mk文件,在LOCAL_SRC_FILES变量添加IFregService.aidl值,如下:

LOCAL_SRC_FILES += \       ......       core/java/android/os/IFregService.aidl \       ......


2. 实现硬件访问服务

在frameworks/base/services/core/java/com/android/server目录中添加FregService.java文件

FregService.java文件
package com.android.server;import android.content.Context;import android.os.IFregService;import android.util.Slog;/** * @hide */public class FregService extends IFregService.Stub{    private static final String TAG = "FregService";    private int mPtr = 0;    FregService(){        mPtr = freg_init_native();        if (0 == mPtr)        {            Slog.e(TAG, "Failed to initialize freg service.");        }    }    public void setVal(int val){        if (0 == mPtr){            Slog.e(TAG, "Freg service is not initialized.");            return;        }        setVal_native(mPtr, val);    }    public int getVal(){        if (0 == mPtr){            Slog.e(TAG, "Freg service is not initialized.");            return 0;        }        return getVal_native(mPtr);    }    private static native int freg_init_native();    private static native void setVal_native(int ptr, int val);    private static native int getVal_native(int ptr);};
注: 注释中需要添加{@hide},不然会出现编译问题

3. 实现硬件访问服务的JNI接口

在frameworks/base/services/core/jni目录下添加com_android_server_FregService.cpp文件
com_android_server_FregService.cpp源文件
/************************************************************************** 文件: com_android_server_FregService.cpp* 作者: fantasy* 邮箱: fantasy@gmail.com * 创建时间: 2016年07月23日 星期六 08时32分51秒*************************************************************************/#define LOG_TAG "FregServiceJNI"#include "jni.h"#include "JNIHelp.h"#include "android_runtime/AndroidRuntime.h"#include <utils/misc.h>#include <utils/Log.h>#include <hardware/hardware.h>#include <hardware/freg.h>#include <stdio.h>namespace android{    /**     * 设置虚拟硬件设备freg的寄存器的值      */    static void freg_setVal(JNIEnv *env, jobject clazz, jint ptr, jint value)    {        /**         * 将参数ptr转换为freg_device_t的结构体变量          */        freg_device_t *device = (freg_device_t*)ptr;        if (!device)        {            ALOGE("Device freg is not open.");            return;        }        int val = value;        ALOGI("Set value %d to device freg.", val);        device->set_val(device, val);    }    /**     * 读取虚拟硬件设备freg的寄存器值     */    static jint freg_getVal(JNIEnv *env, jobject clazz, jint ptr)    {        /**         * 将参数ptr转换为freg_device_t的结构体变量          */        freg_device_t *device = (freg_device_t*)ptr;        if (!device)        {            ALOGE("Device freg is not open.");            return 0;        }        int val = 0;        device->get_val(device, &val);        ALOGI("Get value %d from device freg.", val);        return val;    }    /**     * 打开虚拟硬件设备freg     */    static inline int freg_device_open(const hw_module_t *module, struct freg_device_t **device)    {        return module->methods->open(module, FREG_HARDWARE_DEVICE_ID, (struct hw_device_t**)device);    }    /**     * 初始化虚拟硬件设备freg     */    static jint freg_init(JNIEnv *env, jclass clazz)    {        hw_module_t *module;        freg_device_t *device;        ALOGI("Initializing HAL stub freg......");        /**         * 加载硬件抽象层模块freg         */        int err = hw_get_module(FREG_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module);                if (err)        {            ALOGE("Couldn't load %s module (%s)", FREG_HARDWARE_MODULE_ID, strerror(-err));        } else {            ALOGI("Device freg found.");            /**             *  打开虚拟硬件设备freg             */            if (freg_device_open(module, &device) == 0)            {                ALOGI("Device freg is open.");                /**                 * 将freg_device_t接口转换为整型值返回                 */                return (jint)device;            }            ALOGE("Failed to open device freg.");            return 0;        }        ALOGE("Failed to get HAL stub freg.");        return 0;    }        /**     * Java本地接口方法表     */    static const JNINativeMethod method_table[] = {        {"freg_init_native", "()I", (void*)freg_init},        {"setVal_native", "(II)V", (void*)freg_setVal},        {"getVal_native", "(I)I", (void*)freg_getVal},    };    /**     * 注册Java本地接口方法     */    int register_android_server_FregService(JNIEnv *env)    {        return jniRegisterNativeMethods(env, "com/android/server/FregService", method_table, NELEM(method_table));    }}

同时,在目录frameworks/base/services/core/jni的onload.cpp文件中添加如下代码
#include "JNIHelp.h"#include "jni.h"#include "utils/Log.h"#include "utils/misc.h"namespace android {......int register_android_server_FregService(JNIEnv* env);};using namespace android;

4. 启动硬件访问服务

在frameworks/base/services/java/com/android/server目录下的SystemServer.java中,添加如下内容
private void startOtherServices() {    ......    if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {        ......        try{                Slog.i(TAG, "Freg Service");                ServiceManager.addService("freg", new FregService());            } catch (Throwable e) {                Slog.e(TAG, "Failure staring Freg Service", e);            }    ....    }}

5. 相关权限配置

对/system/sepolicy目录下的如下文件进行相应修改
device.tedomain.tefile_contextsservice.teservice_contextssystem_app.tesystem_server.teuntrusted_app.te

修改如下:

在device.te文件中添加

type freg_device, dev_type;
在domain.te文件中添加
allow domain freg_device:chr_file rw_file_perms;
在file_contexts文件中添加
/dev/freg           u:object_r:freg_device:s0
在service.te中文件中添加
type freg_service, system_api_service, system_server_service, service_manager_type;
在service_contexts文件中添加
freg                                      u:object_r:freg_service:s0
在system_server.te文件中添加
allow system_server freg_device:chr_file rw_file_perms;
在untrusted_app.te文件中添加
allow untrusted_app freg_service:service_manager find;
在system_app.te文件中添加
allow system_app freg_service:service_manager find;

不然APP中调用该freg_service服务时会出现问题,见:http://blog.csdn.net/fantasy_wxe/article/details/52013922

参考

《Android系统源代码情景分析》第2.4节

1 0
原创粉丝点击