HIDL C++

Android 8 重新設計 Android 作業系統,以定義 Android 作業系統 獨立 Android 平台,以及裝置及供應商專屬程式碼。 Android 已經以 HAL 介面的形式定義許多這類介面 在 hardware/libhardware 中定義為 C 標頭HIDL 取代了上述兩欄 HAL 介面搭配穩定版介面,介面可能為用戶端 C++ 中的伺服器端 HIDL 介面 (如下所述),或 Java

本節的頁面會說明 HIDL 介面的 C++ 實作。 包含 HIDL .hal 自動產生的檔案詳細資料 檔案,hidl-gen編譯器的封裝方式和 ,瞭解如何將這些檔案與使用這些檔案的 C++ 程式碼整合。

用戶端和伺服器實作

HIDL 介面具有用戶端和伺服器實作項目:

  • HIDL 介面的用戶端是指使用 存取介面。
  • 伺服器是 HIDL 介面的實作, 即可接收來自用戶端的呼叫並傳回結果 (如有需要)。

libhardware HAL 轉換為 HIDL HAL 會成為伺服器,呼叫 HAL 的程序就會變成 用戶端。預設實作方式可放送直通式和繫結機制 HAL,且可能隨時間改變:

圖 1. 舊版 HAL 的開發進度。

建立 HAL 用戶端

請先在 makefile 中加入 HAL 程式庫:

  • 廠牌:LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
  • Soong: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,而且已經透過 -Lmakefilehidl-gen上的-Landroidbp (./hardware/interfaces/update-makefiles.sh 會對內部使用 HAL 檔案,是實用的參考資源)。從 HAL 轉移過來時 libhardware,只要使用 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 能夠以直通模式運作,您必須具備 HIDL_FETCH_IModuleName 函式所在的位置 /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl(OPTIONAL_IDENTIFIER).so 其中 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 客戶可以升級實作方式

接著,填寫功能片段並設定 Daemon。範例 Daemon 程式碼 (支援直通式):

#include <hidl/LegacySupport.h>

int main(int /* argc */, char* /* argv */ []) {
    return defaultPassthroughServiceImplementation<INfc>("nfc");
}

defaultPassthroughServiceImplementation 次通話 針對提供的 -impl 程式庫的 dlopen(),並提供做為 透過繫結服務處理Daemon 程式碼範例 (適用於純繫結化服務):

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 never exceeds
    // 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
}

這個 Daemon 通常位於 $PACKAGE + "-service-suffix" (用於 例如 android.hardware.nfc@1.0-service),但它可以任何地方。 特定情況下的 sepolicy HAL 的類別是 hal_<module> 屬性 (例如 hal_nfc)。此屬性必須套用至執行 特定 HAL (如果同一個處理程序提供多項 HAL 和多個屬性) 可套用於標籤中