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 #include #include #include #include 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. Android实现文件上传功能(接收端用strust2)
  2. android 获取文件的扩展名和去掉文件的扩展名
  3. android平台上的文件下载,文件和文件的操作
  4. Android APK文件安装过程小结
  5. Android 文件操作
  6. android从资源文件中读取文件流显示
  7. android 快速移动sdCard的文件夹
  8. Android Studio module里面放switch语句报错 R文件找不到

随机推荐

  1. Android(安卓)Studio 主题如何黑色变为白
  2. 【Android】Menu详解
  3. Android(安卓)Studio 3.6.2 | 使用内置文
  4. android ctivity完美退出
  5. Android(安卓)自定义底部上拉控件的实现
  6. Android(安卓)在Launcher桌面添加应用快
  7. 一个有趣的android加载动画
  8. 细看 Google+ 里最有希望成为杀手级应用
  9. Android(安卓)9.0实现系统内录(只录制系统
  10. 关于Android中的Intent一点说明