• Android O HIDL Framework 层实现


    继续来记录 android 应用层到 HAL 层的通信打通过程,本篇随笔实现 framework 层面。

    framework 层的实现并不算杂,主要是依次完成 AIDL、JNI、SERVICE 的实现,代码量并不大就是比较分散,

    需要注意的是在实现方法调用、传参的过程中要仔细和耐心,我可以在这里可是吃了大亏。

     

    一、AIDL 实现:

    ① 创建 frameworks/base/core/java/android/hardware/hidldebug/IHidlDebugService.aidl 

    1 package android.hardware.hidldebug;
    2 
    3 interface IHidlDebugService {
    4     String hidl_debug_test(String str);
    5 }

    ② 修改 frameworks/base/Android.mk,将刚创建的AIDL文件名加入

     1 diff --git a/frameworks/base/Android.mk b/frameworks/base/Android.mk
     2 index a722b30..0911c6a 100755
     3 --- a/frameworks/base/Android.mk
     4 +++ b/frameworks/base/Android.mk
     5 @@ -201,6 +201,7 @@ LOCAL_SRC_FILES += 
     6         core/java/android/hardware/hdmi/IHdmiRecordListener.aidl 
     7         core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl 
     8         core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl 
     9 +       core/java/android/hardware/hidldebug/IHidlDebugService.aidl
    10         core/java/android/hardware/input/IInputManager.aidl 
    11         core/java/android/hardware/input/IInputDevicesChangedListener.aidl 
    12         core/java/android/hardware/input/ITabletModeChangedListener.aidl 

     

    二、JNI 实现:

    ① 创建 frameworks/base/services/core/jni/com_android_server_hidldebug_HidlDebugService.cpp

     1 #include <jni.h>
     2 #include <nativehelper/JNIHelp.h>
     3 #include <binder/IServiceManager.h>
     4 #include <android/hardware/hidldebug/1.0/IHidldebug.h>
     5 #include <log/log.h>
     6 
     7 using android::sp;
     8 using android::hardware::hidl_string;
     9 using android::hardware::hidldebug::V1_0::IHidldebug;
    10 
    11 namespace android {
    12 
    13 sp<IHidldebug> hw_device;
    14 
    15 static jstring charToJstring(JNIEnv *env, const char *pat) {
    16     
    17     jclass strClass = env->FindClass("java/lang/String");
    18     jmethodID ctorID = env->GetMethodID(strClass, "<init>","([BLjava/lang/String;)V");
    19     jbyteArray bytes = env->NewByteArray(strlen(pat));
    20     env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte *) pat);
    21     jstring encoding = env->NewStringUTF("utf-8");
    22     
    23     return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
    24 }
    25 
    26 static jstring android_server_hidldebug_HidlDebugService(JNIEnv* env,jobject /* clazz */, jstring name) {
    27     
    28     const char* str;
    29     jstring ret;
    30     str = env->GetStringUTFChars(name, NULL);
    31     
    32     ALOGW("JNI hidldebug android_server_hidldebug_HidlDebugService.");
    33     
    34     hw_device = IHidldebug::getService();
    35     if (hw_device == nullptr) {
    36           ALOGW("ALOGWJNI hidldebug failed to get IHidldebug service.");
    37           return NULL;
    38     }
    39     
    40     hw_device->helloWorld(str, [&](hidl_string result) {
    41             ALOGW("%s
    ", result.c_str());
    42             ret = charToJstring(env, result.c_str());
    43     });
    44     
    45     return ret;
    46 }
    47     
    48 /*
    49  * JNI registration.
    50  */
    51 static const JNINativeMethod gMethods[] = {
    52     { "hidl_debug_test_native", "(Ljava/lang/String;)Ljava/lang/String;", (void*)android_server_hidldebug_HidlDebugService },
    53 };
    54 
    55 int register_android_server_hidldebug_HidlDebugService(JNIEnv* env)
    56 {
    57     int res = jniRegisterNativeMethods(env, "com/android/server/hidldebug/HidlDebugService",
    58                 gMethods, NELEM(gMethods));
    59     LOG_FATAL_IF(res < 0, "Unable to register HidlDebugService native methods.");
    60     return res;
    61 }
    62 
    63 }; // namespace android

    ② 修改 frameworks/base/services/core/jni/onload.cpp,以便我们编译的JNI可以顺利的注册到系统中

     1 diff --git a/frameworks/base/services/core/jni/onload.cpp b/frameworks/base/services/core/jni/onload.cpp
     2 index e96bda9..011ca54 100755
     3 --- a/frameworks/base/services/core/jni/onload.cpp
     4 +++ b/frameworks/base/services/core/jni/onload.cpp
     5 @@ -23,6 +23,7 @@ namespace android {
     6  int register_android_server_AlarmManagerService(JNIEnv* env);
     7  int register_android_server_BatteryStatsService(JNIEnv* env);
     8  int register_android_server_ConsumerIrService(JNIEnv *env);
     9 +int register_android_server_hidldebug_HidlDebugService(JNIEnv *env);
    10  int register_android_server_InputApplicationHandle(JNIEnv* env);
    11  int register_android_server_InputWindowHandle(JNIEnv* env);
    12  int register_android_server_InputManager(JNIEnv* env);
    13 @@ -65,6 +66,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
    14 
    15      register_android_server_PowerManagerService(env);
    16      register_android_server_SerialService(env);
    17 +    register_android_server_hidldebug_HidlDebugService(env);
    18      register_android_server_InputApplicationHandle(env);
    19      register_android_server_InputWindowHandle(env);
    20      register_android_server_InputManager(env);

    ③ 修改 frameworks/base/services/core/jni/Android.mk,加入 JNI 源文件

     1 diff --git a/frameworks/base/services/core/jni/Android.mk b/frameworks/base/services/core/jni/Android.mk
     2 index 40d7bb7..382bbaf 100755
     3 --- a/frameworks/base/services/core/jni/Android.mk
     4 +++ b/frameworks/base/services/core/jni/Android.mk
     5 @@ -17,6 +17,7 @@ LOCAL_SRC_FILES += 
     6      $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp 
     7      $(LOCAL_REL_DIR)/com_android_server_HardwarePropertiesManagerService.cpp 
     8      $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp 
     9 +    $(LOCAL_REL_DIR)/com_android_server_hidldebug_HidlDebugService.cpp 
    10      $(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp 
    11      $(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp 
    12      $(LOCAL_REL_DIR)/com_android_server_input_InputWindowHandle.cpp 
    13 @@ -92,6 +93,7 @@ LOCAL_SHARED_LIBRARIES += 
    14      android.hardware.light@2.0 
    15      android.hardware.power@1.0 
    16      android.hardware.thermal@1.0 
    17 +    android.hardware.hidldebug@1.0 
    18      android.hardware.tv.cec@1.0 
    19      android.hardware.tv.input@1.0 
    20      android.hardware.vibrator@1.0 

    三、SERVICE 实现:

    ① 创建 frameworks/base/services/core/java/com/android/server/hidldebug/HidlDebugService.java

     1 package com.android.server.hidldebug;
     2 import android.hardware.hidldebug.IHidlDebugService;
     3 
     4 public class HidlDebugService extends IHidlDebugService.Stub {
     5     public HidlDebugService(){
     6       android.util.Log.d("HidlDebug", "Start IHidlDebugService...");
     7     }
     8 
     9     @Override
    10     public String hidl_debug_test(String names){
    11       android.util.Log.d("HidlDebug", "hidl_debug_test()");
    12           return hidl_debug_test_native(names);
    13     }
    14 
    15     private static native String hidl_debug_test_native(String names);

    ② 修改 frameworks/base/services/java/com/android/server/SystemServer.java,加入我们实现过的 service,保证其在系统时可以加入到 ServiceManager

     1 diff --git a/frameworks/base/services/java/com/android/server/SystemServer.java b/frameworks/base/services/java/com/android/server/SystemServer.java
     2 index 1eb63d7..2c1bf04 100755
     3 --- a/frameworks/base/services/java/com/android/server/SystemServer.java
     4 +++ b/frameworks/base/services/java/com/android/server/SystemServer.java
     5 @@ -113,6 +113,8 @@ import com.android.server.vr.VrManagerService;
     6  import com.android.server.webkit.WebViewUpdateService;
     7  import com.android.server.wm.WindowManagerService;
     8 
     9 +import com.android.server.hidldebug.HidlDebugService;
    10 +
    11  import dalvik.system.VMRuntime;
    12 
    13  import java.io.File;
    14 @@ -770,6 +772,10 @@ public final class SystemServer {
    15              telephonyRegistry = new TelephonyRegistry(context);
    16              ServiceManager.addService("telephony.registry", telephonyRegistry);
    17              traceEnd();
    18 +
    19 +            traceBeginAndSlog("StartHidlDebugService");
    20 +            ServiceManager.addService("zackary.HidlDebugService", new HidlDebugService());
    21 +            traceEnd();
    22 
    23              traceBeginAndSlog("StartEntropyMixer");
    24              mEntropyMixer = new EntropyMixer(context);

    四、代码编译

    1 可以选择重新编译整个系统或者 mmm frameworks/base 单独编译后将成果物拷贝到设备中
    2 如果在编译的过程中遇到缺少依赖的情况,例如 NEED BY ...
    3 这时可以使用 mmma 命令来主动编译缺少的依赖
    4 还可能遇到提示需要 update-api 的情况,只要 make update-api 后就可以解决

    五、测试验证

    ① 查看我们实现的 service 是否被成功加载

    1 / # service list | grep hidl
    2 75      zackary.HidlDebugService: [android.hardware.hidldebug.IHidlDebugService]

    ② 如果成功加载,可以使用 service call 来验证流程是否打通,call 之前不要忘记启动我们之前实现的 hidl service

    1 / # service call zackary.HidlDebugService 1 s16 zackary.
    2 Result: Parcel(
    3   0x00000000: 00000000 0000001e 0054005b 00730065 '........[.T.e.s.'
    4   0x00000010: 00200074 006f0052 00740075 006e0069 't. .R.o.u.t.i.n.'
    5   0x00000020: 005d0065 00480020 006c0065 006f006c 'e.]. .H.e.l.l.o.'
    6   0x00000030: 0020002c 0061007a 006b0063 00720061 ',. .z.a.c.k.a.r.'
    7   0x00000040: 002e0079 00000000                   'y.......        ')

    调用成功,可以看到是返回了一个 Parcel,内容正是我们在 HAL 中实现的字符串拼接后的结果,

    好的,framework 层就是这样来实现了,下一篇我们继续来完成一个简单的 android app 调用到本次实现的接口,最终来完善整体的调用过程。

     

  • 相关阅读:
    MySQL 不同版本数据导入的问题
    利用 ps 命令查看进程的位置
    MySQL 重置 root 密码
    killall 中的 signal
    Kafka 的安装及启动
    TypeScript 中 Optional Chaining 和 Nullish Coalescing
    Redis 的使用
    TypeScript 中限制对象键名的取值范围
    React17 使用 JSX 的情况下无须再显式导入 React
    使用 golang 获取远程地址视频的时间
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/13741370.html
Copyright © 2020-2023  润新知