| <html devsite> |
| <head> |
| <title>Interfaces & Packages</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>HIDL is built around interfaces, an abstract type used in object-oriented |
| languages to define behaviors. Each interface is part of a package.</p> |
| |
| <h2 id=packages>Packages</h2> |
| |
| <p>Package names can have sublevels such as <code>package.subpackage</code>. The |
| root directory for published HIDL packages is <code>hardware/interfaces</code> |
| or <code>vendor/vendorName</code> (e.g. <code>vendor/google</code> for Pixel |
| devices). The package name forms one or more subdirectories under the root |
| directory; all files defining a package are in the same directory. For example, |
| <code>package [email protected]</code> could be found |
| under <code>hardware/interfaces/example/extension/light/2.0</code>.</p> |
| |
| <p>The following table lists package prefixes and locations:</p> |
| <table> |
| <tbody> |
| |
| <tr> |
| <th>Package Prefix</th> |
| <th>Location</th> |
| </tr> |
| |
| <tr> |
| <td><code>android.hardware.*</code></td> |
| <td><code>hardware/interfaces/*</code></td> |
| </tr> |
| |
| <tr> |
| <td><code>android.frameworks.*</code></td> |
| <td><code>frameworks/hardware/interfaces/*</code></td> |
| </tr> |
| |
| <tr> |
| <td><code>android.system.*</code></td> |
| <td><code>system/hardware/interfaces/*</code></td> |
| </tr> |
| |
| <tr> |
| <td><code>android.hidl.*</code></td> |
| <td><code>system/libhidl/transport/*</code></td> |
| </tr> |
| |
| </tbody> |
| </table> |
| |
| <p>The package directory contains files with extension <code>.hal</code>. Every |
| file must contain a <code>package</code> statement naming the package and |
| version the file is part of. The file <code>types.hal</code>, if present, does |
| not define an interface but instead defines data types accessible to every |
| interface in the package.</p> |
| |
| <h2 id=interface-def>Interface definition</h2> |
| <p>Aside from <code>types.hal</code>, every other <code>.hal</code> file defines |
| an interface. An interface is typically defined as follows:</p> |
| |
| <pre class="prettyprint"> |
| interface IBar extends IFoo { // IFoo is another interface |
| // embedded types |
| struct MyStruct {/*...*/}; |
| |
| // interface methods |
| create(int32_t id) generates (MyStruct s); |
| close(); |
| }; |
| </pre> |
| |
| <p>An interface without an explicit <code>extends</code> declaration implicitly |
| extends from <code>[email protected]::IBase</code> (similar to |
| <code>java.lang.Object</code> in Java.) The IBase interface, implicitly |
| imported, declares several reserved methods that should not and cannot be |
| redeclared in user-defined interfaces or used otherwise. These methods |
| include:</p> |
| |
| <ul> |
| <li><code>ping</code></li> |
| <li><code>interfaceChain</code></li> |
| <li><code>interfaceDescriptor</code></li> |
| <li><code>notifySyspropsChanged</code></li> |
| <li><code>linkToDeath</code></li> |
| <li><code>unlinkToDeath</code></li> |
| <li><code>setHALInstrumentation</code></li> |
| <li><code>getDebugInfo</code></li> |
| <li><code>debug</code></li> |
| <li><code>getHashChain</code></li> |
| </ul> |
| |
| <h2 id=import>Importing</h2> |
| <p>The <code>import</code> statement is HIDL mechanism to access package |
| interfaces and types in another package. An <code>import</code> statement |
| concerns itself with two entities:</p> |
| |
| <ul> |
| <li>The import<em>ing</em> entity, which can be either a package or an |
| interface; and</li> |
| <li>The import<em>ed</em> entity, which too can be either a package or an |
| interface.</li> |
| </ul> |
| |
| <p>The importing entity is determined by the location of the |
| <code>import</code> statement. When the statement is inside a package's |
| <code>types.hal</code>, what is being imported is visible by the entire package; |
| this is a <em>package-level</em> import. When the statement is inside an |
| interface file, the importing entity is the interface itself; this is an |
| <em>interface-level</em> import.</p> |
| |
| <p>The imported entity is determined by the value after the <code>import</code> |
| keyword. The value need not be a fully-qualified name; if a component is |
| omitted, it is automatically filled with information from the current package. |
| For fully-qualified values, the following import cases are supported:</p> |
| |
| <ul> |
| <li><strong>Whole-package imports</strong>. If the value is a package name and a |
| version (syntax described below), then the entire package is imported into the |
| importing entity.</li> |
| <li><strong>Partial imports</strong>. If the value is: |
| <ul> |
| <li>An interface, the package's <code>types.hal</code> and that interface are |
| imported into the importing entity.</li> |
| <li>A UDT defined in <code>types.hal</code>, then only that UDT is imported into |
| the importing entity (other types in <code>types.hal</code> are not imported). |
| </li> |
| </ul> |
| <li><strong>Types-only imports</strong>. If the value uses the syntax of a |
| partial import described above, but with the keyword <code>types</code> instead |
| of an Interface name, only the UDTs in <code>types.hal</code> of the designated |
| package are imported.</li> |
| </ul> |
| |
| <p>The importing entity gets access to a combination of:</p> |
| <ul> |
| <li>The imported package's common UDTs defined in <code>types.hal</code>;</li> |
| <li>The imported package's interfaces (for a whole-package import) or specified |
| interface (for a partial import) for the purposes of invoking them, passing |
| handles to them and/or inheriting from them.</li> |
| </ul> |
| |
| <p>The import statement uses the fully-qualified-type-name syntax to provide the |
| name and version of the package or interface being imported:</p> |
| |
| <pre class="prettyprint"> |
| import [email protected]; // import a whole package |
| import [email protected]::IQuux; // import an interface and types.hal |
| import [email protected]::types; // import just types.hal |
| </pre> |
| |
| <h2 id=inheritance>Interface inheritance</h2> |
| |
| <p>An interface can be an extension of a previously-defined interface. |
| Extensions can be one of the following three types:</p> |
| <ul> |
| <li>Interface can add functionality to another one, incorporating its API |
| unchanged.</li> |
| <li>Package can add functionality to another one, incorporating its API |
| unchanged.</li> |
| <li>Interface can import types from a package or from a specific interface.</li> |
| </ul> |
| |
| <p>An interface can extend only one other interface (no multiple inheritance). |
| Each interface in a package with a non-zero minor version number must extend an |
| interface in the previous version of the package. For example, if an interface |
| <code>IBar</code> in version 4.0 of package <code>derivative</code> is based on |
| (extends) an interface <code>IFoo</code> in version 1.2 of package |
| <code>original</code>, and a version 1.3 of package <code>original</code> is |
| created, <code>IBar</code> version 4.1 cannot extend version 1.3 of |
| <code>IFoo</code>. Instead, <code>IBar</code> version 4.1 must extend |
| <code>IBar</code> version 4.0, which is tied to <code>IFoo</code> version 1.2. |
| <code>IBar</code> version 5.0 could extend <code>IFoo</code> version 1.3, if |
| desired.</p> |
| |
| <p>Interface extensions do not imply library dependence or cross-HAL inclusion |
| in the generated code—they simply import the data structure and method |
| definitions at the HIDL level. Every method in a HAL must be implemented in that |
| HAL.</p> |
| |
| <h2 id=vendor-ext>Vendor extensions</h2> |
| <p>In some cases, vendor extensions will be implemented as a subclass of the |
| base object that represents the core interface they extend. The same object will |
| be registered under the base HAL name and version, and under the extension's |
| (vendor) HAL name and version.</p> |
| |
| |
| <h2 id=version>Versioning</h2> |
| <p>Packages are versioned, and interfaces have the version of their package. |
| Versions are expressed in two integers, <em>major</em>.<em>minor</em>.</p> |
| <ul> |
| <li><strong>Major</strong> versions are not backwards compatible. Incrementing |
| the major version number resets the minor version number to 0.</li> |
| <li><strong>Minor</strong> versions are backwards compatible. Incrementing the |
| minor number indicates the newer version is fully backward compatible with the |
| previous version. New data structures and methods can be added, but no existing |
| data structures or method signatures may be changed.</li> |
| </ul> |
| |
| <p>For broader compatibility with frameworks, multiple major versions of a HAL |
| can be present on a device simultaneously. While multiple minor versions can |
| also be present on a device, as minor versions are backwards compatible no |
| reason exists to support more than the latest minor version for each major |
| version. For more details on versioning and vendor extensions, see |
| <a href="/devices/architecture/hidl/versioning">HIDL Versioning</a>.</p> |
| |
| <h2 id="interface-layout-summary">Interface layout summary</h2> |
| <p>This section summarizes how to manage a HIDL interface package (such as |
| <code>hardware/interfaces</code>) and consolidates information presented |
| throughout the HIDL section. Before reading, ensure you are familiar with |
| <a href="/devices/architecture/hidl/versioning">HIDL Versioning</a>, the hashing |
| concepts in <a href="/devices/architecture/hidl/hashing#hidl-gen">Hashing with |
| hidl-gen</a>, the details of <a href="/devices/architecture/hidl/">working with |
| HIDL in general</a>, and the following definitions:</p> |
| |
| <table> |
| <thead> |
| <tr> |
| <th width="30%">Term</th> |
| <th>Definition</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>Application Binary Interface (ABI)</td> |
| <td>Application programming interface + any binary linkages required.</td> |
| </tr> |
| <tr> |
| <td>Fully-qualified name (fqName)</td> |
| <td>Name to distinguish a hidl type. Example: |
| <code>[email protected]::IFoo</code>.</td> |
| </tr> |
| <tr> |
| <td>Package</td> |
| <td>Package containing a HIDL interface and types. Example: |
| <code>[email protected]</code>.</td> |
| </tr> |
| <tr> |
| <td> Package root</td> |
| <td>Root package that contains the HIDL interfaces. Example: the HIDL interface |
| <code>android.hardware</code> is in the package root |
| <code>[email protected]</code>.</td> |
| </tr> |
| <tr> |
| <td>Package root path</td> |
| <td>Location in the Android source tree where a package root maps to.</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <p>For more definitions, see HIDL |
| <a href="/devices/architecture/hidl/#terms">Terminology</a>. |
| </p> |
| |
| <h3 id="file-found">Every file can be found from the package root mapping and |
| its fully-qualified name</h3> |
| <p>Package roots are specified to <code>hidl-gen</code> as the argument |
| <code>-r android.hardware:hardware/interfaces</code>. For example, if the |
| package is <code>[email protected]::IFoo</code> and <code>hidl-gen</code> |
| is sent <code>-r vendor.awesome:some/device/independent/path/interfaces</code>, |
| then the interface file should be located in |
| <code>$ANDROID_BUILD_TOP/some/device/independent/path/interfaces/foo/1.0/IFoo.hal</code>. |
| </p> |
| <p>In practice, it is recommended for a vendor or OEM named <code>awesome</code> |
| to put their standard interfaces in <code>vendor.awesome</code>. After a package |
| path has been selected, it must not be changed as this is baked into the ABI of |
| the interface.</p> |
| |
| <h3 id="package-path-mapping">Package path mapping should be unique</h3> |
| <p>For example, if you have <code>-rsome.package:$PATH_A</code> and |
| <code>-rsome.package:$PATH_B</code>, <code>$PATH_A</code> must be equal to |
| <code>$PATH_B</code> for a consistent interface directory (this also makes |
| <a href="/devices/architecture/hidl/versioning">versioning interfaces</a> much |
| easier).</p> |
| |
| <h3 id="package-root-version">Package root must have a versioning file</h3> |
| <p>If you create a package path such as |
| <code>-r vendor.awesome:vendor/awesome/interfaces</code>, you should also |
| create the file |
| <code>$ANDROID_BUILD_TOP/vendor/awesome/interfaces/current.txt</code>, which |
| should contain hashes of interfaces made using the <code>-Lhash</code> option in |
| <code>hidl-gen</code> (this is discussed extensively in |
| <a href="/devices/architecture/hidl/hashing#hidl-gen">Hashing with |
| hidl-gen</a>).</p> |
| |
| <aside class="caution"><strong>Caution:</strong> Manage all changes carefully! |
| The <a href="/devices/tech/vts/">Vendor Test Suite (VTS)</a> will fail if an |
| interface is not frozen, and ABI-incompatible changes to an interface will cause |
| framework-only OTAs to fail.</aside> |
| |
| <h3 id="interfaces-device-dependent">Interfaces go in device-independent |
| locations</h3> |
| <p>In practice, it is recommended to share interfaces between branches. This |
| allows for maximum code re-usage and maximum testing of code across different |
| devices and use cases.</p> |
| |
| </body> |
| </html> |