之前的文章已經分析了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 valuehttps://www.cnblogs.com/jack2010/p/= "";
auto findRet = demoMap.find(key);
if(findRet != demoMap.end()){
result = 0;
value = https://www.cnblogs.com/jack2010/p/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 "[email protected]" #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下創建[email protected]
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: "[email protected]", relative_install_path: "hw", proprietary: true, init_rc: ["[email protected]"], srcs: [ "Demo.cpp", "service.cpp" ], shared_libs: [ "libhidlbase", "libhidltransport", "libutils",
"liblog", "[email protected]", ], }
然后通過mmm 或 mm 的方式 就可以編譯出[email protected] 和 [email protected]的服務了,
如果要自運行,添加上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介面相關的代碼,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/30661.html
標籤:C++
上一篇:判斷一個數是否為素數(質數)
下一篇:關于使用ffmpeg的一些牢騷
