Bạn phải sử dụng HIDL để mô tả tất cả cờ bản dựng dùng để biên dịch khung theo điều kiện. Các cờ bản dựng có liên quan phải được nhóm lại và đưa vào một tệp .hal
duy nhất. Việc sử dụng HIDL để chỉ định các mục cấu hình có các lợi ích sau:
- Có 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 rõ ràng HAL)
- Được ghi chép cẩn thận
- Kiểm soát quyền 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 Bộ kiểm thử dành cho nhà cung cấp (kiểm tra phạm vi, kiểm tra sự phụ thuộc 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ác cấu hình bản dựng dùng để biên dịch khung theo điều kiện, sau đó loại 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
Bạn có thể truy cập vào cấu hình bản dựng cho một hệ thống con 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 trong gói HAL android.hardware.configstore
(hiện tại ở 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 tệp .hal
mới vào tệp Android.bp
và Android.mk
.
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:
- Đặt tên ngắn gọn. Tránh chuyển đổi tên biến makefile thành tên hàm và lưu ý rằng các tiền tố
TARGET_
và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, các giá trị hợp lệ và thông tin liên quan khác.
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
trong cùng một thư mục và gói các giá trị gốc bằng một trường cho biết liệu giá trị có được HAL chỉ định hay không; nếu không, giá trị mặc định sẽ được sử dụng.
struct OptionalString { bool specified; string value; };
Khi thích hợp, hãy xác định enum thể hiện rõ nhất loại 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 xác định để giới hạn số lượng giá trị hợp lệ. Khi xác định các loại dữ liệu tuỳ chỉnh như vậy, hãy thêm một trường hoặc một giá trị enum (ví dụ: USE_DEFAULT
) để biểu thị liệu giá trị đó có được HAL chỉ định hay không.
Không bắt buộc một cờ bản dựng phải trở thành một hàm duy nhất trong HIDL. 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 đó (việc này có thể làm giảm số lượng 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 trong 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 };
Các phương án thay thế cho một hàm HAL
Thay vì sử dụng một hàm HAL duy nhất cho tất cả cờ bản dựng, giao diện HAL cũng cung cấp các hàm đơn giản như getBoolean(string
key)
và getInteger(string key)
. Các cặp key=value
thực tế đượ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ù dễ xác định, nhưng phương pháp này không bao gồm các lợi ích do HIDL mang lại (tạo phiên bản thực thi, dễ lập tài liệu, kiểm soát quyền truy cập) nên không được đề xuất.
Một và nhiều giao diện
Thiết kế giao diện HAL cho các mục cấu hình đưa ra 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 nhóm các mục cấu hình liên quan
Một giao diện thì sẽ dễ dàng hơn nhưng có thể trở nên không duy trì được khi có thêm nhiều mục cấu hình được thêm vào một tệp. Ngoài ra, tính năng kiểm soát quyền truy cập không chi tiết, vì vậy, một 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 (không thể cấp quyền truy cập vào một số mục cấu hình). Ngoài ra, nếu không được cấp quyền truy cập, bạn sẽ không thể đọc các mục cấu hình.
Do những vấn đề này, Android sử dụng nhiều giao diện với một giao diện 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 các mục cấu hình liên quan đến surfaceflinger
và IBluetoothConfigs
cho các mục cấu hình liên quan đến Bluetooth.