| <html devsite><head> |
| |
| <meta name="book_path" value="/_book.yaml"/> |
| |
| <meta name="project_path" value="/_project.yaml"/> |
| </head> |
| <body> |
| |
| <!-- |
| Copyright 2018 The Android Open Source Project |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| http://www.apache.org/licenses/LICENSE-2.0 |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <h1 id="implementing_health" class="page-title">实现“运行状况”</h1> |
| |
| <p>所有 <code>healthd</code> 代码均已重构为 health@2.0-impl 和 <code>libhealthservice</code>,然后均已经过修改以实现 health@2.0 HAL。这两个库通过 health@2.0-service 进行静态关联,这使得 health@2.0-service 能够完成之前由 <code>healthd</code> 完成的作业(即运行 <code>healthd_mainloop</code> 并完成轮询)。在 init 中,health@2.0-service 会将接口 <code>IHealth</code> 的实现注册到 <code>hwservicemanager</code>。在升级搭载 Android 8.x 供应商映像和 Android 9 框架的设备时,供应商映像可能不提供 health@2.0 服务。这项服务是按照<a href="/devices/architecture/vintf/fcm#hal-version-deprecation">弃用时间表</a>强制执行的。</p> |
| |
| <p>为了解决此问题:</p> |
| |
| <ol> |
| <li><code>healthd</code> 会将 <code>IHealth</code> 注册到 <code>hwservicemanager</code>(尽管它是系统守护进程)。<code>IHealth</code> 会被添加到系统清单中(实例名称为“backup”)。</li> |
| <li>框架和 <code>storaged</code> 会通过 <code>healthd</code>(而不是 <code>hwbinder</code>)与 <code>binder</code> 进行通信。</li> |
| <li>框架和 <code>storaged</code> 的代码会进行更改,以获取实例“default”(如果有),然后获取“backup”。 |
| <ul> |
| <li>C++ 客户端代码会使用 <code>libhealthhalutils</code> 中定义的逻辑。</li> |
| <li>Java 客户端代码会使用 <code>HealthServiceWrapper</code> 中定义的逻辑。</li> |
| </ul></li> |
| <li>在广泛推出 IHealth/default 实例且弃用 Android 8.1 供应商映像后,就可以弃用 IHealth/backup 实例和 <code>healthd</code> 了。如需了解详情,请参阅<a href="/devices/tech/health/deprecation">弃用 health@1.0</a>。</li> |
| </ol> |
| |
| <h2 id="board_specific_build_variables_for_healthd">针对 healthd 的板级编译变量</h2> |
| |
| <p><code>BOARD_PERIODIC_CHORES_INTERVAL_*</code> 是用于编译 <code>healthd</code> 的板级变量。板级值用于分隔系统编译部分和供应商编译部分,<strong>无法</strong>针对系统模块定义进行定义。在 health@2.0 中,供应商可以在 <code>healthd_mode_ops->init</code> 中覆盖这两个值(方法是弃用 <code>health@2.0-service.<device></code> 中的 <code>libhealthservice</code> 依赖项并重新实现此函数)。</p> |
| |
| <h2 id="static_implementation_library">静态实现库</h2> |
| |
| <p>与其他 HAL 实现库不同,实现库 health@2.0-impl 是一个<strong>静态</strong>库,health@2.0-service、charger、recovery 和旧版 healthd 均关联到此库。</p> |
| |
| <p>health@2.0.impl 会实现 <code>IHealth</code>(如上所述),并旨在封装 <code>libbatterymonitor</code> 和 <code>libhealthd.<var>BOARD</var></code>。这些 health@2.0-impl 用户不得直接使用 <code>BatteryMonitor</code> 或 <code>libhealthd</code> 中的函数,而应该将这些调用替换为对 <code>Health</code> 类的调用(即实现 <code>IHealth</code> 接口)。为了进一步进行泛化,<code>healthd_common</code> 代码也会包含在 health@2.0-impl 中。新的 <code>healthd_common</code> 包含 health@2.0-service、charger 和 <code>healthd</code> 之间公用代码的剩余部分,并会调用 IHealth 方法(而不是 BatteryMonitor)。</p> |
| |
| <h2 id="implementing_health_20_service">实现 Health 2.0 服务</h2> |
| |
| <p>在为设备实现 health@2.0 服务时,如果默认实现:</p> |
| |
| <ul> |
| <li>足以用于设备,则直接使用 <code>android.hardware.health@2.0-service</code>。</li> |
| <li><p>不足以用于设备,则创建 <code>android.hardware.health@2.0-service.(device)</code> 可执行文件并包括:</p> |
| <pre class="prettyprint"><code>#include <health2/service.h> |
| int main() { return health_service_main(); } |
| </code></pre></li> |
| </ul> |
| |
| <p>然后:</p> |
| |
| <ul> |
| <li><p>如果板级 <code>libhealthd:</code></p> |
| |
| <ul> |
| <li>确实存在,则与其关联。</li> |
| <li>不存在,则提供针对 <code>healthd_board_init</code> 和 <code>healthd_board_battery_update</code> 函数的空实现。</li> |
| </ul></li> |
| <li><p>如果板级 <code>BOARD_PERIODIC_CHORES_INTERVAL_*</code> 变量:</p> |
| |
| <ul> |
| <li>已定义,则创建设备特定的 <code>HealthServiceCommon.cpp</code>(从 <code>hardware/interfaces/health/2.0/utils/libhealthservice</code> 中复制),并在 <code>healthd_mode_service_2_0_init</code> 中对其进行自定义。</li> |
| <li>未定义,则静态关联到 <code>libhealthservice</code>。</li> |
| </ul></li> |
| <li><p>如果设备:</p> |
| |
| <ul> |
| <li>应该实现 <code>getStorageInfo</code> 和 <code>getDiskStats</code> API,则在 <code>get_storage_info</code> 和 <code>get_disk_stats</code> 函数中提供实现。</li> |
| <li>不应该实现这些 API,则静态关联到 <code>libstoragehealthdefault</code>。</li> |
| </ul></li> |
| <li><p>更新必要的 SELinux 权限。</p></li> |
| </ul> |
| |
| <p>如需了解详情,请参阅 <a href="https://android.googlesource.com/platform/hardware/interfaces/+/master/health/2.0/README">hardware/interfaces/health/2.0/README</a>。</p> |
| |
| <h2 id="health_clients">Health 客户端</h2> |
| |
| <p>health@2.0 具有以下客户端:</p> |
| |
| <ul> |
| <li><strong>charger</strong>。<code>libbatterymonitor</code> 和 <code>healthd_common</code> 代码的使用情况信息封装在 health@2.0-impl 中。</li> |
| <li><strong>recovery</strong>。<code>libbatterymonitor</code> 的链接封装在 health@2.0-impl 中。对 <code>Health</code> 实现类的调用取代了对 <code>BatteryMonitor</code> 的所有调用。</li> |
| <li><p><strong>BatteryManager</strong>。<code>BatteryManager.queryProperty(int id)</code> 是 <code>IBatteryPropertiesRegistrar.getProperty</code>(由 <code>healthd</code> 提供并直接读取 <code>/sys/class/power_supply</code>)的唯一客户端。</p> |
| |
| <p>出于安全方面的考虑,不允许应用直接调用 Health HAL。在 Android 9 中,Binder 服务 <code>IBatteryPropertiesRegistrar</code> 由 <code>BatteryService</code>(而非 <code>healthd</code>)提供,<code>BatteryService</code> 会将调用委派给 Health HAL 以检索请求的信息。</p></li> |
| <li><p><strong>BatteryService</strong>。在 Android 9 中,<code>BatteryService</code> 使用 <code>HealthServiceWrapper</code> 来确定要使用的 Health 服务实例(来自供应商的“default”实例或来自 healthd 的“backup”实例)。然后,它通过 <code>IHealth.registerCallback</code> 侦听 Health 事件。</p></li> |
| <li><p><strong>Storaged</strong>。在 Android 9 中,<code>storaged</code> 使用 <code>libhealthhalutils</code> 来确定要使用的 Health 服务实例(来自供应商的“default”实例或来自 healthd 的“backup”实例)。然后,它通过 <code>IHealth.registerCallback</code> 侦听 Health 事件并检索存储信息。</p></li> |
| </ul> |
| |
| <h2 id="selinux_changes">SELinux 变更</h2> |
| |
| <p>新的 health@2.0 HAL 包括以下 SELinux 变更:</p> |
| |
| <ul> |
| <li>将 health@2.0-service 添加到 <code>file_contexts</code>。</li> |
| <li>允许 <code>system_server</code> 和 <code>storaged</code> 使用 <code>hal_health</code>。</li> |
| <li>允许 <code>system_server</code> (<code>BatteryService</code>) 注册 <code>batteryproperties_service</code> (<code>IBatteryPropertiesRegistrar</code>)。</li> |
| <li>允许 <code>healthd</code> 提供 <code>hal_health</code>。</li> |
| <li>移除允许 <code>system_server</code>/<code>storaged</code> 通过 Binder 调用 <code>healthd</code> 的规则。</li> |
| <li>移除允许 <code>healthd</code> 注册 <code>batteryproperties_service</code> (<code>IBatteryPropertiesRegistrar</code>) 的规则。</li> |
| </ul> |
| |
| <p>对于具有自己实现的设备,一些供应商 SELinux 变更可能是必须的。例如:</p> |
| <pre class="prettyprint"><code># device/<manufacturer>/<device>/sepolicy/vendor/file_contexts |
| /vendor/bin/hw/android\.hardware\.health@2\.0-service.<device> u:object_r:hal_health_default_exec:s0 |
| |
| # 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. |
| </code></pre> |
| <h2 id="kernel_interfaces">内核接口</h2> |
| |
| <p><code>healthd</code> 守护进程和默认实现 <code>android.hardware.health@2.0-service</code> 会访问以下内核接口以检索电池信息:</p> |
| |
| <ul> |
| <li><code>/sys/class/power_supply/*/capacity</code></li> |
| <li><code>/sys/class/power_supply/*/charge_counter</code></li> |
| <li><code>/sys/class/power_supply/*/charge_full</code></li> |
| <li><code>/sys/class/power_supply/*/current_avg</code></li> |
| <li><code>/sys/class/power_supply/*/current_max</code></li> |
| <li><code>/sys/class/power_supply/*/current_now</code></li> |
| <li><code>/sys/class/power_supply/*/cycle_count</code></li> |
| <li><code>/sys/class/power_supply/*/health</code></li> |
| <li><code>/sys/class/power_supply/*/online</code></li> |
| <li><code>/sys/class/power_supply/*/present</code></li> |
| <li><code>/sys/class/power_supply/*/status</code></li> |
| <li><code>/sys/class/power_supply/*/technology</code></li> |
| <li><code>/sys/class/power_supply/*/temp</code></li> |
| <li><code>/sys/class/power_supply/*/type</code></li> |
| <li><code>/sys/class/power_supply/*/voltage_max</code></li> |
| <li><code>/sys/class/power_supply/*/voltage_now</code></li> |
| </ul> |
| |
| <p>默认情况下,使用 <code>libbatterymonitor</code> 的任何设备特定的 Health HAL 实现都会访问这些内核接口(除非它们在 <code>healthd_board_init(struct healthd_config*)</code> 中被覆盖)。</p> |
| |
| <p>如果这些文件缺失或者无法从 <code>healthd</code> 或默认服务访问这些文件(例如,文件是一个指向供应商专用文件夹的符号链接,因 SELinux 政策配置错误而拒绝访问),则文件无法访问。因此,即使使用的是默认实现,也可能需要进行其他的供应商特定 SELinux 变更。</p> |
| |
| <h2 id="testing">测试</h2> |
| |
| <p>Android 9 包括专门为 health@2.0 HAL 编写的新 <a href="/compatibility/vts">VTS 测试</a>。如果设备声明在设备清单中提供 health@2.0 HAL,则该设备必须通过相应的 VTS 测试。这些测试是为“default”实例(确保设备正确实现 HAL)和“backup”实例(确保 <code>healthd</code> 在被移除之前继续正常发挥作用)编写的。</p> |
| |
| </body></html> |