Android O重新設計了Android OS,以在獨立於設備的Android平台與特定於設備和供應商的代碼之間定義清晰的接口。 Android已經以HAL接口的形式定義了許多此類接口,這些接口在hardware/libhardware
定義為C頭。 HIDL用穩定的版本化接口替換了這些HAL接口,這些接口可以是C ++(如下所述)或Java的客戶端和服務器端HIDL接口。
本節中的頁面描述了HIDL接口的C ++實現,包括有關由hidl-gen
編譯器從HIDL .hal
文件自動生成的文件,如何打包這些文件以及如何將這些文件與C ++代碼集成的詳細信息。使用它們。
客戶端和服務器實施
HIDL接口具有客戶端和服務器實現:
- HIDL接口的客戶端是通過調用接口上的方法來使用該接口的代碼。
- 服務器是HIDL接口的實現,該接口接收來自客戶端的呼叫並返回結果(如有必要)。
從libhardware
HAL過渡到HIDL HAL時,HAL實現將成為服務器,而調用HAL的進程將成為客戶端。默認實現既可以為直通HAL也可以為綁定HAL提供服務,並且可以隨時間而變化:
圖1.舊式HAL的開發進度。
創建HAL客戶端
首先在makefile中包含HAL庫:
- 製作:
LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
- 宋:
shared_libs: [ …, android.hardware.nfc@1.0 ]
接下來,包括HAL頭文件:
#include <android/hardware/nfc/1.0/IFoo.h> … // in code: sp<IFoo> client = IFoo::getService(); client->doThing();
創建HAL服務器
要創建HAL實現,您必須具有代表您的HAL的.hal
文件,並且已經在hidl-gen
上使用-Lmakefile
或-Landroidbp
為HAL生成了makefile( ./hardware/interfaces/update-makefiles.sh
為此內部HAL文件,是一個很好的參考)。從libhardware
傳輸HAL時,您可以使用c2hal輕鬆地完成很多工作。
要創建必要的文件以實現您的HAL:
PACKAGE=android.hardware.nfc@1.0 LOC=hardware/interfaces/nfc/1.0/default/ m -j hidl-gen 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
為了使HAL以直通模式工作,您必須在/(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so
具有函數HIDL_FETCH_IModuleName 。其中OPTIONAL_IDENTIFIER是標識直通實現的字符串。上面的命令會自動滿足直通模式的要求,這些命令也會創建android.hardware.nfc@1.0-impl
目標,但可以使用任何擴展名。例如android.hardware.nfc@1.0-impl-foo
使用-foo
來區分自己。
如果HAL是次要版本或另一個HAL的擴展,則應使用基本HAL來命名此二進製文件。例如, android.hardware.graphics.mapper@2.1
實現仍應位於名為android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER )
的二進製文件中。通常,此處的OPTIONAL_IDENTIFIER將包含實際的HAL版本。通過這樣命名二進製文件,2.0客戶端可以直接檢索它,而2.1客戶端可以上載該實現。
接下來,使用功能填充存根並設置守護程序。示例守護程序代碼(支持傳遞):
#include <hidl/LegacySupport.h> int main(int /* argc */, char* /* argv */ []) { return defaultPassthroughServiceImplementation<INfc>("nfc"); }
defaultPassthroughServiceImplementation
將dlopen()
提供的-impl
庫並將其作為綁定服務提供。守護程序代碼示例(用於純綁定服務):
int main(int /* argc */, char* /* argv */ []) { // This function must be called before you join to ensure the proper // number of threads are created. The threadpool will never exceed // size one because of this call. ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/); sp<INfc> nfc = new Nfc(); const status_t status = nfc->registerAsService(); if (status != ::android::OK) { return 1; // or handle error } // Adds this thread to the threadpool, resulting in one total // thread in the threadpool. We could also do other things, but // would have to specify 'false' to willJoin in configureRpcThreadpool. ::android::hardware::joinRpcThreadpool(); return 1; // joinRpcThreadpool should never return }
這個守護進程通常位於$PACKAGE + "-service-suffix"
(例如android.hardware.nfc@1.0-service
),但是它可以在任何地方。所述sepolicy特定類的HAL的是屬性hal_<module>
(例如, hal_nfc)
此屬性必須應用於運行特定HAL的守護程序(如果同一進程提供多個HAL,則可以對其應用多個屬性)。