blob: 6b8d99f90a71d596c8a6c14264709ba5502c7f71 [file] [log] [blame]
<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-&gt;init</code> 中覆盖这两个值(方法是弃用 <code>health@2.0-service.&lt;device&gt;</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 &lt;health2/service.h&gt;
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.md" class="external">hardware/interfaces/health/2.0/README.md</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/&lt;manufacturer&gt;/&lt;device&gt;/sepolicy/vendor/file_contexts
/vendor/bin/hw/android\.hardware\.health@2\.0-service.&lt;device&gt; u:object_r:hal_health_default_exec:s0
# device/&lt;manufacturer&gt;/&lt;device&gt;/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>