| <html devsite> |
| <head> |
| <title>Interface Hashing</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>This document describes HIDL interface hashing, a mechanism to prevent |
| accidental interface changes and ensure interface changes are thoroughly vetted. |
| This mechanism is required because HIDL interfaces are versioned, which means |
| that after an interface is released it must not be changed except in an |
| Application Binary Interface (ABI) preserving manner (such as a comment |
| correction).</p> |
| |
| <h2 id=layout>Layout</h2> |
| <p>Every package root directory (i.e. <code>android.hardware</code> mapping to |
| <code>hardware/interfaces</code> or <code>vendor.foo</code> mapping to |
| <code>vendor/foo/hardware/interfaces</code>) must contain a |
| <code>current.txt</code> file that lists all released HIDL interface files.</p> |
| |
| <pre class="prettyprint"> |
| # current.txt files support comments starting with a ‘#' character |
| # this file, for instance, would be vendor/foo/hardware/interfaces/current.txt |
| |
| # Each line has a SHA-256 hash followed by the name of an interface. |
| # They have been shortened in this doc for brevity but they are |
| # 64 characters in length in an actual current.txt file. |
| d4ed2f0e...995f9ec4 vendor.awesome.foo@1.0::IFoo # comments can also go here |
| |
| # types.hal files are also noted in types.hal files |
| c84da9f5...f8ea2648 vendor.awesome.foo@1.0::types |
| |
| # Multiple hashes can be in the file for the same interface. This can be used |
| # to note how ABI sustaining changes were made to the interface. |
| # For instance, here is another hash for IFoo: |
| |
| # Fixes type where "FooCallback" was misspelled in comment on "FooStruct" |
| 822998d7...74d63b8c vendor.awesome.foo@1.0::IFoo |
| </pre> |
| |
| <p class=note><strong>Note:</strong> To help keep track of which hashes come |
| from where, Google separates HIDL <code>current.txt</code> files into different |
| sections: The first section is <em>Released in Android O</em>; the next section |
| will be <em>Released in Android O MR1</em>. We strongly recommend using a |
| similar layout in your <code>current.txt</code> file.</p> |
| |
| <h2 id=hidl-gen>Hashing with hidl-gen</h2> |
| <p>You can add a hash to a <code>current.txt</code> file manually or by |
| using <code>hidl-gen</code>. The following code snippet provides examples of |
| commands you can use with <code>hidl-gen</code> to manage a |
| <code>current.txt</code> file (hashes have been shortened):</p> |
| |
| <pre class="devsite-click-to-copy"> |
| <code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0::types</code> |
| 9626fd18...f9d298a6 vendor.awesome.nfc@1.0::types |
| <code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0::INfc</code> |
| 07ac2dc9...11e3cf57 vendor.awesome.nfc@1.0::INfc |
| <code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0</code> |
| 9626fd18...f9d298a6 vendor.awesome.nfc@1.0::types |
| 07ac2dc9...11e3cf57 vendor.awesome.nfc@1.0::INfc |
| f2fe5442...72655de6 vendor.awesome.nfc@1.0::INfcClientCallback |
| <code class="devsite-terminal">hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0 >> vendor/awesome/hardware/interfaces/current.txt</code> |
| </pre> |
| |
| <p class="warning"><strong>Warning:</strong> Do not replace a hash for a |
| previously-released interface. When changing such an interface, add a new hash |
| to the end of the <code>current.txt</code> file. For details, refer to |
| <a href="#abi-stability">ABI stability</a>.</p> |
| |
| <p>Every interface definition library generated by <code>hidl-gen</code> |
| includes hashes, which can be retrieved by calling |
| <code>IBase::getHashChain</code>. When <code>hidl-gen</code> is compiling an |
| interface, it checks the <code>current.txt</code> file in the root directory of |
| the HAL package to see if the HAL has been changed:</p> |
| |
| <ul> |
| <li>If no hash for the HAL is found, the interface is considered unreleased (in |
| development) and compilation proceeds.</li> |
| <li>If hashes are found, they are checked against the current interface: |
| <ul> |
| <li>If the interface does match the hash, compilation proceeds.</li> |
| <li>If the interface does not match a hash, compilation is halted as this means a previously-released interface is being changed. |
| <ul> |
| <li>For an ABI-preserving change (see |
| <a href="#abi-stability">ABI stability</a>), the <code>current.txt</code> file |
| must be modified before compilation can proceed.</li> |
| <li>All other changes should be made in a minor or major version upgrade of the |
| interface.</li> |
| </ul></li></ul></li></ul> |
| |
| <h2 id=abi-stability>ABI stability</h2> |
| <aside class="key-point"><strong>Key Point:</strong> Please read and understand |
| this section carefully.</aside> |
| |
| <p>An Application Binary Interface (ABI) includes the binary |
| linkages/calling conventions/etc. If the ABI/API changes, the interface no |
| longer works with a generic <code>system.img</code> that was compiled with |
| official interfaces.</p> |
| |
| <p>Making sure that interfaces are versioned and ABI stable is |
| <strong>crucial</strong> for several reasons:</p> |
| |
| <ul> |
| <li>It ensures your implementation can pass the Vendor Test Suite (VTS), which |
| puts you on track to being able to do framework-only OTAs.</li> |
| <li>As an OEM, it enables you to provide a Board Support Package (BSP) that is |
| straightforward to use and compliant.</li> |
| <li>It helps you keep track of what interfaces can be released. Consider |
| <code>current.txt</code> a map of an interfaces directory that allows you to see |
| the history and state of all interfaces being provided in a package root.</li> |
| </ul> |
| |
| <p>When adding a new hash for an interface that already has an entry in |
| <code>current.txt</code>, make sure to add only the hashes that represent |
| interfaces which maintain ABI stability. Review the following types of changes: |
| </p> |
| |
| <table> |
| <tbody> |
| |
| <tr> |
| <th>Changes allowed</th> |
| <td> |
| <ul> |
| <li>Changing a comment (unless this changes the meaning of a method).</li> |
| <li>Changing the name of a parameter.</li> |
| <li>Changing the name of a return parameter.</li> |
| <li>Changing annotations.</li> |
| </ul> |
| </td> |
| </tr> |
| |
| <tr> |
| <th>Changes not allowed</th> |
| <td> |
| <ul> |
| <li>Reordering arguments, methods, etc…</li> |
| <li>Renaming an interface or moving it to a new package.</li> |
| <li>Renaming a package.</li> |
| <li>Adding a method/struct field/etc… anywhere in the interface.</li> |
| <li>Anything that would break a C++ vtable.</li> |
| <li>etc..</li> |
| </ul> |
| </td> |
| </tr> |
| |
| </tbody> |
| </table> |
| |
| </body> |
| </html> |