Android P HIDL demo代碼編寫 (原創)


之前的文章已經分析了HIDL服務的注冊和調用,這篇文章來總結下一個HIDL的服務如何編寫。

縮寫HAL文件

 首先要確認放置文件夾和接口的包名,因為這跟后面使用腳本生成一部分代碼有關,一般默認的放在hardware/interfaces目錄下,我們寫一個簡單的IDemo.hal (hardware/interface/demo/1.0/IDemo.hal)

package android.hardware.demo@1.0;

interface IDemo {
    init(int32_t level) generates (int32_t initRet);

    getProperty(string key) generates (int32_t getResult, string value);
};

 生成接口的執行代碼

使用如下命令生成執行文件:

hidl-gen -o hardware/interfaces/demo/1.0/default -Lc++-impl -randroid.hardware:hardware/intefaces -randroid.hidl:system/libhidl/transport android.hardware.demo@1.0

這個命令會在hardware/interfaces/demo/1.0/default 下生成Demo.cpp 和 Demo.h兩個文件,上面那個接口文件里,getProperty里有兩個返回值,一般函數都只有一個返回值,那這個兩個返回值是回事呢?那我們看看生成的執行代碼是怎么樣的?

#include "Demo.h"

namespace android {
namespace hardware {
namespace demo {
namespace V1_0 {
namespace implementation {

Return<int32_t> Demo::init(int32_t level) {
//這種返回一個參數就按普通函數的做法,返回值就OK
return int32_t{}; } Return<void> Demo::getProperty(const hidl_string& key, getProperty_cb _hidl_cb ) { //這里將兩個返回值封裝到一個回調函數里,然后傳給調用者,使用如下 int result = 0; //使用map 里值來返回
  std::Map<hidl_string, hidl_string> demoMap = {
    {"one", "first"},
    {"two", "second"},
    {"three", "third"}
  };

  int result = -1;
  hidl_string value = "";
  auto findRet = demoMap.find(key);
  if(findRet != demoMap.end()){
    result = 0;
    value = findRet->second;
  }
  //這里就將result 和 value 作為參數直接回調給調用者
  _hidl_cb(result, value); return Void(); } } } } }

生成Android.bp

方法實現完了之后,就需要用命令再生成一個Android.bp

hidl-gen -o hardware/interfaces/demo/1.0/default -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.demo@1.0

執行命令之后,就會在hardeare/interfaces/demo/1.0/default/Android.bp

進入hardware/interface目錄下,執行./update-makefiles.sh之后,會生成demo/1.0/Android.bp 文件

現在有了兩個Android.bp之后,需要采用綁定模式來創建一個Demo服務,在demo/1.0/default下創建一個service.cpp

添加綁定模式的服務代碼

#include <android-base/logging.h>
#include <hidl/HidlTransportSupport.h>
#include <android/hardware/demo/1.0/IDemo.h>

#undef LOG_TAG
#define LOG_TAG "android.hardware.demo@1.0-service"

#include <hidl/LegacySupport.h>
#include "Demo.h"
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::demo::V1.0::implementation::Demo;

int main(){
    configureRpcThreadpool(4, true);
    Demo demo = new Demo();
    auto status = demo.registerAsService();
    if(status != android::OK){
        ALOGE("register demo As Service failed");
        return -1;
    }
    joinRpcThreadpool();
}

 然后再在demo/1.0/default下創建android.hardware.demo@1.0-service.rc

service demo_hal_service /vendor/bin/hw/android.hardware.demo@1.0-service
    class hal
    user  system
    group  system

在demo/1.0/default/Android.bp中增加 init_rc和 service.cpp的編譯項,並將cc_library_shared 改為 cc_binary ,具體如下:

cc_binary {
    name: "android.hardware.demo@1.0-service",
    relative_install_path: "hw",
    proprietary: true,
    init_rc: ["android.hardware.demo@1.0-service.rc"],
    srcs: [
        "Demo.cpp",
        "service.cpp"
    ],  
    shared_libs: [
        "libhidlbase",
        "libhidltransport",
        "libutils",
     "liblog",
"android.hardware.demo@1.0", ], }

 然后通過mmm 或 mm 的方式 就可以編譯出android.hardware.demo@1.0-service 和 android.hardware.demo@1.0-service.rc的服務了。

如果要自運行,添加上Selinux 的相關權限,可以參考其它HIDL 服務的selinux。

關於調用HIDL的接口,之前文章分析過,下面我們寫核心的幾句代碼:

#include <android/hardware/demo/1.0/IDemo.h>
sp<IDemo> mDemo = IDemo::getService();
mDemo->init(1);
string mValue;
mDemo->getProperty("two", [&](int result, string value) {
       if(result == 0)
             mVaule = value;
});

到這里,HIDL的Demo服務代碼可以結束了,后面可以增加復雜的Icallback HIDL接口相關的代碼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM