本文是在上文5. Android10增加硬件抽象层(HAL)模块访问内核驱动程序的基础上进行的,虚拟机环境就是上文结束时的环境。
实现HelloService在aosp10/frameworks/base/core/java/android/os/目录下新建IHelloService.aidl文件
package android.os;
interface IHelloService {
int wirteString(String str);
String readString();
}
在aosp10/frameworks/base/services/core/java/com/android/server目录下新HelloService.java文件
package com.android.server;
import android.content.Context;
import android.os.IHelloService;
import android.util.Slog;
public class HelloService extends IHelloService.Stub {
private static final String TAG = "HelloService";
HelloService() {
init_native();
}
public int wirteString(java.lang.String str){
return wirteString_native(str);
}
public java.lang.String readString() {
return readString_native();
}
private static native boolean init_native();
private static native int wirteString_native(String str);
private static native String readString_native();
};
修改aosp10/frameworks/base目录下的Android.bp,增加一行
"core/java/android/os/IHelloService.aidl",添加jni接口访问HAL层
HelloService通过init_native()、wirteString_native(String str)、readString_native()这三个jni函数来访问HAL层,这里来实现这三个jni函数。
在aosp10/frameworks/base/services/core/jni目录下新建com_android_server_HelloService.cpp文件
#define LOG_TAG "HelloService" #include#include "jni.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace android { //jstring to char* char* jstringTostring(JNIEnv* env, jstring jstr); //char* to jstring jstring stoJstring(JNIEnv* env, const char* pat); struct hello_device_t* device = NULL; static jstring hello_readString(JNIEnv* env, jobject clazz) { if(!device) { ALOGI("Hello JNI: device is not open."); return NULL; } char read_str[100]; device->read_string(device, (char *)&read_str); ALOGI("Hello JNI: read string %s from hello device.", read_str); return stoJstring(env,read_str); } static jint hello_writeString(JNIEnv* env, jobject clazz,jstring str) { if(!device) { ALOGI("Hello JNI: device is not open."); return -1; } char * local_str = jstringTostring(env,str); device->write_string(device, local_str); ALOGI("Hello JNI: write string %s to hello device.", local_str); return sizeof(local_str); } static inline int hello_device_open(const hw_module_t* module, struct hello_device_t** device) { return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device); } static jboolean hello_init(JNIEnv* env, jclass clazz) { hello_module_t* module; ALOGI("Hello JNI: initializing......"); if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) { ALOGI("Hello JNI: hello Stub found."); if(hello_device_open(&(module->common), &device) == 0) { ALOGI("Hello JNI: hello device is open."); return 0; } ALOGI("Hello JNI: failed to open hello device."); return -1; } ALOGI("Hello JNI: failed to get hello stub module."); return -1; } static const JNINativeMethod method_table[] = { { "init_native", "()Z", (void*)hello_init } , { "readString_native", "()Ljava/lang/String;", (void*)hello_readString } , { "wirteString_native", "(Ljava/lang/String;)I", (void*)hello_writeString } , } ; int register_android_server_HelloService(JNIEnv *env) { ALOGI("SystemServer :register_android_server_HelloService."); return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table)); } //jstring to char* char* jstringTostring(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn; } //char* to jstring jstring stoJstring(JNIEnv* env, const char* pat) { jclass strClass = env->FindClass("java/lang/String"); jmethodID ctorID = env->GetMethodID(strClass, " ", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(pat)); env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = env->NewStringUTF("utf-8"); return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); } };
修改aosp10/frameworks/base/services/core/jni目录下的Android.bp文件
"com_android_server_HelloService.cpp",
修改aosp10/frameworks/base/services/core/jni目录下的onload.cpp
int register_android_server_HelloService(JNIEnv* env);
// ......
register_android_server_HelloService(env);
向系统注册HelloService
修改aosp10/frameworks/base/services/java/com/android/server目录下的SystemServer.java文件
import com.android.server.HelloService;
// ......
traceBeginAndSlog("StartHelloService");
try {
ServiceManager.addService("hello_service", new HelloService());
} catch (Throwable e) {
reportWtf("starting HelloService", e);
}
traceEnd();
编译
cd ~/documents/aosp10 export TARGET_PREBUILT_KERNEL=/home/test/documents/msm/arch/arm64/boot/Image.lz4-dtb source build/envsetup.sh lunch aosp_walleye-userdebug time make -j16
报错
make api-stubs-docs-update-current-api
继续编译
time make -j16参考
Android应用程序访问linux驱动第三步:实现并向系统注册Service_阳光玻璃杯-CSDN博客
在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口_老罗的Android之旅-CSDN博客
在Ubuntu上为Android系统的Application frameworks层增加硬件访问服务_老罗的Android之旅-CSDN博客



