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, phương thức triển khai truyền qua của Health 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 init, health@2.1-service đăng ký một phương thức triển khai giao diện IHealth thành hwservicemanager. Khi nâng cấp 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 cũ của nhà cung cấp đượ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ể "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 phiên bản "mặc định" nếu có, sau đó là "sao lưu".
    • 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, IHealth/backup và healthd có thể không được dùng nữa.

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

BOARD_PERIODIC_CHORES_INTERVAL_* là các biến dành riêng cho bảng được dùng để tạo healthd. Trong quá trình phân chia 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 bảng cho các mô-đun hệ thống. Những giá trị này từng bị ghi đè trong hàm healthd_board_init không dùng nữa.

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

Triển khai dịch vụ Health 2.1

Để biết thông tin về cách triển khai dịch vụ Health 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:

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

    Để đả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ụ liên kết IBatteryPropertiesRegistrar do BatteryService cung cấp thay vì healthd. BatteryService uỷ quyền lệnh gọi đến HAL sức khoẻ để truy xuất thông tin được yêu cầu.

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

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

Thay đổi về SELinux

HAL health@2.1 có các thay đổi sau đây về SELinux trong nền tảng:

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

Đối với những thiết bị có chế độ triển khai riêng, có thể cầ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 kernel

Trình nền healthd và chế độ 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 sau đây để truy xuất thông tin về pin:

  • /sys/class/power_supply/*/capacity_level (được thêm vào Health 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 Health 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 Health 2.1)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

Mọi hoạt động triển khai HAL về sức khoẻ dành riêng cho thiết bị đều sử dụng libbatterymonitor để truy cập vào các giao diện kernel này theo mặc định, 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 truy cập được từ healthd hoặc từ dịch vụ mặc định (ví dụ: tệp là một đường 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. Do đó, có thể cần thêm các thay đổi dành riêng cho nhà cung cấp đối với SELinux ngay cả khi bạn sử dụng chế độ triển khai mặc định.

Một số giao diện kernel được dùng trong Health 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 kernel, bạn nên chọn CL 1398913 trước khi tạo dịch vụ Health HAL 2.1.

Thử nghiệm

Android 11 có các thử nghiệm VTS mới được viết dành riêng cho HAL health@2.1. Nếu khai báo health@2.1 HAL trong tệp kê khai thiết bị, thì thiết bị phải vượt qua các kiểm thử VTS tương ứng. Các bài kiểm thử được viết cho cả phiên bản mặc định (để đảm bảo rằng thiết bị triển khai HAL đúng cách) và phiên bản dự phòng (để đảm bảo rằng 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 2.0 của Health nêu ra một bộ yêu cầu về giao diện HAL, nhưng các 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 kiểm thử VTS mới được thêm vào để thực thi các yêu cầu sau đây trên những thiết bị chạy Android 11 trở lên:

  • Đơn vị của dòng điện tức thời và dòng điện trung bình của pin phải là microampe (μA).
  • Dấu hiệu của dòng điện tức thời và dòng điện trung bình của pin 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
    • dòng điện < 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 có kết nối nguồn điện 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 có 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à truyền các giá trị từ giao diện nhân, 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 của pin được báo cáo bằng dấu và đơn vị chính xác. Điều này bao gồm các nút sysfs sau:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Giá trị dương cho biết dòng điện đi vào pin.
    • Giá trị phải tính bằng microampe (μA).
  • Đảm bảo điện áp pin được báo cáo bằng đơ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 chế độ triển khai HAL mặc định chia voltage_now cho 1000 và báo cáo các giá trị bằng milivolt (mV). Xem @1.0::HealthInfo.

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