Bạn phải sử dụng HIDL để mô tả tất cả cờ bản dựng được dùng cho theo điều kiện
biên dịch khung. Cờ bản dựng liên quan phải được nhóm lại và đưa vào một
tệp .hal
. Sử dụng HIDL để chỉ định các mục cấu hình
bao gồm các lợi ích sau:
- Đã lập phiên bản (để thêm các mục cấu hình mới, nhà cung cấp/OEM phải mở rộng HAL)
- Có đầy đủ tài liệu chứng minh
- Kiểm soát truy cập bằng SELinux
- Kiểm tra tính hợp lý cho các mục cấu hình thông qua Kiểm thử nhà cung cấp Suite (kiểm tra phạm vi, kiểm tra sự phụ thuộc lẫn nhau giữa các mục, v.v.)
- API được tạo tự động trong cả C++ và Java
Xác định cờ bản dựng mà khung sử dụng
Bắt đầu bằng cách xác định cấu hình bản dựng dùng để biên dịch có điều kiện
khung, sau đó từ bỏ các cấu hình lỗi thời để làm cho tập hợp nhỏ hơn. Ví dụ:
bộ cờ bản dựng sau đây được xác định cho surfaceflinger
:
TARGET_USES_HWC2
TARGET_BOARD_PLATFORM
TARGET_DISABLE_TRIPLE_BUFFERING
TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
NUM_FRAMEBUFFER_SURFACE_BUFFERS
TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK
VSYNC_EVENT_PHASE_OFFSET_NS
SF_VSYNC_EVENT_PHASE_OFFSET_NS
PRESENT_TIME_OFFSET_FROM_VSYNC_NS
MAX_VIRTUAL_DISPLAY_DIMENSION
Tạo giao diện HAL
Cấu hình bản dựng cho hệ thống phụ được truy cập thông qua giao diện HAL, trong khi
các giao diện để cung cấp giá trị cấu hình được nhóm lại trong gói HAL
android.hardware.configstore
(hiện có ở phiên bản 1.0).
Ví dụ: để tạo tệp giao diện HAL cho surfaceflinger
, trong
hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
:
package android.hardware.configstore@1.0; interface ISurfaceFlingerConfigs { // TO-BE-FILLED-BELOW };
Sau khi tạo tệp .hal
, hãy chạy
hardware/interfaces/update-makefiles.sh
để thêm mới
.hal
vào Android.bp
và
Android.mk
tệp.
Thêm hàm cho cờ bản dựng
Đối với mỗi cờ bản dựng, hãy thêm một hàm mới vào giao diện. Ví dụ: trong
hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
:
interface ISurfaceFlingerConfigs { disableTripleBuffering() generates(OptionalBool ret); forceHwcForVirtualDisplays() generates(OptionalBool ret); enum NumBuffers: uint8_t { USE_DEFAULT = 0, TWO = 2, THREE = 3, }; numFramebufferSurfaceBuffers() generates(NumBuffers ret); runWithoutSyncFramework() generates(OptionalBool ret); vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret); presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret); maxVirtualDisplayDimension() generates(OptionalInt32 ret); };
Khi thêm hàm:
- Sử dụng tên ngắn gọn. Tránh chuyển đổi biến makefile
tên vào tên hàm và lưu ý rằng
TARGET_
và Tiền tốBOARD_
không còn cần thiết nữa. - Thêm nhận xét. Giúp nhà phát triển hiểu được mục đích của mục cấu hình, cách mục này thay đổi hành vi của khung, giá trị hợp lệ và các thông tin liên quan khác của bạn.
Kiểu dữ liệu trả về của hàm có thể là
Optional[Bool|String|Int32|UInt32|Int64|UInt64]
. Các loại được xác định
trong types.hal
ở cùng thư mục và gói giá trị gốc bằng một
trường cho biết giá trị có được HAL chỉ định hay không; nếu không, giá trị mặc định
giá trị được sử dụng.
struct OptionalString { bool specified; string value; };
Khi thích hợp, hãy xác định enum thể hiện tốt nhất loại của
mục cấu hình và sử dụng enum đó làm loại dữ liệu trả về. Trong ví dụ trên,
enum NumBuffers
được định nghĩa để giới hạn số lượng giá trị hợp lệ
giá trị. Khi xác định các loại dữ liệu tuỳ chỉnh đó, hãy thêm một trường hoặc một giá trị enum (cho
ví dụ: USE_DEFAULT
) để cho biết liệu giá trị có được chỉ định hay không
bởi HAL.
Một cờ bản dựng không bắt buộc phải trở thành một hàm duy nhất trong Phóng điện cường độ cao. Ngoài ra, chủ sở hữu mô-đun có thể tổng hợp các cờ bản dựng có liên quan chặt chẽ vào một cấu trúc và có một hàm trả về cấu trúc đó (làm như vậy có thể giảm số lệnh gọi hàm).
Ví dụ: tuỳ chọn tổng hợp hai cờ bản dựng thành một cấu trúc duy nhất
tại hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
là:
interface ISurfaceFlingerConfigs { // other functions here struct SyncConfigs { OptionalInt64 vsyncEventPhaseoffsetNs; OptionalInt64 presentTimeoffsetFromSyncNs; }; getSyncConfigs() generates (SyncConfigs ret); // other functions here };
Giải pháp thay thế cho một chức năng HAL
Thay vì sử dụng một hàm HAL duy nhất cho tất cả cờ bản dựng, HAL
cũng cung cấp các hàm đơn giản như getBoolean(string
key)
và getInteger(string key)
. Dữ liệu thực tế
Các cặp key=value
được lưu trữ trong các tệp riêng biệt và dịch vụ HAL
cung cấp các giá trị bằng cách đọc/phân tích cú pháp các tệp đó.
Mặc dù phương pháp này dễ xác định nhưng không bao gồm các lợi ích do HIDL cung cấp (tạo phiên bản thực thi, dễ sử dụng tài liệu, kiểm soát quyền truy cập) nên không nên dùng.
Một và nhiều giao diện
Thiết kế giao diện HAL cho các mục cấu hình thể hiện hai lựa chọn:
- Một giao diện duy nhất bao gồm tất cả các mục cấu hình
- Nhiều giao diện, mỗi giao diện bao gồm một tập hợp cấu hình liên quan mục
Một giao diện sẽ dễ dàng hơn nhưng có thể trở nên không thể duy trì khi các mục cấu hình sẽ được thêm vào tệp duy nhất. Ngoài ra, tính năng kiểm soát quyền truy cập không chi tiết, do đó quy trình được cấp quyền truy cập vào giao diện có thể đọc tất cả các mục cấu hình (bạn không thể truy cập vào một phần các mục cấu hình đã cấp). Ngoài ra, nếu không được cấp quyền truy cập, bạn không thể truy cập vào các mục cấu hình đã đọc.
Do những vấn đề này, Android sử dụng nhiều giao diện với một lớp trừu tượng phần cứng (HAL) duy nhất
cho một nhóm các mục cấu hình có liên quan. Ví dụ:
ISurfaceflingerConfigs
cho surfaceflinger
liên quan
các mục cấu hình và IBluetoothConfigs
cho mục liên quan đến Bluetooth
các mục cấu hình.