Android 6.0中添加硬件访问服务
16lz
2021-01-23
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文件中添加
在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节更多相关文章
- Android实现文件上传功能(接收端用strust2)
- android 获取文件的扩展名和去掉文件的扩展名
- android平台上的文件下载,文件和文件的操作
- Android APK文件安装过程小结
- Android 文件操作
- android从资源文件中读取文件流显示
- android 快速移动sdCard的文件夹
- Android Studio module里面放switch语句报错 R文件找不到