Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.
Trang này được dịch bởi Cloud Translation API.
Switch to English

HIDL C ++

Android O tái kiến ​​trúc hệ điều hành Android để xác định các giao diện rõ ràng giữa nền tảng Android độc lập với thiết bị và mã dành riêng cho thiết bị và nhà cung cấp. Android đã định nghĩa nhiều giao diện như vậy ở dạng giao diện HAL, được định nghĩa là tiêu đề C trong hardware/libhardware . HIDL thay thế các giao diện HAL này bằng các giao diện ổn định, có phiên bản, có thể là giao diện HIDL phía máy khách và phía máy chủ trong C ++ (mô tả bên dưới) hoặc Java .

Các trang trong phần này mô tả cách triển khai C ++ của giao diện HIDL, bao gồm chi tiết về các tệp được tạo tự động từ các tệp .hal bởi trình biên dịch hidl-gen , cách các tệp này được đóng gói và cách tích hợp các tệp này với mã C ++. sử dụng chúng.

Triển khai máy khách & máy chủ

Giao diện HIDL có triển khai máy khách và máy chủ:

  • Máy khách của giao diện HIDL là mã sử dụng giao diện bằng cách gọi các phương thức trên đó.
  • Máy chủ là một triển khai của giao diện HIDL nhận cuộc gọi từ máy khách và trả về kết quả (nếu cần).

Trong quá trình chuyển đổi từ libhardware HAL sang HIDL HAL, việc triển khai HAL trở thành máy chủ và quá trình gọi vào HAL trở thành máy khách. Các triển khai mặc định có thể phân phát cả HAL chuyển qua và được liên kết, đồng thời có thể thay đổi theo thời gian:

Hình 1. Tiến trình phát triển cho các HAL kế thừa.

Tạo ứng dụng khách HAL

Bắt đầu bằng cách đưa các thư viện HAL vào makefile:

  • Tạo: LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
  • Soong: shared_libs: [ …, android.hardware.nfc@1.0 ]

Tiếp theo, bao gồm các tệp tiêu đề HAL:

#include <android/hardware/nfc/1.0/IFoo.h>
…
// in code:
sp<IFoo> client = IFoo::getService();
client->doThing();

Tạo máy chủ HAL

Để tạo việc triển khai HAL, bạn phải có các tệp .hal đại diện cho HAL của bạn và đã tạo các tệp trang điểm cho HAL của bạn bằng cách sử dụng -Lmakefile hoặc -Landroidbp trên hidl-gen ( ./hardware/interfaces/update-makefiles.sh thực hiện việc này cho các tệp HAL nội bộ và là một tài liệu tham khảo tốt). Khi chuyển HALs từ libhardware , bạn có thể dễ dàng thực hiện nhiều công việc này bằng cách sử dụng c2hal.

Để tạo các tệp cần thiết để triển khai HAL của bạn:

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 hoạt động ở chế độ truyền, bạn phải có hàm HIDL_FETCH_IModuleName nằm trong /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so trong đó OPTIONAL_IDENTIFIER là một chuỗi xác định việc triển khai chuyển qua. Các yêu cầu về chế độ chuyển qua được đáp ứng tự động bởi các lệnh trên, lệnh này cũng tạo ra mục tiêu android.hardware.nfc@1.0-impl , nhưng có thể sử dụng bất kỳ phần mở rộng nào. Ví dụ: android.hardware.nfc@1.0-impl-foo sử dụng -foo để phân biệt chính nó.

Nếu một HAL là một phiên bản nhỏ hoặc một phần mở rộng của một HAL khác, thì HAL cơ sở nên được sử dụng để đặt tên cho hệ nhị phân này. Ví dụ: triển khai android.hardware.graphics.mapper@2.1 vẫn phải ở dạng nhị phân có tên android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER ) . Thông thường, OPTIONAL_IDENTIFIER ở đây sẽ bao gồm phiên bản HAL thực tế. Bằng cách đặt tên cho tệp nhị phân như thế này, các máy khách 2.0 có thể truy xuất trực tiếp và các máy khách 2.1 có thể upcast việc triển khai.

Tiếp theo, điền vào các sơ khai với chức năng và thiết lập một daemon. Mã daemon mẫu (hỗ trợ chuyển qua):

#include <hidl/LegacySupport.h>

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

defaultPassthroughServiceImplementation sẽ dlopen() thư viện -impl được cung cấp và cung cấp nó như một dịch vụ được ràng buộc. Mã daemon mẫu (cho dịch vụ ràng buộc thuần túy):

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
}

Daemon này thường sống trong $PACKAGE + "-service-suffix" (ví dụ: android.hardware.nfc@1.0-service ), nhưng nó có thể ở bất cứ đâu. Thuộc tính riêng cho một lớp HAL cụ thể là thuộc tính hal_<module> (ví dụ: hal_nfc) . Thuộc tính này phải được áp dụng cho daemon chạy một HAL cụ thể (nếu cùng một quá trình phân phát nhiều HAL, nhiều thuộc tính có thể được áp dụng cho nó).