Cảm biến Multi-HAL

Cảm biến Multi-HAL là một khung cho phép các cảm biến HAL chạy cùng với các HAL cảm biến khác. Cảm biến Multi-HAL tải động các HAL phụ của cảm biến đượ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 đối tượng gọi lại có thể xử lý việc đăng sự kiện cũng như thu thập và giải phóng khóa đá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 của 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ã đa HAL chứa chức năng chính của quy trình.

Cảm biến Multi-HAL 2.1, có sẵn trên các thiết bị chạy Android 11 trở lên, là phiên bản lặp lại của Cảm biến 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 đề 2.1 SubHal .

Đối với các thiết bị chạy Android 13 trở lên sử dụng Cảm biến AIDL HAL , bạn có thể sử dụng lớp chêm đa HAL để cho phép khả năng đa HAL. Để biết chi tiết triển khai, hãy xem Sử dụng Multi-HAL cảm biến với AIDL HAL cảm biến .

Sự khác biệt giữa Cảm biến Multi-HAL 2 và Cảm biến HAL 2

Cảm biến Multi-HAL 2, có sẵn trên các thiết bị chạy Android 10 trở lên, giới thiệu một số phần tóm tắt bên trên Cảm biến HAL 2 để giúp tương tác với API HAL dễ dàng hơn. 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 tạo chuyển một lớp IHalProxyCallback thay vì hai FMQ và ISensorsCallback .
  • Sub-HAL phải triển khai chức năng 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 chức năng tên để có thể phân biệt được HAL phụ được tải với các HAL phụ khác.

Sự khác biệt chính giữa Cảm biến Multi-HAL 2 và Cảm biến HAL 2 là ở chức năng khởi tạo. Thay vì cung cấp FMQ, giao diện IHalProxyCallback cung cấp hai phương thức, một phương thức để đăng các sự kiện cảm biến lên khung cảm biến và một phương thức để tạo khóa đánh thức. Dưới lớp vỏ bọc, Cảm biến Multi-HAL quản lý tất cả các tương tác với FMQ để đảm bảo cung cấp kịp thời các sự kiện cảm biến cho tất cả các HAL phụ. Chúng tôi đặc biệt khuyến nghị các HAL phụ sử dụng phương pháp createScopedWakelock để giao gánh nặng về thời gian chờ khóa chế độ thức cho Cảm biến Multi-HAL và tập trung việc sử dụng khóa chế độ thức thành một khóa chế độ thức chung cho toàn bộ Cảm biến Multi-HAL, giúp giảm thiểu việc khóa và mở khóa cuộc gọi.

Cảm biến Multi-HAL 2 cũng được tích hợp sẵn một số tính năng an toàn. Nó xử lý các tình huống trong đó 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, Multi-HAL cảm biến 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ờ đợi sự kiện được đăng.

Mã nguồn và triển khai tham chiếu

Tất cả mã Multi-HAL của Cảm biến đều có sẵn trong hardware/interfaces/sensors/common/default/2.X/multihal/ . Dưới đây là con trỏ đến một số tài nguyên.

  • HalProxy.h : Đối tượng HalProxy được khởi tạo bởi Sensors multi-HAL 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 khai HalProxy chứa tất cả logic cần thiết để ghép kênh liên lạc giữa các HAL phụ và khung cảm biến.
  • SubHal.h : Giao diện ISensorsSubHal xác định giao diện mà các HAL phụ phải tuân theo để tương thích với HalProxy . Sub-HAL triển khai phương thức khởi tạo để đối tượng HalProxyCallback có thể được sử dụng cho postEventscreateScopedWakelock .

    Để 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 thử nghiệm đơn vị này xác minh việc triển khai HalProxy .

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ : Ví dụ triển khai HAL phụ này sử dụng cảm biến giả để tạo dữ liệu giả. Hữu ích để kiểm tra xem nhiều HAL phụ tương tác như thế nào trên một thiết bị.

Thực hiện

Phần này mô tả cách triển khai Cảm biến Multi-HAL trong các tình huống sau:

Sử dụng Cảm biến Multi-HAL với Cảm biến AIDL HAL

Để cho phép khả năng đa HAL với Cảm biến AIDL HAL, hãy nhập mô-đun lớp miếng chêm AIDL Multi-HAL, được tìm thấy trong phần cứng/giao diện/cảm biến/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ủa cảm biến AIDL và HIDL và xác định một trình bao bọc xung quanh giao diện multi-HAL được mô tả trong Triển khai Cảm biến Multi-HAL 2.1 . Lớp miếng đệm AIDL multi-HAL tương thích với các thiết bị triển khai Cảm biến Multi-HAL 2.1.

Lớp miếng chêm đa HAL AIDL cho phép bạn hiển thị bộ theo dõi đầu và các loại cảm biến IMU trục giới hạn trong Cảm biến AIDL HAL. Để sử dụng các loại cảm biến này được xác định bởi giao diện AIDL HAL, 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 an toàn vì các trường loại cảm biến được hỗ trợ số nguyên của cảm biến AIDL và HIDL HAL không trùng nhau.

Triển khai cảm biến Multi-HAL 2.1

Để triển khai Cảm biến Multi-HAL 2.1 trên thiết bị mới, hãy làm theo các bước sau:

  1. Triển khai giao diện ISensorsSubHal như được mô tả trong SubHal.h .
  2. Triển khai phương thức sensorsHalGetSubHal_2_1 trong SubHal.h .
  3. Thêm mục tiêu cc_library_shared để xây dựng HAL con mới được triển khai. Khi thêm mục tiêu:

    1. Đảm bảo mục tiêu được đẩy đến một nơi nào đó trên phân vùng nhà cung cấp của thiết bị.
    2. Trong tệp cấu hình có tại /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ệp hals.conf .

    Để biết ví dụ về mục nhập Android.bp để xây dựng thư viện HAL phụ, hãy xem hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp .

  4. Xóa tất cả các mục nhập android.hardware.sensors khỏi tệp kê manifest.xml chứa danh sách HAL được hỗ trợ trên thiết bị.

  5. Xóa tất cả các tệp dịch vụ android.hardware.sensorsservice.rc khỏi tệp device.mk và thêm android.hardware.sensors@2.1-service.multihalandroid.hardware.sensors@2.1-service.multihal.rc vào PRODUCT_PACKAGES .

Khi khởi động, HalProxy khởi động, tìm kiếm HAL phụ mới được triển khai và khởi tạo nó bằng cách gọi sensorsHalGetSubHal_2_1 .

Chuyển từ Cảm biến 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 sub-HAL của bạn.

Đây là những 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 đặc tả ISensors.hal .
  • Hàm initialize() chuyển IHalProxyCallback mới thay vì hàm từ giao diện SubHal 2.0
  • Các HAL phụ phải triển khai getSensorsList_2_1injectSensorData_2_1 thay vì getSensorsListinjectSensorData vì các phương thức này sử dụng các loại mới được thêm vào trong phiên bản 2.1 của đặc tả ISensors.hal .
  • Các HAL phụ phải hiển thị sensorsHalGetSubHal_2_1 thay vì sensorsHalGetSubHal cho Multi-HAL để coi chúng là các HAL phụ phiên bản 2.1.

Cổng từ Cảm biến HAL 2.0

Khi nâng cấp lên Cảm biến Multi-HAL 2.0 từ Cảm biến HAL 2.0 , hãy đảm bảo việc triển khai HAL đáp ứng các yêu cầu sau.

Khởi tạo HAL

Cảm biến HAL 2.0 có chức năng khởi tạo cho phép dịch vụ cảm biến vượt qua FMQ và gọi lại cảm biến động. Trong Sensors Multi-HAL 2.0, hàm initialize() chuyển một lệnh gọi lại duy nhất phải được sử dụng để đăng các sự kiện cảm biến, lấy khóa chế độ thức và thông báo về 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ó sự kiện cảm biến.

sự kiện WAKE_UP

Trong Cảm biến HAL 2.0, HAL có thể quản lý khóa đánh thức để triển khai. Trong Sensors Multi-HAL 2.0, các HAL phụ cho phép triển khai Multi-HAL quản lý khóa chế độ thức và có thể yêu cầu lấy khóa chế độ thức bằng cách gọi createScopedWakelock . Khóa chế độ thức có phạm vi bị khóa phải được lấy và chuyển tới postEvents khi đăng sự kiện đánh thức lên quá trình triển khai Multi-HAL.

Cảm biến động

Cảm biến Multi-HAL 2.0 yêu cầu onDynamicSensorsConnectedonDynamicSensorsDisconnected trong IHalProxyCallback được gọi bất cứ khi nào kết nối cảm biến động thay đổi. Các lệnh gọi lại này có sẵn như một phần của con trỏ IHalProxyCallback được cung cấp thông qua hàm initialize() .

Cổng từ Cảm biến HAL 1.0

Khi nâng cấp lên Cảm biến Multi-HAL 2.0 từ Cảm biến 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 tạo HAL

Hàm initialize() phải được hỗ trợ để thiết lập lệnh gọi lại giữa triển khai HAL phụ và Multi-HAL.

Hiển thị các cảm biến có sẵn

Trong Cảm biến 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 khởi động lại HAL trên các cảm biến. Đ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ị được getSensorsList() trả về có thể thay đổi sau khi thiết bị thực hiện 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 Cảm biến HAL 2.0, thay vì đợi cuộc thăm 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 Cảm biến HAL 1.0, HAL có thể quản lý khóa đánh thức để triển khai. Trong Sensors Multi-HAL 2.0, các HAL phụ cho phép triển khai Multi-HAL quản lý khóa chế độ thức và có thể yêu cầu lấy khóa chế độ thức bằng cách gọi createScopedWakelock . Khóa chế độ thức có phạm vi bị khóa phải được lấy và chuyển tới postEvents khi đăng sự kiện đánh thức lên quá trình triển khai Multi-HAL.

Cảm biến động

Trong Cảm biến HAL 1.0, cảm biến động được trả về thông qua hàm poll() . Cảm biến Multi-HAL 2.0 yêu cầu onDynamicSensorsConnectedonDynamicSensorsDisconnected trong IHalProxyCallback được gọi bất cứ khi nào kết nối cảm biến động thay đổi. Các lệnh gọi lại này có sẵn như một phần của con trỏ IHalProxyCallback được cung cấp thông qua hàm initialize() .

Cổng từ Cảm biến Multi-HAL 1.0

Để chuyển một triển khai hiện có từ Sensors Multi-HAL 1.0 , hãy làm theo các bước sau.

  1. Đảm bảo rằng cấu hình HAL của cảm biến được đặt tại /vendor/etc/sensors/hals.conf. Điều này có thể liên quan đến việc di chuyển tệp nằm ở /system/etc/sensors/hals.conf .
  2. Xóa mọi tham chiếu đến hardware/hardware.hhardware/sensors.h vì những thứ này không được hỗ trợ cho HAL 2.0.
  3. Cổng HAL phụ như được mô tả trong Chuyển từ cảm biến Hal 1.0 .
  4. Đặt Cảm biến 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 Cảm biến Mutli-HAL 2.0 .

Thẩm định

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 Bộ kiểm tra nhà cung cấp (VTS) để đảm bảo việ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 HAL của cảm biến đặt ra.

Để chỉ chạy các kiểm tra VTS của cảm biến khi VTS được thiết lập trên máy chủ, hãy thực hiện 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 AIDL Multi-HAL, hãy chạy VtsAidlHalSensorsTargetTest .

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

Chạy thử nghiệm đơn vị

Các thử nghiệm đơn vị trong HalProxy_test.cpp thử nghiệm HalProxy bằng cách sử dụng các HAL phụ giả được khởi tạo trong thử nghiệm đơn vị và không được tải động. Khi tạo một HAL phụ mới, các thử nghiệm này sẽ đóng vai trò là hướng dẫn về cách thêm các thử nghiệm đơn vị nhằm xác minh rằng HAL phụ mới được triển khai đúng cách.

Để chạy thử nghiệm, hãy thực hiện các lệnh sau:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

Kiểm tra với các HAL phụ giả mạo

Các HAL phụ giả mạo là các triển khai giả của giao diện ISensorsSubHal . Các HAL phụ hiển thị các danh sách cảm biến khác nhau. Khi các cảm biến được kích hoạt, chúng định kỳ đăng các sự kiện cảm biến được tạo tự động lên HalProxy dựa trên các khoảng thời gian được chỉ định trong yêu cầu cảm biến nhất định.

Các HAL phụ giả mạo có thể được sử dụng để kiểm tra 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à để nhấn mạnh các khía cạnh khác nhau của mã Multi-HAL của Cảm biến.

Hai HAL phụ giả mạo có sẵn tại hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ .

Để xây dựng 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:

  1. Chạy các lệnh sau để xây dựng và đẩy ba 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
    
  2. Cập nhật cấu hình HAL của cảm biến tại /vendor/etc/sensors/hals.conf với các đường dẫn cho HAL phụ giả mạo.

    /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
    
  3. Khởi động lại HalProxy và tải các HAL phụ mới được liệt kê trong cấu hình.

    adb shell stop
    adb shell start
    

Gỡ lỗi

Các nhà phát triển có thể gỡ lỗi khung bằng cách sử dụng lệnh lshal . Để yêu cầu đầu ra gỡ lỗi của Cảm biến HAL, hãy chạy lệnh sau:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

Thông tin về trạng thái hiện tại của HalProxy và các HAL phụ của nó sau đó được xuất ra thiết bị đầu cuối. Dưới đây là ví dụ về đầu ra lệnh cho đối tượng HalProxy và các HAL phụ giả mạo.

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 rằng có nhiều sự kiện đang chờ ghi vào khung cảm biến. Điều này cho thấy dịch vụ cảm biến bị bế tắc hoặc bị hỏng và không xử lý các sự kiện cảm biến hoặc một loạt sự kiện cảm biến gần đây đã được đăng từ HAL phụ.

Nếu số lượng giới thiệu khóa đánh thức lớn hơn 0 , điều này có nghĩa là HalProxy đã có được khóa đánh thức. Giá trị này chỉ được lớn hơn 0 nếu ScopedWakelock được cố ý giữ lại hoặc nếu các sự kiện đánh thức được gửi tới HalProxy và chưa được khung cảm biến xử lý.

Bộ mô tả tệp được chuyển tới phương thức gỡ lỗi của HalProxy được chuyển đến từng HAL phụ nên các nhà phát triển phải triển khai phương thức gỡ lỗi như một phần của giao diện ISensorsSubHal .