android hal学习——aidl,java service,jni编写
一、参考
二、代码
1、aidl相关
1)aidl文件定义
位置:
frameworks/base/core/java/android/os/IExampleService.aidl
package android.os;interface IExampleService { void setVal(int val); int getVal();}
2)、修改相应的Android.mk
vim frameworks/base/Android.mk
找到下面的这句话:
## READ ME: ############################################################ When updating this list of aidl files, consider if that aidl is## part of the SDK API. If it is, also add it to the list below that## is preprocessed and distributed with the SDK. This list should## not contain any aidl files for parcelables, but the one below should## if you intend for 3rd parties to be able to send those objects## across process boundaries.#### READ ME: ########################################################LOCAL_SRC_FILES += \
在这个LOCAL_SRC_FILES后面增加:
。。。 core/java/android/os/IExampleService.aidl \
3)、编译aidl
mmm frameworks/base/... n Runtime shutdown[100% 8/8] Install: out/target/product/generic/system/framework/framework.jarmake: Leaving directory `/home/zzz/opensource/android-src'#### make completed successfully (03:34 (mm:ss)) ####
2、服务端service相关
1)实现服务端service功能
参考文章提到是在frameworks/base/services/java/com/android/server建立ExampleService.java来实现aidl接口,应该是版本不同,我这边需要则在以下目录下实现:
frameworks/base/services/core/java/com/android/server。
代码照旧copy:
package com.android.server;import android.content.Context;import android.os.IExampleService;import android.util.Slog;public class ExampleService extends IExampleService.Stub { private static final String TAG = "ExampleService"; private int mPtr = 0; ExampleService() { mPtr = init_native(); if(mPtr == 0) { Slog.e(TAG, "Failed to initialize example service."); } } public void setVal(int val) { if(mPtr == 0) { Slog.e(TAG, "Example service is not initialized."); return; } setVal_native(mPtr, val); } public int getVal() { if(mPtr == 0) { Slog.e(TAG, "Example service is not initialized."); return 0; } return getVal_native(mPtr); } private static native int init_native(); private static native void setVal_native(int ptr, int val); private static native int getVal_native(int ptr);};
2)、编译该service
mmm frameworks/base/services/core/ 。。。 ============================================Starting build with ninjaninja: Entering directory `.'[100% 5/5] build out/target/product/ge...rvices.core_intermediates/classes.jack make: Leaving directory `/home/zzz/opensource/android-src' #### make completed successfully (01:11 (mm:ss)) ####
3、jni相关
1)定义jni cpp文件
位置:frameworks/base/services/core/jni/com_android_server_ExampleService.cpp
#define LOG_TAG "ExampleServiceJNI"#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/example.h>#include <stdio.h>namespace android { static void example_setVal(JNIEnv* env, jobject clazz, jint ptr, jint value) { example_device_t* device = (example_device_t*)ptr; if(!device) { LOGE("Device example is not open."); return; } int val = value; LOGI("Set value %d to device example.", val); device->set_val(device, val); } static jint example_getVal(JNIEnv* env, jobject clazz, jint ptr) { example_device_t* device = (example_device_t*)ptr; if(!device) { LOGE("Device example is not open."); return 0; } int val = 0; device->get_val(device, &val); LOGI("Get value %d from device example.", val); return val; } static inline int example_device_open(const hw_module_t* module, struct example_device_t** device) { return module->methods->open(module, EXAMPLE_HARDWARE_DEVICE_ID, (struct hw_device_t**)device); } static jint example_init(JNIEnv* env, jclass clazz) { example_module_t* module; example_device_t* device; LOGI("Initializing HAL stub example......"); if(hw_get_module(EXAMPLE_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) { LOGI("Device example found."); if(example_device_open(&(module->common), &device) == 0) { LOGI("Device example is open."); return (jint)device; } LOGE("Failed to open device example."); return 0; } LOGE("Failed to get HAL stub example."); return 0; } static const JNINativeMethod method_table[] = { {"init_native", "()I", (void*)example_init}, {"setVal_native", "(II)V", (void*)example_setVal}, {"getVal_native", "(I)I", (void*)example_getVal}, }; int register_android_server_ExampleService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/ExampleService", method_table, NELEM(method_table)); }};
2)修改onload.cpp代码,增加相关的函数:
vim frameworks/base/services/core/jni/onload.cpp
namespace android {...int register_android_server_ExampleService(JNIEnv* env);};extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */){... register_android_server_ExampleService(env); return JNI_VERSION_1_4;}
3)修改Android.mk文件
vim frameworks/base/services/core/jni/Android.mk
增加LOCAL_SRC_FILES的内容:
LOCAL_SRC_FILES += \... $(LOCAL_REL_DIR)/com_android_server_ExampleService.cpp \ $(LOCAL_REL_DIR)/onload.cpp \
4)编译
mmm frameworks/base/services/core/jni/
... ============================================Starting build with ninjaninja: Entering directory `.'ninja: no work to do.make: Leaving directory `/home/zzz/opensource/android-src'#### make completed successfully (4 seconds) ####
4、将ExampleService加入到系统进程中
vim frameworks/base/services/java/com/android/server/SystemServer.java
增加:
814 815 816 //-----------begin-----------------// 817 try { 818 Slog.i(TAG, "Example Service"); 819 ServiceManager.addService("example", new ExampleService()); 820 } catch (Throwable e) { 821 Slog.e(TAG, "Failure starting Example Service", e); 822 } 823 //---------end---------//
5、重新编译frameworks/base/services模块:
mmm frameworks/base/services/
第一次编译出了点错误:
frameworks/base/services/core/jni/com_android_server_ExampleService.cpp:66:9: error: use of undeclared identifier 'LOGE' LOGE("Failed to get HAL stub example."); ^ 9 errors generated. ninja: build stopped: subcommand failed. make: *** [ninja_wrapper] Error 1make: Leaving directory `/home/zzz/opensource/android-src'#### make failed to build some targets (01:32 (mm:ss)) ####
将com_android_server_ExampleService.cpp里面的LOGE改为ALOGE,LOGI改为ALOGI,再编译:
mmm frameworks/base/services/
No need to regenerate ninja fileStarting build with ninjaninja: Entering directory `.'[100% 19/19] build out/target/product/...interaction_intermediates/classes.jack make: Leaving directory `/home/gumh/opensource/android-src' #### make completed successfully (6 seconds) ####
6、修改权限
为了避免无权访问/dev/example,修改以下文件:
vim system/core/rootdir/ueventd.rc
在最后面增加:
/dev/example 0666 root root
7、重新生成system.img
make snod
。。。make_ext4fs -T -1 -S out/target/product/generic/root/file_contexts.bin -L system -l 1610612736 -a system out/target/product/generic/system.img out/target/product/generic/system out/target/product/generic/systemCreating filesystem with parameters: Size: 1610612736 Block size: 4096 Blocks per group: 32768 Inodes per group: 8192 Inode size: 256 Journal blocks: 6144 Label: system Blocks: 393216 Block groups: 12 Reserved block group size: 95Created filesystem with 1751/98304 inodes and 146362/393216 blocksout/target/product/generic/system.img maxsize=1644333504 blocksize=2112 total=1610612736 reserve=16610880#### make completed successfully (19 seconds) ####
更多相关文章
- NFS挂载android文件系统
- android 9.0 SD卡权限问题 文件管理器没有权限
- material design 的android开源代码整理
- Android Studio代码混淆,开启Proguard,稍微总结一下
- android 读取文件内容操作