Giao diện & Gói

HIDL được xây dựng xung quanh các giao diện, một kiểu trừu tượng được sử dụng trong các ngôn ngữ hướng đối tượng để xác định hành vi. Mỗi giao diện là một phần của một gói.

Gói

Tên gói có thể có các cấp độ con như package.subpackage . Thư mục gốc của các gói HIDL được xuất bản là hardware/interfaces hoặc vendor/vendorName (ví dụ: vendor/google dành cho thiết bị Pixel). Tên gói tạo thành một hoặc nhiều thư mục con trong thư mục gốc; tất cả các tệp xác định một gói đều nằm trong cùng một thư mục. Ví dụ: package android.hardware.example.extension.light@2.0 có thể được tìm thấy trong hardware/interfaces/example/extension/light/2.0 .

Bảng sau liệt kê các tiền tố và vị trí của gói:

Tiền tố gói Vị trí Các loại giao diện
android.hardware.* hardware/interfaces/* HAL
android.frameworks.* frameworks/hardware/interfaces/* khung/liên quan
android.system.* system/hardware/interfaces/* hệ thống/liên quan
android.hidl.* system/libhidl/transport/* cốt lõi

Thư mục gói chứa các tệp có phần mở rộng .hal . Mỗi tệp phải chứa một câu lệnh package đặt tên cho gói và phiên bản mà tệp đó là một phần. Tệp types.hal , nếu có, không xác định giao diện mà thay vào đó xác định các loại dữ liệu có thể truy cập được đối với mọi giao diện trong gói.

Định nghĩa giao diện

Ngoài types.hal , mọi tệp .hal khác đều xác định một giao diện. Một giao diện thường được định nghĩa như sau:

interface IBar extends IFoo { // IFoo is another interface
    // embedded types
    struct MyStruct {/*...*/};

    // interface methods
    create(int32_t id) generates (MyStruct s);
    close();
};

Một giao diện không có khai báo extends rõ ràng sẽ ngầm mở rộng từ android.hidl.base@1.0::IBase (tương tự như java.lang.Object trong Java.) Giao diện IBase, được nhập ngầm, khai báo một số phương thức dành riêng không nên và không thể được khai báo lại trong các giao diện do người dùng xác định hoặc được sử dụng theo cách khác. Những phương pháp này bao gồm:

  • ping
  • interfaceChain
  • interfaceDescriptor
  • notifySyspropsChanged
  • linkToDeath
  • unlinkToDeath
  • setHALInstrumentation
  • getDebugInfo
  • debug
  • getHashChain

Nhập khẩu

Câu lệnh import là cơ chế HIDL để truy cập các giao diện và loại gói trong gói khác. Một câu lệnh import liên quan đến hai thực thể:

  • Thực thể nhập , có thể là gói hoặc giao diện; Và
  • Thực thể được nhập, cũng có thể là gói hoặc giao diện.

Thực thể nhập khẩu được xác định bởi vị trí của báo cáo import . Khi câu lệnh nằm trong types.hal của một gói, toàn bộ gói sẽ hiển thị những gì đang được nhập; đây là một lần nhập cấp gói . Khi câu lệnh nằm trong một tệp giao diện, thực thể nhập chính là giao diện đó; đây là một lần nhập ở cấp độ giao diện .

Thực thể được nhập được xác định bởi giá trị sau từ khóa import . Giá trị không nhất thiết phải là tên đủ điều kiện; nếu một thành phần bị bỏ qua, nó sẽ tự động được điền thông tin từ gói hiện tại. Đối với các giá trị đủ điều kiện, các trường hợp nhập sau được hỗ trợ:

  • Nhập khẩu nguyên kiện . Nếu giá trị là tên gói và phiên bản (cú pháp được mô tả bên dưới) thì toàn bộ gói sẽ được nhập vào thực thể nhập.
  • Nhập khẩu một phần . Nếu giá trị là:
    • Một giao diện, types.hal của gói và giao diện đó được nhập vào thực thể nhập.
    • Một UDT được xác định trong types.hal thì chỉ UDT đó được nhập vào thực thể nhập (các loại khác trong types.hal không được nhập).
  • Chỉ nhập khẩu các loại . Nếu giá trị sử dụng cú pháp nhập một phần được mô tả ở trên, nhưng với từ khóa types thay vì tên Giao diện thì chỉ các UDT trong types.hal của gói được chỉ định mới được nhập.

Thực thể nhập khẩu có quyền truy cập vào sự kết hợp của:

  • UDT chung của gói đã nhập được xác định trong types.hal ;
  • Giao diện của gói đã nhập (đối với nhập toàn bộ gói) hoặc giao diện được chỉ định (đối với nhập một phần) nhằm mục đích gọi chúng, chuyển các thẻ điều khiển cho chúng và/hoặc kế thừa từ chúng.

Câu lệnh nhập sử dụng cú pháp tên loại đủ điều kiện để cung cấp tên và phiên bản của gói hoặc giao diện đang được nhập:

import android.hardware.nfc@1.0;            // import a whole package
import android.hardware.example@1.0::IQuux; // import an interface and types.hal
import android.hardware.example@1.0::types; // import just types.hal

Kế thừa giao diện

Giao diện có thể là phần mở rộng của giao diện được xác định trước đó. Tiện ích mở rộng có thể là một trong ba loại sau:

  • Giao diện có thể thêm chức năng vào một giao diện khác, kết hợp API của nó không thay đổi.
  • Gói có thể thêm chức năng cho gói khác, kết hợp API của nó không thay đổi.
  • Giao diện có thể nhập các loại từ một gói hoặc từ một giao diện cụ thể.

Một giao diện chỉ có thể mở rộng một giao diện khác (không có nhiều kế thừa). Mỗi giao diện trong gói có số phiên bản phụ khác 0 phải mở rộng giao diện trong phiên bản trước của gói. Ví dụ: nếu giao diện IBar trong phiên bản 4.0 của gói derivative dựa trên (mở rộng) giao diện IFoo trong phiên bản 1.2 của gói original và phiên bản 1.3 của gói original được tạo, thì phiên bản IBar 4.1 không thể mở rộng phiên bản 1.3 của IFoo . Thay vào đó, phiên bản IBar 4.1 phải mở rộng phiên bản IBar 4.0, được gắn với phiên bản IFoo 1.2. Phiên bản IBar 5.0 có thể mở rộng phiên bản IFoo 1.3 nếu muốn.

Các phần mở rộng giao diện không ngụ ý sự phụ thuộc vào thư viện hoặc bao gồm HAL chéo trong mã được tạo ra—chúng chỉ đơn giản nhập cấu trúc dữ liệu và định nghĩa phương thức ở cấp HIDL. Mọi phương thức trong HAL phải được triển khai trong HAL đó.

Tiện ích mở rộng nhà cung cấp

Trong một số trường hợp, tiện ích mở rộng của nhà cung cấp sẽ được triển khai dưới dạng lớp con của đối tượng cơ sở đại diện cho giao diện cốt lõi mà chúng mở rộng. Đối tượng tương tự sẽ được đăng ký dưới tên và phiên bản HAL cơ sở cũng như dưới tên và phiên bản HAL của tiện ích mở rộng (nhà cung cấp).

Phiên bản

Các gói được tạo phiên bản và các giao diện có phiên bản của gói đó. Các phiên bản được thể hiện bằng hai số nguyên, chính . người vị thành niên .

  • Các phiên bản chính không tương thích ngược. Việc tăng số phiên bản chính sẽ đặt lại số phiên bản phụ thành 0.
  • Các phiên bản nhỏ có khả năng tương thích ngược. Việc tăng số phụ cho biết phiên bản mới hơn hoàn toàn tương thích ngược với phiên bản trước. Cấu trúc dữ liệu và phương thức mới có thể được thêm vào nhưng không thể thay đổi cấu trúc dữ liệu hoặc chữ ký phương thức hiện có.

Nhiều phiên bản chính hoặc phụ của HAL có thể xuất hiện đồng thời trên một thiết bị. Tuy nhiên, phiên bản phụ nên được ưu tiên hơn phiên bản chính vì mã máy khách hoạt động với giao diện phiên bản phụ trước đó cũng sẽ hoạt động với các phiên bản phụ sau này của cùng giao diện đó. Để biết thêm chi tiết về lập phiên bản và tiện ích mở rộng của nhà cung cấp, hãy xem Phiên bản HIDL .

Tóm tắt bố cục giao diện

Phần này tóm tắt cách quản lý gói giao diện HIDL (chẳng hạn như hardware/interfaces ) và hợp nhất thông tin được trình bày trong phần HIDL. Trước khi đọc, hãy đảm bảo rằng bạn đã quen thuộc với Phiên bản HIDL , các khái niệm băm trong Băm với hidl-gen , các chi tiết làm việc với HIDL nói chung và các định nghĩa sau:

Thuật ngữ Sự định nghĩa
Giao diện nhị phân ứng dụng (ABI) Giao diện lập trình ứng dụng + bất kỳ liên kết nhị phân nào được yêu cầu.
Tên đủ điều kiện (fqName) Tên để phân biệt một loại hidl. Ví dụ: android.hardware.foo@1.0::IFoo .
Bưu kiện Gói chứa giao diện HIDL và các loại. Ví dụ: android.hardware.foo@1.0 .
Gói gốc Gói gốc chứa giao diện HIDL. Ví dụ: giao diện HIDL android.hardware nằm trong gói root android.hardware.foo@1.0 .
Đường dẫn gốc gói Vị trí trong cây nguồn Android nơi gốc gói ánh xạ tới.

Để biết thêm định nghĩa, hãy xem Thuật ngữ HIDL.

Mọi tệp có thể được tìm thấy từ ánh xạ gốc của gói và tên đủ điều kiện của nó

Gốc gói được chỉ định cho hidl-gen làm đối số -r android.hardware:hardware/interfaces . Ví dụ: nếu gói là vendor.awesome.foo@1.0::IFoohidl-gen được gửi -r vendor.awesome:some/device/independent/path/interfaces thì tệp giao diện phải được đặt trong $ANDROID_BUILD_TOP/some/device/independent/path/interfaces/foo/1.0/IFoo.hal .

Trong thực tế, nhà cung cấp hoặc OEM có tên awesome nên đặt giao diện tiêu chuẩn của họ trong vendor.awesome . Sau khi đường dẫn gói đã được chọn, nó không được thay đổi vì đường dẫn này được đưa vào ABI của giao diện.

Ánh xạ đường dẫn gói phải là duy nhất

Ví dụ: nếu bạn có -rsome.package:$PATH_A-rsome.package:$PATH_B , $PATH_A phải bằng $PATH_B cho một thư mục giao diện nhất quán (điều này cũng làm cho giao diện lập phiên bản dễ dàng hơn nhiều).

Gốc gói phải có tệp phiên bản

Nếu bạn tạo một đường dẫn gói chẳng hạn như -r vendor.awesome:vendor/awesome/interfaces , bạn cũng nên tạo tệp $ANDROID_BUILD_TOP/vendor/awesome/interfaces/current.txt , tệp này sẽ chứa các giá trị băm của giao diện được tạo bằng cách sử dụng -Lhash tùy chọn trong hidl-gen (điều này được thảo luận rộng rãi trong Băm với hidl-gen ).

Giao diện đi ở các vị trí độc lập với thiết bị

Trong thực tế, nên chia sẻ giao diện giữa các nhánh. Điều này cho phép tái sử dụng mã tối đa và kiểm tra mã tối đa trên các thiết bị và trường hợp sử dụng khác nhau.