ติดตั้งใช้งาน Health 2.1

ใน Android 11 เราได้ปรับโครงสร้างโค้ด healthd ทั้งหมดเป็น libhealthloop และ libhealth2impl แล้วแก้ไขเพื่อติดตั้งใช้งาน health@2.1 HAL health@2.0-impl-2.1 ซึ่งเป็นการติดตั้งใช้งานแบบ Passthrough ของ Health 2.1 จะลิงก์ไลบรารีทั้ง 2 นี้แบบคงที่ ไลบรารีที่ลิงก์แบบคงที่ ช่วยให้ health@2.0-impl-2.1 ทำงานได้เหมือนกับ healthd เช่น การเรียกใช้ healthd_mainloop และการโพล ใน init, health@2.1-service จะลงทะเบียนการติดตั้งใช้งานอินเทอร์เฟซ IHealth กับ hwservicemanager เมื่ออัปเกรดอุปกรณ์ด้วยอิมเมจของผู้ให้บริการ Android 8.x หรือ 9 และเฟรมเวิร์ก Android 11 อิมเมจของผู้ให้บริการอาจไม่มีบริการ health@2.1 การบังคับใช้ความเข้ากันได้แบบย้อนหลังกับอิมเมจของผู้ให้บริการรุ่นเก่าจะเป็นไปตาม กำหนดการเลิกใช้งาน

วิธีตรวจสอบความเข้ากันได้แบบย้อนหลัง

  1. healthd จะลงทะเบียน IHealth กับ hwservicemanager แม้ว่าจะเป็น Daemon ของระบบก็ตาม เราได้เพิ่ม IHealth ลงในไฟล์ Manifest ของระบบโดยใช้ชื่ออินสแตนซ์ "backup"
  2. เฟรมเวิร์กและ storaged จะสื่อสารกับ healthd ผ่าน hwbinder แทน binder
  3. เราได้เปลี่ยนโค้ดสำหรับเฟรมเวิร์กและ storaged เพื่อดึงข้อมูลอินสแตนซ์ "default" หากมี แล้วจึงดึงข้อมูล "backup"
    • โค้ดไคลเอ็นต์ C++ ใช้ตรรกะที่กำหนดไว้ใน libhealthhalutils
    • โค้ดไคลเอ็นต์ Java ใช้ตรรกะที่กำหนดไว้ใน HealthServiceWrapper
  4. หลังจากที่ IHealth/default พร้อมใช้งานอย่างแพร่หลายและเราเลิกใช้งานอิมเมจของผู้ให้บริการ Android 8.1 แล้ว เราจะเลิกใช้งาน IHealth/backup และ healthd ได้

ตัวแปรบิลด์เฉพาะบอร์ดสำหรับ healthd

BOARD_PERIODIC_CHORES_INTERVAL_* เป็นตัวแปรเฉพาะบอร์ดที่ใช้สร้าง healthd การแยกบิลด์ระบบ/ผู้ให้บริการทำให้เรา กำหนด ค่าเฉพาะบอร์ดสำหรับโมดูลระบบไม่ได้ ค่าเหล่านี้เคยถูกลบล้างในฟังก์ชัน healthd_board_init ที่เลิกใช้งานแล้ว

ใน health@2.1 ผู้ให้บริการสามารถลบล้างค่าช่วงเวลาของงานที่ทำเป็นระยะๆ 2 ค่านี้ในโครงสร้าง healthd_config ก่อนที่จะส่งไปยังคอนสตรักเตอร์ของคลาสการติดตั้งใช้งาน Health คลาสการติดตั้งใช้งาน Health ควรรับค่ามาจาก android::hardware::health::V2_1::implementation::Health

ติดตั้งใช้งานบริการ Health 2.1

ดูข้อมูลเกี่ยวกับการติดตั้งใช้งานบริการ Health 2.1 ได้ที่ hardware/interfaces/health/2.1/README.md

ไคลเอ็นต์ Health

health@2.x มีไคลเอ็นต์ต่อไปนี้

  • charger การใช้โค้ด libbatterymonitor และ healthd_common จะรวมอยู่ใน health@2.0-impl
  • recovery การลิงก์กับ libbatterymonitor จะรวมอยู่ใน health@2.0-impl การเรียกใช้ BatteryMonitor ทั้งหมดจะถูกแทนที่ด้วยการเรียกใช้คลาสการติดตั้งใช้งาน Health
  • BatteryManager BatteryManager.queryProperty(int id) เป็นไคลเอ็นต์เดียวของ IBatteryPropertiesRegistrar.getProperty IBatteryPropertiesRegistrar.getProperty ได้รับจาก healthd และอ่าน /sys/class/power_supply โดยตรง

    เนื่องจากข้อควรพิจารณาด้านความปลอดภัย เราจึงไม่อนุญาตให้แอปเรียกใช้ health HAL โดยตรง ใน Android 9 ขึ้นไป BatteryService จะเป็นผู้ให้บริการ Binder IBatteryPropertiesRegistrar แทน healthd BatteryService จะมอบสิทธิ์การเรียกใช้ health HAL เพื่อดึงข้อมูลที่ขอ

  • BatteryService ใน Android 9 ขึ้นไป BatteryService จะใช้ HealthServiceWrapper เพื่อพิจารณาว่าจะใช้อินสแตนซ์บริการ Health เริ่มต้น จาก vendor หรือใช้อินสแตนซ์บริการ Health สำรอง จาก healthd จากนั้น BatteryService จะฟังเหตุการณ์ Health ผ่าน IHealth.registerCallback

  • Storaged ใน Android 9 ขึ้นไป storaged จะใช้ libhealthhalutils เพื่อพิจารณาว่าจะใช้อินสแตนซ์บริการ Health เริ่มต้น จาก vendor หรือใช้อินสแตนซ์บริการ Health สำรอง จาก healthd จากนั้น storaged จะฟังเหตุการณ์ Health ผ่าน IHealth.registerCallback และดึงข้อมูลพื้นที่เก็บข้อมูล

การเปลี่ยนแปลง SELinux

health@2.1 HAL มีการเปลี่ยนแปลง SELinux ต่อไปนี้ในแพลตฟอร์ม

  • เพิ่ม android.hardware.health@2.1-service ลงใน file_contexts

สำหรับอุปกรณ์ที่มีการติดตั้งใช้งานของตัวเอง อาจจำเป็นต้องมีการเปลี่ยนแปลง SELinux ของผู้ให้บริการบางอย่าง ตัวอย่าง

# 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.

อินเทอร์เฟซเคอร์เนล

Daemon healthd และการติดตั้งใช้งานเริ่มต้น android.hardware.health@2.0-impl-2.1 จะเข้าถึงอินเทอร์เฟซเคอร์เนลต่อไปนี้เพื่อดึงข้อมูลแบตเตอรี่

  • /sys/class/power_supply/*/capacity_level (เพิ่มใน 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 (เพิ่มใน 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 (เพิ่มใน Health 2.1)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

การติดตั้งใช้งาน health HAL เฉพาะอุปกรณ์ที่ใช้ libbatterymonitor จะเข้าถึงอินเทอร์เฟซเคอร์เนลเหล่านี้โดยค่าเริ่มต้น เว้นแต่จะมีการลบล้างในคอนสตรักเตอร์ของคลาสการติดตั้งใช้งาน Health

หากไฟล์เหล่านี้หายไปหรือไม่สามารถเข้าถึงได้จาก healthd หรือจากบริการเริ่มต้น (เช่น ไฟล์เป็นลิงก์สัญลักษณ์ไปยังโฟลเดอร์เฉพาะของผู้ให้บริการซึ่งปฏิเสธการเข้าถึงเนื่องจากนโยบาย SELinux ที่กำหนดค่าไม่ถูกต้อง) ไฟล์เหล่านี้อาจทำงานไม่ถูกต้อง ดังนั้นอาจจำเป็นต้องมีการเปลี่ยนแปลง SELinux เฉพาะของผู้ให้บริการเพิ่มเติม แม้ว่าจะใช้การติดตั้งใช้งานเริ่มต้นก็ตาม

อินเทอร์เฟซเคอร์เนลบางรายการที่ใช้ใน Health 2.1 เช่น /sys/class/power_supply/*/capacity_level และ /sys/class/power_supply/*/time_to_full_now อาจเป็นตัวเลือก อย่างไรก็ตาม เพื่อป้องกันไม่ให้เฟรมเวิร์กทำงานไม่ถูกต้องเนื่องจากอินเทอร์เฟซเคอร์เนลหายไป เราขอแนะนำให้เลือกใช้ CL 1398913 ก่อนสร้างบริการ Health HAL 2.1

การทดสอบ

Android 11 มีการทดสอบ VTS ใหม่ ที่เขียนขึ้นมาโดยเฉพาะสำหรับ health@2.1 HAL หากอุปกรณ์ประกาศ health@2.1 HAL ในไฟล์ Manifest ของอุปกรณ์ อุปกรณ์นั้นจะต้องผ่านการทดสอบ VTS ที่เกี่ยวข้อง เราได้เขียนการทดสอบสำหรับทั้งอินสแตนซ์เริ่มต้น (เพื่อให้แน่ใจว่าอุปกรณ์ติดตั้งใช้งาน HAL อย่างถูกต้อง) และอินสแตนซ์สำรอง (เพื่อให้แน่ใจว่า healthd จะทำงานต่อไปได้อย่างถูกต้องก่อนที่จะนำออก)

ข้อกำหนดด้านข้อมูลแบตเตอรี่

Health 2.0 HAL ระบุชุดข้อกำหนดเกี่ยวกับอินเทอร์เฟซ HAL แต่การทดสอบ VTS ที่เกี่ยวข้องค่อนข้างยืดหยุ่นในการบังคับใช้ข้อกำหนดเหล่านั้น ใน Android 11 เราได้เพิ่มการทดสอบ VTS ใหม่เพื่อบังคับใช้ข้อกำหนดต่อไปนี้ในอุปกรณ์ที่เปิดตัวด้วย Android 11 ขึ้นไป

  • หน่วยของกระแสไฟแบตเตอรี่แบบทันทีและแบบเฉลี่ยต้องเป็นไมโครแอมป์ (μA)
  • เครื่องหมายของกระแสไฟแบตเตอรี่แบบทันทีและแบบเฉลี่ยต้องถูกต้อง โดยเฉพาะอย่างยิ่ง
    • current == 0 เมื่อสถานะแบตเตอรี่เป็น UNKNOWN
    • current > 0 เมื่อสถานะแบตเตอรี่เป็น CHARGING
    • current <= 0 เมื่อสถานะแบตเตอรี่เป็น NOT_CHARGING
    • current < 0 เมื่อสถานะแบตเตอรี่เป็น DISCHARGING
    • ไม่บังคับใช้เมื่อสถานะแบตเตอรี่เป็น FULL
  • สถานะแบตเตอรี่ต้องถูกต้องตามการเชื่อมต่อแหล่งจ่ายไฟ โดยเฉพาะอย่างยิ่ง
    • สถานะแบตเตอรี่ต้องเป็น CHARGING, NOT_CHARGING, หรือ FULL หาก และเมื่อมีการเชื่อมต่อแหล่งจ่ายไฟ
    • สถานะแบตเตอรี่ต้องเป็น DISCHARGING หากและเมื่อมีการยกเลิกการเชื่อมต่อแหล่งจ่ายไฟ

หากคุณใช้ libbatterymonitor ในการติดตั้งใช้งานและส่งค่าจากอินเทอร์เฟซเคอร์เนลแบบ Passthrough ให้ตรวจสอบว่าโหนด sysfs รายงานค่าที่ถูกต้อง

  • ตรวจสอบว่ามีการรายงานกระแสไฟแบตเตอรี่ด้วยเครื่องหมายและหน่วยที่ถูกต้อง ซึ่งรวมถึงโหนด sysfs ต่อไปนี้
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • ค่าบวกแสดงถึงกระแสไฟที่ไหลเข้าสู่แบตเตอรี่
    • ค่าควรเป็นไมโครแอมป์ (μA)
  • ตรวจสอบว่ามีการรายงานแรงดันไฟแบตเตอรี่เป็นไมโครโวลต์ (μV) ซึ่งรวมถึงโหนด sysfs ต่อไปนี้
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • โปรดทราบว่าการติดตั้งใช้งาน HAL เริ่มต้นจะหาร voltage_now ด้วย 1000 และรายงานค่าเป็นมิลลิโวลต์ (mV) ดู @1.0::HealthInfo

ดูรายละเอียดได้ที่ คลาสแหล่งจ่ายไฟของ Linux