Triển khai Health 2.1

Trong Android 11, tất cả mã healthd đều được tái cấu trúc thành libhealthlooplibhealth2impl, sau đó được sửa đổi để triển khai HAL health@2.1. Hai thư viện này được liên kết tĩnh bằng health@2.0-impl-2.1, quá trình triển khai chuyển tiếp của Sức khoẻ 2.1. Các thư viện được liên kết tĩnh cho phép health@2.0-impl-2.1 thực hiện cùng một công việc như healthd, chẳng hạn như chạy healthd_mainloop và thăm dò ý kiến. Trong quá trình khởi động, health@2.1-service sẽ đăng ký quá trình triển khai giao diện IHealth với hwservicemanager. Khi nâng cấp các thiết bị có hình ảnh nhà cung cấp Android 8.x hoặc 9 và khung Android 11, hình ảnh nhà cung cấp có thể không cung cấp dịch vụ health@2.1. Khả năng tương thích ngược với hình ảnh nhà cung cấp cũ được thực thi theo lịch trình ngừng sử dụng.

Để đảm bảo khả năng tương thích ngược:

  1. healthd đăng ký IHealth với hwservicemanager mặc dù là một trình nền hệ thống. IHealth được thêm vào tệp kê khai hệ thống, với tên thực thể là "backup".
  2. Khung và storaged giao tiếp với healthd thông qua hwbinder thay vì binder.
  3. Mã cho khung và storaged được thay đổi để tìm nạp thực thể "default" (mặc định) nếu có, sau đó là "backup" (dự phòng).
    • Mã ứng dụng C++ sử dụng logic được xác định trong libhealthhalutils.
    • Mã ứng dụng Java sử dụng logic được xác định trong HealthServiceWrapper.
  4. Sau khi IHealth/default được cung cấp rộng rãi và hình ảnh nhà cung cấp Android 8.1 không được dùng nữa, bạn có thể ngừng sử dụng IHealth/backup và healthd.

Các biến bản dựng dành riêng cho bo mạch cho healthd

BOARD_PERIODIC_CHORES_INTERVAL_* là các biến dành riêng cho bo mạch dùng để tạo healthd. Trong quá trình phân tách bản dựng hệ thống/nhà cung cấp, bạn không thể xác định các giá trị dành riêng cho bo mạch cho các mô-đun hệ thống. Các giá trị này từng bị ghi đè trong hàm healthd_board_init không được dùng nữa.

Trong health@2.1, nhà cung cấp có thể ghi đè 2 giá trị khoảng thời gian công việc định kỳ này trong cấu trúc healthd_config trước khi chuyển sang hàm khởi tạo lớp triển khai sức khoẻ. Lớp triển khai sức khoẻ phải kế thừa từ android::hardware::health::V2_1::implementation::Health.

Triển khai dịch vụ Sức khoẻ 2.1

Để biết thông tin về cách triển khai dịch vụ Sức khoẻ 2.1, hãy xem hardware/interfaces/health/2.1/README.md.

Ứng dụng sức khoẻ

health@2.x có các ứng dụng sau:

  • charger. Việc sử dụng mã libbatterymonitorhealthd_common được gói trong health@2.0-impl.
  • recovery. Liên kết đến libbatterymonitor được gói trong health@2.0-impl. Tất cả lệnh gọi đến BatteryMonitor đều được thay thế bằng lệnh gọi vào lớp triển khai Health.
  • BatteryManager. BatteryManager.queryProperty(int id) là ứng dụng duy nhất của IBatteryPropertiesRegistrar.getProperty. IBatteryPropertiesRegistrar.getProperty được cung cấp bởi healthd và trực tiếp đọc /sys/class/power_supply.

    Để đảm bảo an toàn, các ứng dụng không được phép gọi trực tiếp vào HAL sức khoẻ. Trong Android 9 trở lên, dịch vụ trình liên kết IBatteryPropertiesRegistrar được cung cấp bởi BatteryService thay vì healthd. BatteryService uỷ quyền lệnh gọi cho HAL sức khoẻ để truy xuất thông tin được yêu cầu.

  • BatteryService. Trong Android 9 trở lên, BatteryService sử dụng HealthServiceWrapper để xác định xem có nên sử dụng thực thể dịch vụ sức khoẻ mặc định từ vendor hay sử dụng thực thể dịch vụ sức khoẻ dự phòng từ healthd. Sau đó, BatteryService sẽ theo dõi các sự kiện sức khoẻ thông qua IHealth.registerCallback.

  • Storaged. Trong Android 9 trở lên, storaged sử dụng libhealthhalutils để xác định xem có nên sử dụng thực thể dịch vụ sức khoẻ mặc định từ vendor hay sử dụng thực thể dịch vụ sức khoẻ dự phòng từ healthd. Sau đó, storaged sẽ theo dõi các sự kiện sức khoẻ thông qua IHealth.registerCallback và truy xuất thông tin về bộ nhớ.

Các thay đổi về SELinux

HAL health@2.1 bao gồm các thay đổi sau về SELinux trong nền tảng:

  • Thêm android.hardware.health@2.1-service vào file_contexts.

Đối với các thiết bị có quá trình triển khai riêng, bạn có thể cần thực hiện một số thay đổi về SELinux của nhà cung cấp. Ví dụ:

# device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te
# Add device specific permissions to hal_health_default domain, especially
# if it links to board-specific libhealthd or implements storage APIs.

Giao diện nhân hệ điều hành

Trình nền healthd và quá trình triển khai mặc định android.hardware.health@2.0-impl-2.1 truy cập vào các giao diện nhân hệ điều hành sau để truy xuất thông tin về pin:

  • /sys/class/power_supply/*/capacity_level (được thêm vào Sức khoẻ 2.1)
  • /sys/class/power_supply/*/capacity
  • /sys/class/power_supply/*/charge_counter
  • /sys/class/power_supply/*/charge_full
  • /sys/class/power_supply/*/charge_full_design (được thêm vào Sức khoẻ 2.1)
  • /sys/class/power_supply/*/current_avg
  • /sys/class/power_supply/*/current_max
  • /sys/class/power_supply/*/current_now
  • /sys/class/power_supply/*/cycle_count
  • /sys/class/power_supply/*/health
  • /sys/class/power_supply/*/online
  • /sys/class/power_supply/*/present
  • /sys/class/power_supply/*/status
  • /sys/class/power_supply/*/technology
  • /sys/class/power_supply/*/temp
  • /sys/class/power_supply/*/time_to_full_now (được thêm vào Sức khoẻ 2.1)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

Theo mặc định, mọi quá trình triển khai HAL sức khoẻ dành riêng cho thiết bị sử dụng libbatterymonitor đều truy cập vào các giao diện nhân hệ điều hành này, trừ phi bị ghi đè trong hàm khởi tạo lớp triển khai sức khoẻ.

Nếu các tệp này bị thiếu hoặc không thể truy cập được từ healthd hoặc từ dịch vụ mặc định (ví dụ: tệp là một liên kết tượng trưng đến một thư mục dành riêng cho nhà cung cấp từ chối quyền truy cập do chính sách SELinux được định cấu hình sai), thì các tệp này có thể không hoạt động đúng cách. Vì vậy, bạn có thể cần thực hiện thêm các thay đổi về SELinux dành riêng cho nhà cung cấp ngay cả khi sử dụng quá trình triển khai mặc định.

Một số giao diện nhân hệ điều hành được sử dụng trong Sức khoẻ 2.1, chẳng hạn như /sys/class/power_supply/*/capacity_level/sys/class/power_supply/*/time_to_full_now, có thể là không bắt buộc. Tuy nhiên, để ngăn chặn các hành vi không chính xác của khung do thiếu giao diện nhân hệ điều hành, bạn nên chọn lọc CL 1398913 trước khi tạo dịch vụ HAL Sức khoẻ 2.1.

Thử nghiệm

Android 11 bao gồm các bài kiểm thử VTS mới được viết riêng cho HAL health@2.1. Nếu một thiết bị khai báo HAL health@2.1 trong tệp kê khai thiết bị, thì thiết bị đó phải vượt qua các bài kiểm thử VTS tương ứng. Các bài kiểm thử được viết cho cả thực thể mặc định (để đảm bảo thiết bị triển khai HAL đúng cách) và thực thể dự phòng (để đảm bảo healthd tiếp tục hoạt động đúng cách trước khi bị xoá).

Yêu cầu về thông tin pin

HAL Sức khoẻ 2.0 nêu một tập hợp các yêu cầu về giao diện HAL, nhưng các bài kiểm thử VTS tương ứng tương đối thoải mái trong việc thực thi các yêu cầu đó. Trong Android 11, các bài kiểm thử VTS mới được thêm vào để thực thi các yêu cầu sau trên các thiết bị ra mắt bằng Android 11 trở lên:

  • Đơn vị của dòng điện pin tức thời và trung bình phải là microampe (μA).
  • Dấu của dòng điện pin tức thời và trung bình phải chính xác. Cụ thể:
    • current == 0 khi trạng thái pin là UNKNOWN
    • current > 0 khi trạng thái pin là CHARGING
    • current <= 0 khi trạng thái pin là NOT_CHARGING
    • current < 0 khi trạng thái pin là DISCHARGING
    • Không thực thi khi trạng thái pin là FULL
  • Trạng thái pin phải chính xác so với việc nguồn điện có được kết nối hay không. Cụ thể:
    • trạng thái pin phải là một trong các trạng thái CHARGING, NOT_CHARGING hoặc FULL nếu và chỉ khi nguồn điện được kết nối;
    • trạng thái pin phải là DISCHARGING nếu và chỉ khi nguồn điện bị ngắt kết nối.

Nếu bạn sử dụng libbatterymonitor trong quá trình triển khai và chuyển các giá trị từ giao diện nhân hệ điều hành, hãy đảm bảo các nút sysfs đang báo cáo các giá trị chính xác:

  • Đảm bảo dòng điện pin được báo cáo bằng dấu và đơn vị chính xác. Trong đó có các nút sysfs sau:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Các giá trị dương cho biết dòng điện đi vào pin.
    • Các giá trị phải ở đơn vị microampe (μA).
  • Đảm bảo điện áp pin được báo cáo ở đơn vị microvolt (μV). Trong đó có các nút sysfs sau:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • Xin lưu ý rằng quá trình triển khai HAL mặc định chia voltage_now cho 1000 và báo cáo các giá trị ở đơn vị milivolt (mV). Xem @1.0::HealthInfo.

Để biết thông tin chi tiết, hãy xem lớp nguồn Linux.