Sensors Multi-HAL là một khung cho phép các HAL cảm biến chạy cùng với các HAL cảm biến khác. Sensors Multi-HAL tải động các Sensors sub-HAL được lưu trữ dưới dạng thư viện động trên phân vùng của nhà cung cấp và cung cấp cho chúng một đối tượng gọi lại có thể xử lý việc đăng các sự kiện cũng như thu thập và giải phóng khoá đánh thức. HAL phụ của cảm biến là HAL cảm biến được tích hợp vào một đối tượng dùng chung trên phân vùng nhà cung cấp và được khung đa HAL sử dụng. Các HAL phụ này không phụ thuộc vào nhau hoặc vào mã multi-HAL chứa hàm chính cho quy trình.
Sensors Multi-HAL 2.1 (có trên các thiết bị chạy Android 11 trở lên) là một phiên bản của Sensors Multi-HAL 2.0, hỗ trợ tải các HAL phụ có thể hiển thị loại cảm biến góc bản lề. Để hỗ trợ loại cảm biến này, các HAL phụ phải sử dụng các API HAL phụ được xác định trong tiêu đề SubHal 2.1.
Đối với các thiết bị chạy Android 13 trở lên sử dụng Sensors AIDL HAL, bạn có thể sử dụng lớp shim nhiều HAL để cho phép khả năng nhiều HAL. Để biết thông tin chi tiết về cách triển khai, hãy xem phần Sử dụng Sensors Multi-HAL với Sensors AIDL HAL.
Sự khác biệt giữa Sensors Multi-HAL 2 và Sensors HAL 2
Sensors Multi-HAL 2 (có trên các thiết bị chạy Android 10 trở lên) giới thiệu một số lớp trừu tượng trên Sensors HAL 2 để giúp bạn dễ dàng tương tác với các API HAL. Sensors Multi-HAL 2 giới thiệu lớp HalProxy để xử lý việc triển khai giao diện Sensors HAL 2 và giao diện V2_1/SubHal
(hoặc V2_0/SubHal
) để cho phép HalProxy
tương tác với các HAL phụ.
Giao diện ISensorsSubHal
khác với giao diện 2.1/ISensors.hal
(hoặc 2.0/ISensors.hal
) ở những điểm sau:
- Phương thức khởi chạy sẽ truyền một lớp
IHalProxyCallback
thay vì hai FMQ vàISensorsCallback
. - Các HAL phụ phải triển khai một hàm gỡ lỗi để cung cấp thông tin gỡ lỗi trong báo cáo lỗi.
- Các HAL phụ phải triển khai một hàm tên để có thể phân biệt HAL phụ đã tải với các HAL phụ khác.
Điểm khác biệt chính giữa Sensors Multi-HAL 2 và Sensors HAL 2 nằm ở các hàm khởi tạo. Thay vì cung cấp FMQ, giao diện IHalProxyCallback
cung cấp 2 phương thức, một phương thức để đăng các sự kiện cảm biến vào khung cảm biến và một phương thức để tạo khoá đánh thức. Về cơ bản, Sensors Multi-HAL quản lý mọi hoạt động tương tác với FMQ để đảm bảo việc phân phối kịp thời các sự kiện cảm biến cho tất cả các HAL phụ. Các HAL phụ nên sử dụng phương thức createScopedWakelock
để uỷ quyền gánh nặng hết thời gian chờ khoá đánh thức cho Sensors Multi-HAL và tập trung việc sử dụng khoá đánh thức vào một khoá đánh thức chung cho toàn bộ Sensors Multi-HAL. Nhờ đó, bạn có thể giảm thiểu các lệnh gọi khoá và mở khoá.
Sensors Multi-HAL 2 cũng có một số tính năng an toàn tích hợp sẵn. Thư viện này xử lý các trường hợp FMQ cảm biến đầy hoặc khi khung cảm biến Android khởi động lại và trạng thái cảm biến cần được đặt lại. Ngoài ra, khi các sự kiện được đăng lên lớp HalProxy
nhưng khung cảm biến không thể chấp nhận các sự kiện ngay lập tức, Sensors Multi-HAL có thể di chuyển các sự kiện sang một luồng nền để cho phép công việc tiếp tục trên tất cả các HAL phụ trong khi chờ các sự kiện được đăng.
Mã nguồn và cách triển khai tham chiếu
Tất cả mã Multi-HAL của Cảm biến đều có trong hardware/interfaces/sensors/common/default/2.X/multihal/
.
Sau đây là thông tin về một số tài nguyên.
HalProxy.h
: Đối tượngHalProxy
được Sensors multi-HAL khởi tạo và xử lý việc truyền dữ liệu từ các HAL phụ đến khung cảm biến.HalProxy.cpp
: Việc triển khaiHalProxy
chứa tất cả logic cần thiết để ghép kênh giao tiếp giữa các HAL phụ và khung cảm biến.SubHal.h
: Giao diệnISensorsSubHal
xác định giao diện mà các HAL phụ phải tuân theo để tương thích vớiHalProxy
. HAL phụ triển khai phương thức khởi tạo để có thể dùng đối tượngHalProxyCallback
chopostEvents
vàcreateScopedWakelock
.Đối với các chế độ triển khai Multi-HAL 2.0, hãy sử dụng phiên bản 2.0 của
SubHal.h
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: Các kiểm thử đơn vị này xác minh việc triển khaiHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: Ví dụ về việc triển khai HAL phụ này sử dụng các cảm biến giả để tạo dữ liệu giả. Hữu ích cho việc kiểm thử cách nhiều HAL phụ tương tác trên một thiết bị.
Triển khai
Phần này mô tả cách triển khai Sensors Multi-HAL trong các trường hợp sau:
- Sử dụng Sensors Multi-HAL với Sensors AIDL HAL
- Triển khai Sensors Multi-HAL 2.1
- Chuyển từ Sensors Multi-HAL 2.0 sang Multi-HAL 2.1
- Chuyển từ Sensors HAL 2.0
- Chuyển từ Sensors HAL 1.0
- Chuyển từ Sensors Multi-HAL 1.0
Sử dụng Sensors Multi-HAL với Sensors AIDL HAL
Để cho phép khả năng đa HAL với Sensors AIDL HAL, hãy nhập mô-đun lớp shim AIDL Multi-HAL có trong hardware/interfaces/sensors/aidl/default/multihal/. Mô-đun này xử lý việc chuyển đổi giữa các loại định nghĩa HAL cảm biến AIDL và HIDL, đồng thời xác định một trình bao bọc xung quanh giao diện nhiều HAL được mô tả trong phần Triển khai nhiều HAL cảm biến 2.1. Lớp shim AIDL multi-HAL tương thích với những thiết bị triển khai Sensors Multi-HAL 2.1.
Lớp shim đa HAL của AIDL cho phép bạn hiển thị bộ theo dõi đầu và các loại cảm biến IMU có trục hạn chế trong Sensors AIDL HAL. Để sử dụng các loại cảm biến này do giao diện AIDL HAL xác định, hãy đặt trường type
trong cấu trúc SensorInfo
trong quá trình triển khai getSensorsList_2_1()
. Điều này là an toàn vì các trường loại cảm biến dựa trên số nguyên của AIDL và HIDL sensors HAL không trùng lặp.
Triển khai Sensors Multi-HAL 2.1
Để triển khai Sensors Multi-HAL 2.1 trên một thiết bị mới, hãy làm theo các bước sau:
- Triển khai giao diện
ISensorsSubHal
như mô tả trongSubHal.h
. - Triển khai phương thức
sensorsHalGetSubHal_2_1
trongSubHal.h
. Thêm mục tiêu
cc_library_shared
để tạo HAL phụ mới được triển khai. Khi thêm mục tiêu:- Đảm bảo đích đến được chuyển đến một vị trí nào đó trên phân vùng nhà cung cấp của thiết bị.
- Trong tệp cấu hình nằm ở
/vendor/etc/sensors/hals.conf
, hãy thêm đường dẫn đến thư viện trên một dòng mới. Nếu cần, hãy tạo tệphals.conf
.
Để biết ví dụ về mục
Android.bp
để tạo thư viện HAL phụ, hãy xemhardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Xoá tất cả các mục
android.hardware.sensors
khỏi tệpmanifest.xml
. Tệp này chứa danh sách các HAL được hỗ trợ trên thiết bị.Xoá tất cả các tệp dịch vụ
android.hardware.sensors
vàservice.rc
khỏi tệpdevice.mk
rồi thêmandroid.hardware.sensors@2.1-service.multihal
vàandroid.hardware.sensors@2.1-service.multihal.rc
vàoPRODUCT_PACKAGES
.
Khi khởi động, HalProxy
sẽ bắt đầu, tìm kiếm HAL phụ mới triển khai và khởi tạo HAL phụ đó bằng cách gọi sensorsHalGetSubHal_2_1
.
Chuyển từ Sensors Multi-HAL 2.0 sang Multi-HAL 2.1
Để chuyển từ Multi-HAL 2.0 sang Multi-HAL 2.1, hãy triển khai giao diện SubHal
và biên dịch lại HAL phụ.
Sau đây là sự khác biệt giữa giao diện SubHal
2.0 và 2.1:
IHalProxyCallback
sử dụng các loại được tạo trong phiên bản 2.1 của quy cáchISensors.hal
.- Hàm
initialize()
truyền mộtIHalProxyCallback
mới thay vì mộtSubHal
từ giao diện 2.0 - Các HAL phụ phải triển khai
getSensorsList_2_1
vàinjectSensorData_2_1
thay vìgetSensorsList
vàinjectSensorData
vì các phương thức này sử dụng các loại mới được thêm vào phiên bản 2.1 của quy cáchISensors.hal
. - Các HAL phụ phải hiển thị
sensorsHalGetSubHal_2_1
thay vìsensorsHalGetSubHal
để Multi-HAL coi chúng là HAL phụ phiên bản 2.1.
Cổng từ Sensors HAL 2.0
Khi nâng cấp lên Sensors Multi-HAL 2.0 từ Sensors HAL 2.0, hãy đảm bảo rằng việc triển khai HAL đáp ứng các yêu cầu sau.
Khởi chạy HAL
HAL 2.0 của cảm biến có một hàm khởi chạy cho phép dịch vụ cảm biến truyền FMQ và một lệnh gọi lại cảm biến động. Trong Sensors Multi-HAL 2.0, hàm initialize()
sẽ truyền một lệnh gọi lại duy nhất mà bạn phải dùng để đăng các sự kiện cảm biến, lấy khoá đánh thức và thông báo về việc kết nối và ngắt kết nối cảm biến động.
Đăng các sự kiện cảm biến vào quá trình triển khai Multi-HAL
Thay vì đăng các sự kiện cảm biến thông qua FMQ, HAL phụ phải ghi các sự kiện cảm biến vào IHalProxyCallback
khi có các sự kiện cảm biến.
Sự kiện WAKE_UP
Trong Sensors HAL 2.0, HAL có thể quản lý khoá đánh thức cho quá trình triển khai của mình. Trong Sensors Multi-HAL 2.0, các HAL phụ cho phép việc triển khai Multi-HAL quản lý khoá đánh thức và có thể yêu cầu lấy khoá đánh thức bằng cách gọi createScopedWakelock
.
Bạn phải lấy và truyền một khoá đánh thức có phạm vi bị khoá đến postEvents
khi đăng các sự kiện đánh thức vào quá trình triển khai Multi-HAL.
Cảm biến động
Sensors Multi-HAL 2.0 yêu cầu onDynamicSensorsConnected
và onDynamicSensorsDisconnected
trong IHalProxyCallback
được gọi bất cứ khi nào các kết nối cảm biến động thay đổi. Các lệnh gọi lại này có sẵn trong con trỏ IHalProxyCallback
được cung cấp thông qua hàm initialize()
.
Cổng từ Sensors HAL 1.0
Khi nâng cấp lên Sensors Multi-HAL 2.0 từ Sensors HAL 1.0, hãy đảm bảo việc triển khai HAL đáp ứng các yêu cầu sau.
Khởi chạy HAL
Bạn phải hỗ trợ hàm initialize()
để thiết lập lệnh gọi lại giữa HAL phụ và việc triển khai Multi-HAL.
Hiển thị các cảm biến hiện có
Trong Sensors Multi-HAL 2.0, hàm getSensorsList()
phải trả về cùng một giá trị trong một lần khởi động thiết bị, ngay cả khi HAL cảm biến khởi động lại. Điều này cho phép khung cố gắng thiết lập lại các kết nối cảm biến nếu máy chủ hệ thống khởi động lại. Giá trị do getSensorsList()
trả về có thể thay đổi sau khi thiết bị khởi động lại.
Đăng các sự kiện cảm biến vào quá trình triển khai Multi-HAL
Trong Sensors HAL 2.0, thay vì chờ poll()
được gọi, HAL phụ phải chủ động ghi các sự kiện cảm biến vào IHalProxyCallback
bất cứ khi nào có sự kiện cảm biến.
Sự kiện WAKE_UP
Trong Sensors HAL 1.0, HAL có thể quản lý khoá đánh thức cho quá trình triển khai của mình. Trong Sensors Multi-HAL 2.0, các HAL phụ cho phép việc triển khai Multi-HAL quản lý các khoá đánh thức và có thể yêu cầu lấy khoá đánh thức bằng cách gọi createScopedWakelock
.
Bạn phải lấy và truyền một khoá đánh thức có phạm vi bị khoá đến postEvents
khi đăng các sự kiện đánh thức vào quá trình triển khai Multi-HAL.
Cảm biến động
Trong Sensors HAL 1.0, các cảm biến động được trả về thông qua hàm poll()
.
Sensors Multi-HAL 2.0 yêu cầu onDynamicSensorsConnected
và onDynamicSensorsDisconnected
trong IHalProxyCallback
được gọi bất cứ khi nào các kết nối cảm biến động thay đổi. Các lệnh gọi lại này có sẵn trong con trỏ IHalProxyCallback
được cung cấp thông qua hàm initialize()
.
Cổng từ Sensors Multi-HAL 1.0
Để chuyển một quy trình triển khai hiện có từ Sensors Multi-HAL 1.0, hãy làm theo các bước sau.
- Đảm bảo rằng cấu hình HAL cảm biến nằm tại
/vendor/etc/sensors/hals.conf
. Việc này có thể liên quan đến việc di chuyển tệp nằm tại/system/etc/sensors/hals.conf
. - Xoá mọi thông tin tham chiếu đến
hardware/hardware.h
vàhardware/sensors.h
vì các thông tin tham chiếu này không được hỗ trợ cho HAL 2.0. - Chuyển các HAL phụ như mô tả trong phần Chuyển từ Sensors Hal 1.0.
- Đặt Sensors Multi-HAL 2.0 làm HAL được chỉ định bằng cách làm theo các bước 3 và 4 trong phần Triển khai Sensors Multi-HAL 2.0.
Xác nhận kết quả
Chạy VTS
Khi bạn đã tích hợp một hoặc nhiều HAL phụ với Sensors Multi-Hal 2.1, hãy sử dụng Vendor Test Suite (VTS) để đảm bảo các triển khai HAL phụ của bạn đáp ứng tất cả các yêu cầu do giao diện Sensors HAL đặt ra.
Để chỉ chạy các kiểm thử VTS về cảm biến khi VTS được thiết lập trên một máy chủ lưu trữ, hãy thực thi các lệnh sau:
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_0Target && \
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_1Target
Nếu bạn đang chạy lớp shim Multi-HAL AIDL, hãy chạy VtsAidlHalSensorsTargetTest
.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Chạy kiểm thử đơn vị
Các kiểm thử đơn vị trong HalProxy_test.cpp
kiểm thử HalProxy
bằng cách sử dụng các HAL phụ giả được khởi tạo trong kiểm thử đơn vị và không được tải động. Khi tạo một HAL phụ mới, các kiểm thử này sẽ đóng vai trò là hướng dẫn về cách thêm các kiểm thử đơn vị để xác minh rằng HAL phụ mới được triển khai đúng cách.
Để chạy các kiểm thử, hãy thực thi các lệnh sau:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Thử nghiệm bằng các HAL phụ giả
Các HAL phụ giả là các phương thức triển khai giả của giao diện ISensorsSubHal
.
Các HAL phụ sẽ hiển thị nhiều danh sách cảm biến. Khi được kích hoạt, các cảm biến sẽ định kỳ đăng các sự kiện cảm biến được tạo tự động vào HalProxy
dựa trên khoảng thời gian được chỉ định trong một yêu cầu cảm biến nhất định.
Bạn có thể dùng các HAL phụ giả để kiểm thử cách hoạt động của mã Multi-HAL đầy đủ với các HAL phụ khác được tải vào hệ thống và để kiểm tra nhiều khía cạnh của mã Sensors Multi-HAL.
Có 2 HAL phụ giả tại hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
.
Để tạo và đẩy các HAL phụ giả vào một thiết bị, hãy thực hiện các bước sau:
Chạy các lệnh sau để tạo và đẩy 3 HAL phụ giả khác nhau vào thiết bị:
$ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
mma
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
Cập nhật cấu hình HAL cảm biến tại
/vendor/etc/sensors/hals.conf
bằng các đường dẫn cho các HAL phụ giả./vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
Khởi động lại
HalProxy
và tải các HAL phụ mới có trong cấu hình.adb shell stop
adb shell start
Gỡ lỗi
Nhà phát triển có thể gỡ lỗi khung bằng lệnh lshal
. Để yêu cầu đầu ra gỡ lỗi của Sensors HAL, hãy chạy lệnh sau:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Sau đó, thông tin về trạng thái hiện tại của HalProxy
và các HAL phụ của nó sẽ được xuất ra thiết bị đầu cuối. Dưới đây là ví dụ về kết quả của lệnh đối với đối tượng HalProxy
và các HAL phụ giả.
Internal values:
Threads are running: true
Wakelock timeout start time: 200 ms ago
Wakelock timeout reset time: 73208 ms ago
Wakelock ref count: 0
# of events on pending write queue: 0
# of non-dynamic sensors across all subhals: 8
# of dynamic sensors across all subhals: 0
SubHals (2):
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Nếu số được chỉ định cho # of events on pending write queue
là một số lớn (1000 trở lên), điều này cho biết có nhiều sự kiện đang chờ được ghi vào khung cảm biến. Điều này cho biết dịch vụ cảm biến bị bế tắc hoặc gặp sự cố và không xử lý các sự kiện cảm biến, hoặc một loạt lớn các sự kiện cảm biến gần đây đã được đăng từ một HAL phụ.
Nếu số lượt tham chiếu khoá chế độ thức lớn hơn 0
, tức là HalProxy
đã nhận được một khoá chế độ thức. Giá trị này chỉ được lớn hơn 0
nếu ScopedWakelock
đang được giữ có chủ ý hoặc nếu các sự kiện đánh thức được gửi đến HalProxy
và chưa được khung cảm biến xử lý.
Chỉ số mô tả tệp được truyền đến phương thức gỡ lỗi của HalProxy
sẽ được truyền đến từng HAL phụ, vì vậy, nhà phát triển phải triển khai phương thức gỡ lỗi trong giao diện ISensorsSubHal
.