| <html devsite><head> |
| <title>HIDL C++</title> |
| <meta name="project_path" value="/_project.yaml"/> |
| <meta name="book_path" value="/_book.yaml"/> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 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. |
| --> |
| |
| <p>Android O 对 Android 操作系统的架构重新进行了设计,以在独立于设备的 Android 平台与特定于设备和供应商的代码之间定义清晰的接口。Android 已经以 HAL 接口的形式(在 <code>hardware/libhardware</code> 下定义为 C 标头)定义了许多此类接口。HIDL 将这些 HAL 接口替换为稳定的带版本接口,它们可以是采用 C++ 的客户端和服务器端 HIDL 接口(如下所述)或 <a href="/devices/architecture/hidl-java/index.html">Java</a> 接口。</p> |
| |
| <p>本部分中的几页内容介绍了 HIDL 接口的 C++ 实现,其中详细说明了 <code>hidl-gen</code> 编译器基于 HIDL <code>.hal</code> 文件自动生成的文件,这些文件如何打包,以及如何将这些文件与使用它们的 C++ 代码集成。</p> |
| |
| <h2 id="client-server">客户端和服务器实现</h2> |
| <p>HIDL 接口具有客户端和服务器实现:</p> |
| |
| <ul> |
| <li>HIDL 接口的<strong>客户端</strong>实现是指通过在该接口上调用方法来使用该接口的代码。</li> |
| <li><strong>服务器</strong>实现是指 HIDL 接口的实现,它可接收来自客户端的调用并返回结果(如有必要)。</li> |
| </ul> |
| |
| <p>在从 <code>libhardware</code> HAL 转换为 HIDL HAL 的过程中,HAL 实现成为服务器,而调用 HAL 的进程则成为客户端。默认实现可提供直通和绑定式 HAL,并可能会随着时间而发生变化:</p> |
| |
| <p><img src="../images/treble_cpp_legacy_hal_progression.png"/></p> |
| <p><strong>图 1.</strong> 旧版 HAL 的发展历程。</p> |
| |
| <h2>创建 HAL 客户端</h2> |
| <p>首先将 HAL 库添加到 makefile 中:</p> |
| |
| <ul> |
| <li>Make:<code>LOCAL_SHARED_LIBRARIES += [email protected]</code></li> |
| <li>Soong:<code>shared_libs: [ …, [email protected] ]</code></li> |
| </ul> |
| |
| <p>接下来,添加 HAL 头文件:</p> |
| |
| <pre class="prettyprint"> |
| #include <android/hardware/nfc/1.0/IFoo.h> |
| … |
| // in code: |
| sp<IFoo> client = IFoo::getService(); |
| client->doThing(); |
| </pre> |
| |
| <h2>创建 HAL 服务器</h2> |
| <p>要创建 HAL 实现,您必须具有表示 HAL 的 <code>.hal</code> 文件并已在 <code>hidl-gen</code> 上使用 <code>-Lmakefile</code> 或 <code>-Landroidbp</code> 为 HAL 生成 makefile(<code>./hardware/interfaces/update-makefiles.sh</code> 会为内部 HAL 文件执行这项操作,这是一个很好的参考)。从 <code>libhardware</code> 通过 HAL 传输时,您可以使用 c2hal 轻松完成许多此类工作。</p> |
| |
| <p>创建必要的文件来实现您的 HAL:</p> |
| |
| <pre class="prettyprint"> |
| [email protected] |
| LOC=hardware/interfaces/nfc/1.0/default/ |
| make hidl-gen -j64 |
| hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \ |
| -randroid.hidl:system/libhidl/transport $PACKAGE |
| hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \ |
| -randroid.hidl:system/libhidl/transport $PACKAGE |
| </pre> |
| |
| <p>为了让 HAL 在直通模式下发挥作用(对于旧版设备),您必须具有 HIDL_FETCH_IModuleName 函数<em></em>(位于 <code>/system/lib(64)?/hw/[email protected](-$OPTIONAL_IDENTIFIER).so</code> 下),其中 <code>$OPTIONAL_IDENTIFIER</code> 是一个标识直通实现的字符串。直通模式要求会通过上述命令自动满足,这些命令也会创建 <code>[email protected]</code> 目标。</p> |
| |
| <p>接下来,使用功能填写存根并设置守护进程。守护进程代码(支持直通)示例:</p> |
| |
| <pre class="prettyprint"> |
| #include <hidl/LegacySupport.h> |
| |
| int main(int /* argc */, char* /* argv */ []) { |
| return defaultPassthroughServiceImplementation<INfc>("nfc"); |
| } |
| </pre> |
| |
| <p><code>defaultPassthroughServiceImplementation</code> 将对提供的 <code>-impl</code> 库执行 <code>dlopen()</code> 操作,并将其作为绑定式服务提供。守护进程代码(对于纯绑定式服务)示例:</p> |
| |
| <pre class="prettyprint"> |
| int main(int /* argc */, char* /* argv */ []) { |
| Nfc nfc = new Nfc(); |
| nfc->registerAsService(); |
| } |
| </pre> |
| |
| <p>此守护进程应该存在于 <code>$PACKAGE + "-service"</code>(例如 <code>[email protected]</code>)中。HAL 的特定类的 <a href="/security/selinux/device-policy.html">sepolicy</a> 是属性 <code>hal_<module></code>(例如 <code>hal_nfc)</code>)。您必须将此属性应用到运行特定 HAL 的守护进程(如果同一进程提供多个 HAL,则可以将多个属性应用到该进程)。</p> |
| |
| </body></html> |