Health 2.1 लागू करना

Android 11 में, healthd के सभी कोड को libhealthloop और libhealth2impl में रिफ़ैक्टर किया गया है. इसके बाद, health@2.1 HAL को लागू करने के लिए, इनमें बदलाव किया गया है. इन दोनों लाइब्रेरी को, Health 2.1 के पासथ्रू लागू करने वाले health@2.0-impl-2.1 से स्टैटिक तौर पर लिंक किया जाता है. स्टैटिक तौर पर लिंक की गई लाइब्रेरीज़ health@2.0-impl-2.1 को healthd जैसा काम करने की अनुमति देती हैं. जैसे, healthd_mainloop को रन करना और पोलिंग करना. init में, health@2.1-service, hwservicemanager के लिए, इंटरफ़ेस IHealth का एक लागू करने वाला वर्शन रजिस्टर करता है. Android 8.x या 9 के वेंडर इमेज और Android 11 फ़्रेमवर्क वाले डिवाइसों को अपग्रेड करने पर, हो सकता है कि वेंडर इमेज, health@2.1 सेवा उपलब्ध न कराए. पुराने वेंडर इमेज के साथ बैकवर्ड कंपैटिबिलिटी, बंद करने के शेड्यूल के हिसाब से लागू की जाती है.

बैकवर्ड कंपैटिबिलिटी पक्का करने के लिए:

  1. healthd , सिस्टम डेमॉन होने के बावजूद, hwservicemanager के लिए IHealth रजिस्टर करता है. IHealth को सिस्टम मेनिफ़ेस्ट में जोड़ा जाता है. इसका इंस्टेंस नेम "backup" होता है.
  2. फ़्रेमवर्क और storaged, binder के बजाय hwbinder के ज़रिए healthd से कम्यूनिकेट करते हैं.
  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 में, वेंडर, इन दो वैल्यू को health implementation class constructor को पास करने से पहले, healthd_config struct में बदल सकते हैं. health implementation class को 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 implementation class में मौजूद कॉल से बदल दिया जाता है.
  • BatteryManager. BatteryManager.queryProperty(int id) , IBatteryPropertiesRegistrar.getProperty का इकलौता क्लाइंट था. IBatteryPropertiesRegistrar.getProperty , healthd से उपलब्ध कराया जाता था और सीधे तौर पर /sys/class/power_supply को पढ़ा जाता था.

    सुरक्षा को ध्यान में रखते हुए, ऐप्लिकेशन को सीधे तौर पर health HAL को कॉल करने की अनुमति नहीं होती. Android 9 और इसके बाद के वर्शन में, बाइंडर सेवा IBatteryPropertiesRegistrar, healthd के बजाय BatteryService से उपलब्ध कराई जाती है. मांगी गई जानकारी पाने के लिए, BatteryService, health HAL को कॉल डेलिगेट करता है.

  • BatteryService. Android 9 और इसके बाद के वर्शन में, BatteryService, यह तय करने के लिए HealthServiceWrapper का इस्तेमाल करता है कि vendor से डिफ़ॉल्ट health service instance का इस्तेमाल किया जाए या healthd से बैकअप health service instance का इस्तेमाल किया जाए. इसके बाद, BatteryService, IHealth.registerCallback के ज़रिए, हेल्थ इवेंट के लिए सुनता है.

  • Storaged. Android 9 और इसके बाद के वर्शन में, storaged, यह तय करने के लिए libhealthhalutils का इस्तेमाल करता है कि vendor से डिफ़ॉल्ट health service instance का इस्तेमाल किया जाए या healthd से बैकअप health service instance का इस्तेमाल किया जाए. इसके बाद, storaged, 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.

कर्नेल इंटरफ़ेस

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 implementation class constructor में बदला जा सकता है.

अगर ये फ़ाइलें मौजूद नहीं हैं या healthd या डिफ़ॉल्ट सेवा से इन्हें ऐक्सेस नहीं किया जा सकता है (उदाहरण के लिए, फ़ाइल, वेंडर के हिसाब से बनाए गए किसी फ़ोल्डर का सिंबॉलिक लिंक है, जो गलत तरीके से कॉन्फ़िगर की गई SELinux नीति की वजह से ऐक्सेस नहीं किया जा सकता), तो हो सकता है कि ये सही तरीके से काम न करें. इसलिए, डिफ़ॉल्ट तौर पर लागू करने वाले वर्शन का इस्तेमाल करने के बावजूद, वेंडर के हिसाब से SELinux में कुछ और बदलाव करने पड़ सकते हैं.

Health 2.1 में इस्तेमाल किए गए कुछ कर्नेल इंटरफ़ेस, जैसे कि /sys/class/power_supply/*/capacity_level और /sys/class/power_supply/*/time_to_full_now वैकल्पिक हो सकते हैं. हालांकि, कर्नेल इंटरफ़ेस के मौजूद न होने की वजह से, फ़्रेमवर्क के गलत तरीके से काम करने से बचने के लिए, हमारा सुझाव है कि Health HAL 2.1 सेवा बनाने से पहले, CL 1398913 को चेरी-पिक करें.

जांच करना

Android 11 में, VTS के नए टेस्ट शामिल हैं. इन्हें खास तौर पर health@2.1 HAL के लिए लिखा गया है. अगर कोई डिवाइस, डिवाइस मेनिफ़ेस्ट में health@2.1 HAL के बारे में बताता है, तो उसे VTS के संबंधित टेस्ट पास करने होंगे. टेस्ट, डिफ़ॉल्ट इंस्टेंस (यह पक्का करने के लिए कि डिवाइस, HAL को सही तरीके से लागू करता है) और बैकअप इंस्टेंस (यह पक्का करने के लिए कि healthd को हटाने से पहले, वह सही तरीके से काम करता रहे) दोनों के लिए लिखे जाते हैं.

बैटरी की जानकारी से जुड़ी ज़रूरी शर्तें

Health 2.0 HAL, HAL इंटरफ़ेस के लिए कुछ ज़रूरी शर्तें तय करता है. हालांकि, VTS के संबंधित टेस्ट में, इन्हें लागू करने के लिए ज़्यादा सख्ती नहीं बरती जाती. Android 11 में, VTS के नए टेस्ट जोड़े गए हैं. इनका मकसद, Android 11 और इसके बाद के वर्शन वाले डिवाइसों पर, इन ज़रूरी शर्तों को लागू करना है:

  • बैटरी की मौजूदा और औसत करंट की यूनिट, माइक्रोएंपियर (μA) होनी चाहिए.
  • बैटरी की तात्कालिक और औसत करंट का साइन सही होना चाहिए. खास तौर पर:
    • जब बैटरी की स्थिति UNKNOWN हो, तो current == 0 होना चाहिए
    • जब बैटरी की स्थिति CHARGING हो, तो current > 0 होना चाहिए
    • जब बैटरी की स्थिति NOT_CHARGING हो, तो current <= 0 होना चाहिए
    • जब बैटरी की स्थिति DISCHARGING हो, तो current < 0 होना चाहिए
    • जब बैटरी की स्थिति FULL हो, तो इसे लागू नहीं किया जाता
  • बैटरी की स्थिति, पावर सोर्स के कनेक्ट होने या न होने के हिसाब से सही होनी चाहिए. खास तौर पर:
    • बैटरी की स्थिति, CHARGING, NOT_CHARGING या FULL में से कोई एक होनी चाहिए. यह सिर्फ़ तब लागू होता है, जब कोई पावर सोर्स कनेक्ट हो.
    • बैटरी की स्थिति DISCHARGING होनी चाहिए. यह सिर्फ़ तब लागू होता है, जब कोई पावर सोर्स कनेक्ट न हो.

अगर आपने अपने लागू करने वाले वर्शन में libbatterymonitor का इस्तेमाल किया है और कर्नेल इंटरफ़ेस से वैल्यू पास की हैं, तो पक्का करें कि 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 को 1,000 से भाग देता है और वैल्यू को मिलीवोल्ट (mV) में रिपोर्ट करता है. @1.0::HealthInfo देखें.

ज़्यादा जानकारी के लिए, Linux power supply class देखें.