Giao diện và gói

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

Gói

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

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

Tiền tố gói Vị trí 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/ có liên quan
android.hidl.* system/libhidl/transport/* core

Thư mục gói chứa các tệp có đuôi .hal. Mỗi tệp phải chứa câu lệnh package đặt tên cho gói và phiên bản có chứa tệp. Tệp types.hal, nếu có, sẽ không xác định giao diện mà xác định loại dữ liệu mà mọi trong gói.

Định nghĩa giao diện

Ngoài types.hal, mọi tệp .hal khác định nghĩa 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();
};

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

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

Quy trình nhập

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

  • Thực thểing nhập, có thể là một gói hoặc một giao diện
  • Thực thểed được nhập có thể là một gói hoặc một giao diện

Pháp nhân nhập được xác định theo vị trí của Câu lệnh import. Khi câu lệnh này nằm trong gói types.hal, nội dung đang được nhập sẽ hiển thị trên toàn bộ gói; đây là lần nhập cấp gói. Khi câu lệnh nằm bên trong một tệp giao diện, đối tượng nhập chính là chính giao diện đó; đây là một cấp giao diện.

Thực thể đã nhập được xác định theo giá trị sau import từ khoá. Giá trị không cần phải là tên đủ điều kiện; nếu một thành phần là đã bỏ qua, nó sẽ tự động được điền với 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 toàn bộ gói. Nếu giá trị là tên gói và (cú pháp được mô tả bên dưới), thì toàn bộ gói sẽ được nhập vào đang nhập thực thể.
  • Nhập 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 đối tượng nhập.
    • Một UDT được xác định trong types.hal, thì chỉ UDT đó được nhập vào đối tượng nhập (các loại khác trong types.hal sẽ không được nhập).
  • Chỉ nhập loại dữ liệu. Nếu giá trị sử dụng cú pháp của nhập một phần được mô tả ở trên, nhưng với từ khóa types thay thế tên Giao diện, chỉ các UDT trong types.hal thuộc tính được chỉ định đã được nhập.

Thực thể nhập sẽ có quyền truy cập vào tổ hợp:

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

Câu lệnh nhập sử dụng cú pháp đủ điều kiện-type-name để cung cấp giá trị 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

Tính kế thừa giao diện

Giao diện có thể là phần mở rộng của một giao diện đã được xác định trước đó. Phần 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 giao diện đó không thay đổi.
  • Gói có thể thêm chức năng vào một gói khác, kết hợp API của gói đó 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 tính kế thừa). Mỗi giao diện trong gói có số phiên bản nhỏ khác 0 phải mở rộng trong phiên bản trước của gói. Ví dụ: nếu một giao diện IBar trong phiên bản 4.0 của gói derivative được 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 là đã tạo, IBar phiên bản 4.1 không thể mở rộng phiên bản 1.3 của IFoo. Thay vào đó, IBar phiên bản 4.1 phải mở rộng IBar phiên bản 4.0, gắn liền với IFoo phiên bản 1.2. IBar phiên bản 5.0 có thể mở rộng IFoo phiên bản 1.3, nếu mong muốn.

Tiện ích giao diện không ngụ ý sự phụ thuộc vào thư viện hoặc bao gồm nhiều lớp HAL trong mã được tạo — chúng chỉ cần nhập cấu trúc và phương thức dữ liệu ở cấp độ HIDL. Mọi phương thức trong HAL đều phải được triển khai theo cách đó Lớp trừu tượng phần cứng (HAL).

Tiện ích của nhà cung cấp

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

Lập phiên bản

Các gói được tạo phiên bản và giao diện có phiên bản của gói tương ứng. Các phiên bản được biểu thị dưới dạng 2 số nguyên, chính.nhỏ.

  • Các phiên bản chính không có khả năng tương thích ngược. Tăng dần số phiên bản lớn 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. Tăng số lượng số nhỏ 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 đó. Bạn có thể thêm cấu trúc và phương thức dữ liệu mới, nhưng chưa có cấu trúc dữ liệu hoặc chữ ký phương thức có thể bị thay đổi.

Một thiết bị có thể có nhiều phiên bản lớn hoặc nhỏ của HAL đồng thời. Tuy nhiên, phiên bản nhỏ nên được ưu tiên hơn phiên bản chính phiên bản vì mã ứng dụng khách hoạt động với giao diện phiên bản nhỏ trước đó cũng hoạt động với các phiên bản nhỏ sau này của cùng giao diện đó. Để biết thêm chi tiết về tạo phiên bản và tiện ích của nhà cung cấp, xem Tạo 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à tổng hợp thông tin đã trình bày trong phần HIDL. Trước khi đọc, hãy đảm bảo bạn hiểu rõ Tạo phiên bản HiDL, băm bằng các khái niệm về hidl-gen, thông tin chi tiết về cách làm việc với HIDL nói chung và các định nghĩa sau đây:

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

Để biết các định nghĩa khác, hãy xem HIDL Thuật ngữ.

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

Gốc của 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 vào -r vendor.awesome:some/device/independent/path/interfaces, thì tệp giao diện sẽ được đặt trong $ANDROID_BUILD_TOP/some/device/independent/path/interfaces/foo/1.0/IFoo.hal.

Trong thực tế, bạn nên sử dụng thuộc tính này cho một nhà cung cấp hoặc nhà sản xuất thiết bị gốc có tên là awesome để đưa giao diện tiêu chuẩn của họ vào vendor.awesome. Sau khi gói hàng đường dẫn đã được chọn, bạn không được thay đổi đường dẫn này 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 thư mục giao diện nhất quán (điều này cũng giúp giao diện tạo phiên bản dễ dàng hơn).

Thư mục gốc của gói phải có một tệp tạo phiên bản

Nếu bạn tạo một đường dẫn gói 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, phải chứa hàm băm của các giao diện được tạo bằng tuỳ chọn -Lhash trong hidl-gen (nội dung này được thảo luận rộng rãi trong Hàm băm bằng hidl-gen).

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

Trên thực tế, bạn nên chia sẻ giao diện giữa các nhánh. Chiến dịch này cho phép sử dụng lại mã tối đa và kiểm thử tối đa mã trên các thiết bị và trường hợp sử dụng.