Triển khai Health 2.1

Trong Android 11, tất cả mã healthd đượ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 chuyển tiếp của Health 2.1. Các thư viện liên kết tĩnh cho phép health@2.0-impl-2.1 làm công việc tương tự như healthd, chẳng hạn như chạy healthd_mainloop và thăm dò ý kiến. Trong quá trình khởi tạo, health@2.1-service sẽ đăng ký việc triển khai giao diện IHealth cho hwservicemanager. Khi nâng cấp thiết bị bằng 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ủa nhà cung cấp cũ được thực thi theo lịch biểu 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ể "mặc định" nếu có, sau đó là "bản 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/mặc định được cung cấp rộng rãi và hình ảnh nhà cung cấp Android 8.1 không còn được dùng nữa, IHealth/sao lưu và healthd có thể không còn được dùng nữa. Để biết thêm thông tin chi tiết, hãy xem phần Giảm giá sức khoẻ@1.0.

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 dùng nữa.

Trong health@2.1, nhà cung cấp có thể ghi đè hai 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 truyền đến hàm khởi tạo lớp triển khai sức khoẻ. Lớp triển khai trạng thái sẽ 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 gói trong health@2.0-impl.
  • recovery. Mối liên kết với libbatterymonitor được gói trong health@2.0-impl. Tất cả các lệnh gọi đến BatteryMonitor sẽ đượ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à khách hàng duy nhất của IBatteryPropertiesRegistrar.getProperty. IBatteryPropertiesRegistrar.getProperty do healthd cung cấp 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ụ 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 sử dụng HealthServiceWrapper để xác định xem có 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ẻ bản sao từ healthd. Sau đó, BatteryService theo dõi các sự kiện về sức khoẻ thông qua IHealth.registerCallback.

  • Đã lưu trữ. Trên Android 9 trở lên, storaged sử dụng libhealthhalutils để xác định xem nên sử dụng phiên bản dịch vụ sức khoẻ mặc định của vendor hay sử dụng phiên bản dịch vụ sức khoẻ sao lưu của 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 bộ nhớ.

Thay đổi SELinux

HAL health@2.1 bao gồm 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 các thiết bị có cách triển khai riêng, có thể bạn cần thực hiện một số thay đổi đối với 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

Trình nền healthd và phương thức 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 pin:

  • /sys/class/power_supply/*/capacity_level (đã thêm trong 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 (đã thêm trong 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 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 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 thể truy cập từ healthd hoặc từ dịch vụ mặc định (ví dụ: tệp là đườ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 bị định cấu hình sai), thì các tệp này có thể hoạt động khô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 mặc dù đang sử dụng phương thức triển khai mặc định.

Một số giao diện nhân 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ể không bắt buộc. Tuy nhiên, để ngăn chặn hành vi khung không chính xác do thiếu giao diện nhân, 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 bao gồm các 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 rằng thiết bị triển khai HAL đúng cách) và thực thể sao lưu (để đả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 Health 2.0 nêu ra một bộ yêu cầu trên giao diện HAL, nhưng các kiểm thử VTS tương ứng tương đối nới lỏng 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 các thiết bị chạy 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ì 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
    • dòng điện <= 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 về việc nguồn điện đã được kết nối hay chưa. Cụ thể:
    • trạng thái pin phải là một trong các giá trị 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à 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 giá trị chính xác:

  • Đảm bảo dòng pin được báo cáo bằng dấu và đơn vị chính xác. 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 đang đi vào pin.
    • Giá trị phải được tính bằng microampe (μA).
  • Đảm bảo điện áp pin được báo cáo bằng microvolt (μV). Bao gồm các nút sysfs sau:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • Xin lưu ý rằng cách triển khai HAL mặc định chia voltage_now cho 1000 và báo cáo các giá trị theo milivon (mV). Xem @1.0::HealthInfo.

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