美文网首页
HIDL服务编写实现

HIDL服务编写实现

作者: Lazy1 | 来源:发表于2022-03-02 17:18 被阅读0次

    HIDL则是用来连接Framework和HAL通信,调用HAL层,AOSP的hardware/interfaces/目录下有很多的HIDL

    • 一般目录都是hardware/interfaces/xx下,这里我们看fingerprint,具体的位置在 hardware/interface/biometrics/fingerprint/2.1/ 目录下有个 IBiometricsFingerprint.hal
    
    package android.hardware.biometrics.fingerprint@2.1;
    
    import IBiometricsFingerprintClientCallback;
    
    interface IBiometricsFingerprint {
      /**
       * Set notification callback:
       * Registers a user function that must receive notifications from the HAL
       * This call must block if the HAL state machine is in busy state until HAL
       * leaves the busy state.
       *
       * @return deviceId is a unique handle for this fingerprint device
          这个方法是在HAL层定义的方法
       */
      @callflow(next={"setActiveGroup"})
      @entry
      setNotify(IBiometricsFingerprintClientCallback clientCallback)
          generates (uint64_t deviceId);
     
    };
    
    
    
    • 然后就可以使用Android提供的工具hidl-gen来生成HIDL框架,执行如下命令:
    PACKAGE=android.hardware.fingerprint_hidl@2.1
    LOC=hardware/interfaces/biometrics/fingerprint/2.1/default/
    hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
    hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
    
    • 执行命令成功之后我们会发现hardware/interface/biometrics/fingerprint/2.1/下多了一个default目录,进入default目录,里面有三个文件Android.bp,BiometricsFingerprint.cpp,BiometricsFingerprint.h
    • 之后再在执行./hardware/interfaces/update-makefiles.sh这个命令,update-makefiles.sh这个脚本目的是为HIDL生成对应Android.bp文件
    • 还需要编写一个 service.cpp
    #define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-service"
    
    #include <android/log.h>
    #include <hidl/HidlSupport.h>
    #include <hidl/HidlTransportSupport.h>
    #include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
    #include <android/hardware/biometrics/fingerprint/2.1/types.h>
    #include "BiometricsFingerprint.h"
    
    using android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
    using android::hardware::biometrics::fingerprint::V2_1::implementation::BiometricsFingerprint;
    using android::hardware::configureRpcThreadpool;
    using android::hardware::joinRpcThreadpool;
    using android::sp;
    
    int main() {
        android::sp<IBiometricsFingerprint> bio = BiometricsFingerprint::getInstance();
    
        configureRpcThreadpool(1, true /*callerWillJoin*/);
    
        if (bio != nullptr) {
            if (::android::OK != bio->registerAsService()) {
                return 1;
            }
        } else {
            ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
        }
    
        joinRpcThreadpool();
    
        return 0; // should never get here
    }
    
    • 然后再 Android.bp 加上service.cpp
    cc_binary {
        name: "android.hardware.biometrics.fingerprint@2.1-service",
        defaults: ["hidl_defaults"],
        init_rc: ["android.hardware.biometrics.fingerprint@2.1-service.rc"],
        vendor: true,
        relative_install_path: "hw",
        srcs: [
            "BiometricsFingerprint.cpp",
            "service.cpp",
        ],
    
        shared_libs: [
            "libcutils",
            "liblog",
            "libhidlbase",
            "libhidltransport",
            "libhardware",
            "libutils",
            "android.hardware.biometrics.fingerprint@2.1",
        ],
    
    }
    
    • HIDL想要被Framework获取使用还需要在manifest.xml中注册,将这个hwservice注册到系统(这样getService()才能找到它) 在/device/(Vender)/(Product)/manifest.xml中添加: 例如: \device\mediatek\mt6771
    • 然后执行 mmm hardware/interface/biometrics/fingerprint/2.1/ 就会进行编译,并且生成so库
    • 对应java层调用直接可以用这样方式调用
     public synchronized IBiometricsFingerprint getFingerprintDaemon() {
            if (mDaemon == null) {
                Slog.v(TAG, "mDaemon was null, reconnect to fingerprint");
                try {
                    mDaemon = IBiometricsFingerprint.getService();
                } catch (java.util.NoSuchElementException e) {
                    // Service doesn't exist or cannot be opened. Logged below.
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to get biometric interface", e);
                }
             
            }
            return mDaemon;
        }
    

    getService 方式就可以引用到HIDL层代码使用

    • 还有在JNI层中也可以通过类似于 IGnss_V1_1::getService() 获取到HIDL层对象来达到调用
    • HIDL中自动在defaut中生成文件xx.cpp以后需要在 HIDL_FETCH_XXX中进行HAL层的初始化操作
    IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
        hw_module_t* module;
        IGnss* iface = nullptr;
        int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    
        if (err == 0) {
            hw_device_t* device;
            err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
            if (err == 0) {
                iface = new Gnss(reinterpret_cast<gps_device_t*>(device));
            } else {
                ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
            }
        } else {
          ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
        }
        return iface;
    }
    
    

    相关文章

      网友评论

          本文标题:HIDL服务编写实现

          本文链接:https://www.haomeiwen.com/subject/eknsrrtx.html