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

Ngôn ngữ định nghĩa giao diện HAL hoặc HIDL (phát âm là "hide-l") là một ngôn ngữ mô tả giao diện (IDL) để chỉ định giao diện giữa HAL và người dùng của nó. Nó cho phép chỉ định các kiểu và các cuộc gọi phương thức, được thu thập vào các giao diện và gói. Nói rộng hơn, HIDL là một hệ thống giao tiếp giữa các cơ sở mã có thể được biên dịch độc lập.

HIDL được thiết kế để sử dụng cho giao tiếp giữa các quá trình (IPC). Giao tiếp giữa các quá trình được gọi là Binderized . Đối với các thư viện phải được liên kết với một quy trình, chế độ chuyển qua cũng có sẵn (không được hỗ trợ trong Java).

HIDL chỉ định cấu trúc dữ liệu và chữ ký phương thức, được tổ chức trong các giao diện (tương tự như một lớp) được thu thập thành các gói. Cú pháp của HIDL sẽ trông quen thuộc với các lập trình viên C ++ và Java, mặc dù với một bộ từ khóa khác. HIDL cũng sử dụng các chú thích kiểu Java.

Thiết kế HIDL

Mục tiêu của HIDL là khung có thể được thay thế mà không cần phải xây dựng lại HAL. HAL sẽ được xây dựng bởi các nhà cung cấp hoặc nhà sản xuất SOC và đưa vào một /vendor phân vùng của /vendor trên thiết bị, cho phép khuôn khổ, trong phân vùng riêng của nó, được thay thế bằng OTA mà không cần biên dịch lại HAL.

Thiết kế HIDL cân bằng các mối quan tâm sau:

  • Khả năng tương tác . Tạo giao diện có thể tương tác đáng tin cậy giữa các quy trình có thể được biên dịch với nhiều kiến ​​trúc, dãy công cụ và cấu hình xây dựng. Giao diện HIDL được tạo phiên bản và không thể thay đổi sau khi chúng được xuất bản.
  • Hiệu quả . HIDL cố gắng giảm thiểu số lượng các thao tác sao chép. Dữ liệu do HIDL xác định được gửi tới mã C ++ trong cấu trúc dữ liệu bố cục tiêu chuẩn C ++ có thể được sử dụng mà không cần giải nén. HIDL cũng cung cấp giao diện bộ nhớ chia sẻ và vì RPC vốn dĩ hơi chậm, HIDL hỗ trợ hai cách để truyền dữ liệu mà không cần sử dụng cuộc gọi RPC: bộ nhớ chia sẻ và Hàng đợi tin nhắn nhanh (FMQ).
  • Trực quan . HIDL tránh các vấn đề hóc búa về quyền sở hữu bộ nhớ bằng cách chỉ sử dụng in các tham số cho RPC (xem Ngôn ngữ Định nghĩa Giao diện Android (AIDL) ); các giá trị không thể được trả về một cách hiệu quả từ các phương thức được trả về thông qua các hàm gọi lại. Việc chuyển dữ liệu vào HIDL để truyền hay nhận dữ liệu từ HIDL đều không thay đổi quyền sở hữu dữ liệu — quyền sở hữu luôn duy trì với hàm gọi. Dữ liệu chỉ cần tồn tại trong khoảng thời gian của hàm được gọi và có thể bị hủy ngay sau khi hàm được gọi trả về.

Sử dụng chế độ chuyển qua

Để cập nhật các thiết bị chạy phiên bản Android cũ hơn lên Android O, bạn có thể bọc cả HAL thông thường (và kế thừa) trong giao diện HIDL mới phục vụ HAL ở chế độ liên kết và cùng một quy trình (chuyển qua). Gói này là trong suốt đối với cả HAL và Android framework.

Chế độ chuyển qua chỉ có sẵn cho ứng dụng C ++ và triển khai. Các thiết bị chạy phiên bản Android cũ hơn không có HAL được viết bằng Java, vì vậy HAL của Java vốn đã được ràng buộc.

Khi tệp .hal được biên dịch, hidl-gen tạo thêm tệp tiêu đề chuyển qua BsFoo.h ngoài các tiêu đề được sử dụng cho giao tiếp liên kết; tiêu đề này định nghĩa các hàm được dlopen ed. Khi các HAL chuyển qua chạy trong cùng một quá trình mà chúng được gọi, trong hầu hết các trường hợp, các phương thức truyền qua được gọi bằng lệnh gọi hàm trực tiếp (cùng một luồng). oneway phương pháp chạy trong chủ đề riêng của họ khi họ không có ý định chờ cho HAL để xử lý chúng (phương tiện này bất kỳ HAL mà sử dụng oneway phương pháp trong chế độ passthrough phải được thread-safe).

Với một IFoo.hal , BsFoo.h kết thúc tốt đẹp các phương pháp HIDL tạo để cung cấp các tính năng bổ sung (như làm oneway giao dịch chạy trong thread khác). Tệp này tương tự như BpFoo.h , tuy nhiên thay vì truyền IPC bằng cách sử dụng chất kết dính, các chức năng mong muốn được gọi trực tiếp. Việc triển khai HAL trong tương lai có thể cung cấp nhiều triển khai, chẳng hạn như FooFast HAL và FooAccurate HAL. Trong những trường hợp như vậy, một tệp cho mỗi lần triển khai bổ sung sẽ được tạo (ví dụ: PTFooFast.cppPTFooAccurate.cpp ).

Binderizing chuyển qua HAL

Bạn có thể ràng buộc các triển khai HAL hỗ trợ chế độ chuyển qua. Với giao diện HAL abcd@MN::IFoo , hai gói được tạo:

  • abcd@MN::IFoo-impl . Chứa việc triển khai HAL và hiển thị hàm IFoo* HIDL_FETCH_IFoo(const char* name) . Trên các thiết bị cũ, gói này được dlopen ed và việc triển khai được khởi tạo bằng HIDL_FETCH_IFoo . Bạn có thể tạo mã cơ sở bằng hidl-gen-Lc++-impl-Landroidbp-impl .
  • abcd@MN::IFoo-service . Mở HAL chuyển qua và tự đăng ký dưới dạng một dịch vụ được ràng buộc, cho phép việc triển khai HAL giống nhau được sử dụng như cả chuyển qua và liên kết.

Với kiểu IFoo , bạn có thể gọi sp<IFoo> IFoo::getService(string name, bool getStub) để có quyền truy cập vào một phiên bản của IFoo . Nếu getStub là true, getService cố gắng mở HAL ở chế độ chuyển qua. Nếu getStub là false, getService cố gắng tìm một dịch vụ được ràng buộc; nếu không thành công, nó sẽ cố gắng tìm dịch vụ chuyển qua. Tham số getStub không bao giờ được sử dụng ngoại trừ trong defaultPassthroughServiceImplementation . (Các thiết bị khởi chạy với Android O là các thiết bị được ràng buộc hoàn toàn, do đó, việc mở dịch vụ ở chế độ chuyển qua không được phép.)

Ngữ pháp HIDL

Theo thiết kế, ngôn ngữ HIDL tương tự như C (nhưng không sử dụng bộ tiền xử lý C). Tất cả các dấu câu không được mô tả bên dưới (ngoại trừ việc sử dụng =| ) rõ ràng là một phần của ngữ pháp.

Lưu ý: Để biết chi tiết về kiểu mã HIDL, hãy xem Hướng dẫn kiểu mã .

  • /** */ chỉ ra một nhận xét tài liệu. Chúng chỉ có thể được áp dụng cho các khai báo kiểu, phương thức, trường và giá trị enum.
  • /* */ cho biết một nhận xét nhiều dòng.
  • // cho biết chú thích đến cuối dòng. Ngoài // , các dòng mới giống với bất kỳ khoảng trắng nào khác.
  • Trong ví dụ ngữ pháp dưới đây, văn bản từ // đến cuối dòng không phải là một phần của ngữ pháp mà thay vào đó là một chú thích về ngữ pháp.
  • [empty] có nghĩa là thuật ngữ có thể trống.
  • ? theo sau một nghĩa đen hoặc thuật ngữ có nghĩa là nó là tùy chọn.
  • ... cho biết trình tự chứa không hoặc nhiều mục với dấu câu phân cách như đã chỉ ra. Không có đối số khác nhau trong HIDL.
  • Dấu phẩy phân tách các phần tử của dãy.
  • Dấu chấm phẩy kết thúc mỗi phần tử, kể cả phần tử cuối cùng.
  • UPPERCASE là một danh nghĩa.
  • italics là một họ mã thông báo như integer hoặc integer identifier (quy tắc phân tích cú pháp C chuẩn).
  • constexpr là một biểu thức hằng kiểu C (chẳng hạn như 1 + 11L << 3 ).
  • import_name là một gói hoặc tên giao diện, đủ điều kiện như được mô tả trong Phiên bản HIDL .
  • Các words thường là các mã thông báo theo nghĩa đen.

Thí dụ:

ROOT =
    PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... }  // not for types.hal
  | PACKAGE IMPORTS ITEM ITEM...  // only for types.hal; no method definitions

ITEM =
    ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?;
  |  safe_union identifier { UFIELD; UFIELD; ...};
  |  struct identifier { SFIELD; SFIELD; ...};  // Note - no forward declarations
  |  union identifier { UFIELD; UFIELD; ...};
  |  enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar
  |  typedef TYPE identifier;

VERSION = integer.integer;

PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION;

PREAMBLE = interface identifier EXTENDS

EXTENDS = <empty> | extends import_name  // must be interface, not package

GENERATES = generates (FIELD, FIELD ...)

// allows the Binder interface to be used as a type
// (similar to typedef'ing the final identifier)
IMPORTS =
   [empty]
  |  IMPORTS import import_name;

TYPE =
  uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t |
 float | double | bool | string
|  identifier  // must be defined as a typedef, struct, union, enum or import
               // including those defined later in the file
|  memory
|  pointer
|  vec<TYPE>
|  bitfield<TYPE>  // TYPE is user-defined enum
|  fmq_sync<TYPE>
|  fmq_unsync<TYPE>
|  TYPE[SIZE]

FIELD =
   TYPE identifier

UFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...};
  |  struct identifier { FIELD; FIELD; ...};
  |  union identifier { FIELD; FIELD; ...};
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SIZE =  // Must be greater than zero
     constexpr

ANNOTATIONS =
     [empty]
  |  ANNOTATIONS ANNOTATION

ANNOTATION =
  |  @identifier
  |  @identifier(VALUE)
  |  @identifier(ANNO_ENTRY, ANNO_ENTRY  ...)

ANNO_ENTRY =
     identifier=VALUE

VALUE =
     "any text including \" and other escapes"
  |  constexpr
  |  {VALUE, VALUE ...}  // only in annotations

ENUM_ENTRY =
     identifier
  |  identifier = constexpr

Thuật ngữ

Phần này sử dụng các thuật ngữ liên quan đến HIDL sau:

ràng buộc Cho biết HIDL đang được sử dụng cho các cuộc gọi thủ tục từ xa giữa các quy trình, được thực hiện trên cơ chế giống như Binder. Xem thêm thông qua .
gọi lại, không đồng bộ Giao diện do người dùng HAL phục vụ, được chuyển tới HAL (thông qua phương thức HIDL) và được HAL gọi để trả về dữ liệu bất kỳ lúc nào.
gọi lại, đồng bộ Trả về dữ liệu từ triển khai phương thức HIDL của máy chủ cho máy khách. Không được sử dụng cho các phương thức trả về giá trị void hoặc một giá trị nguyên thủy.
khách hàng Quy trình gọi các phương thức của một giao diện cụ thể. HAL hoặc quy trình khung có thể là máy khách của một giao diện và máy chủ của một giao diện khác. Xem thêm thông qua .
kéo dài Cho biết một giao diện bổ sung các phương thức và / hoặc kiểu vào một giao diện khác. Một giao diện chỉ có thể mở rộng một giao diện khác. Có thể được sử dụng để tăng phiên bản nhỏ trong cùng một tên gói hoặc cho một gói mới (ví dụ: phần mở rộng của nhà cung cấp) để xây dựng trên một gói cũ hơn.
tạo ra Chỉ ra một phương thức giao diện trả về các giá trị cho máy khách. Để trả về một giá trị không phải nguyên thủy hoặc nhiều giá trị, một hàm gọi lại đồng bộ sẽ được tạo.
giao diện Bộ sưu tập các phương pháp và loại. Được dịch thành một lớp trong C ++ hoặc Java. Tất cả các phương thức trong một giao diện được gọi theo cùng một hướng: một tiến trình máy khách gọi các phương thức được thực hiện bởi một tiến trình máy chủ.
một chiều Khi được áp dụng cho một phương thức HIDL, cho biết phương thức không trả về giá trị nào và không chặn.
gói hàng Tập hợp các giao diện và kiểu dữ liệu dùng chung một phiên bản.
chuyển qua Phương thức HIDL trong đó máy chủ là một thư viện chia sẻ, dlopen ed của khách hàng. Trong chế độ chuyển qua, máy khách và máy chủ là cùng một quy trình nhưng các cơ sở mã riêng biệt. Chỉ được sử dụng để đưa các cơ sở mã kế thừa vào mô hình HIDL. Xem thêm Binderized .
người phục vụ Quy trình thực hiện các phương thức của một giao diện. Xem thêm thông qua .
vận chuyển Cơ sở hạ tầng HIDL di chuyển dữ liệu giữa máy chủ và máy khách.
phiên bản Phiên bản của một gói. Bao gồm hai số nguyên, chính và phụ. Các bước tăng phiên bản nhỏ có thể thêm (nhưng không thay đổi) các loại và phương pháp.