diff options
author | Gina Dimino <gdimino@google.com> | 2021-07-12 16:35:38 -0700 |
---|---|---|
committer | Gina Dimino <gdimino@google.com> | 2021-07-15 15:35:51 -0700 |
commit | fc5fc0e74df003b0ee454d3418b88cd722282c49 (patch) | |
tree | 7fa97b880b85be7de5b713d233cdc407c20b88cd /en/devices/architecture/hidl | |
parent | e55b3193405187e091a4ac7730ef04360ec04504 (diff) | |
download | source.android.com-fc5fc0e74df003b0ee454d3418b88cd722282c49.tar.gz |
Remove obsolete sync directories for SAC
Test: N/A
Change-Id: I5245330990d722ad4d15a0600532943840f30830
Diffstat (limited to 'en/devices/architecture/hidl')
-rw-r--r-- | en/devices/architecture/hidl/binder-ipc.html | 314 | ||||
-rw-r--r-- | en/devices/architecture/hidl/code-style.html | 730 | ||||
-rw-r--r-- | en/devices/architecture/hidl/converting.html | 87 | ||||
-rw-r--r-- | en/devices/architecture/hidl/fmq.html | 433 | ||||
-rw-r--r-- | en/devices/architecture/hidl/hashing.html | 167 | ||||
-rw-r--r-- | en/devices/architecture/hidl/index.html | 338 | ||||
-rw-r--r-- | en/devices/architecture/hidl/interfaces.html | 316 | ||||
-rw-r--r-- | en/devices/architecture/hidl/memoryblock.md | 302 | ||||
-rw-r--r-- | en/devices/architecture/hidl/network-stack.html | 176 | ||||
-rw-r--r-- | en/devices/architecture/hidl/services.html | 236 | ||||
-rw-r--r-- | en/devices/architecture/hidl/threading.html | 178 | ||||
-rw-r--r-- | en/devices/architecture/hidl/types.html | 410 | ||||
-rw-r--r-- | en/devices/architecture/hidl/versioning.html | 703 |
13 files changed, 0 insertions, 4390 deletions
diff --git a/en/devices/architecture/hidl/binder-ipc.html b/en/devices/architecture/hidl/binder-ipc.html deleted file mode 100644 index 22c38a11..00000000 --- a/en/devices/architecture/hidl/binder-ipc.html +++ /dev/null @@ -1,314 +0,0 @@ -<html devsite> - <head> - <title>Using Binder IPC</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 page describes changes to the binder driver in Android O, provides -details on using binder IPC, and lists required SELinux policy.</p> - -<h2 id=binder-changes>Changes to binder driver</h2> - -<p>Starting in Android O, the Android framework and HALs now communicate with -each other using binder. As this communication dramatically increases binder -traffic, Android O includes several improvements designed to keep binder IPC -fast. SoC vendors and OEMs integrating the latest version of the driver should -review the list of these improvements, relevant SHAs for the 3.18, 4.4, and 4.9 -kernels, and required userspace changes.</p> - -<h3 id=contexts>Multiple binder domains (contexts)</h3> -<em>In common-3.10, common-3.18, common-4.4, common-4.9, and upstream</em> -<p> -To cleanly split the binder traffic between framework (device-independent) and -vendor (device-specific) code, Android O introduces the concept of a <em>binder -context</em>. Each binder context has its own device node and its own context -(service) manager. You can access the context manager only through the device -node to which it belongs and, when passing a binder node through a certain -context, it is accessible from that same context only by another process, thus -completely isolating the domains from each other. For details on using, see -<a href="#vndbinder">vndbinder</a> and -<a href="#vndservicemanager">vndservicemanager</a>. -</p> - - -<h3 id=scatter>Scatter-gather</h3> -<em>In common-3.10, common-3.18, common-4.4, common-4.9, and upstream</em> -<p> -In previous releases of Android, every piece of data in a binder call was copied -three times: -</p> -<ul> -<li>Once to serialize it into a -<code><a href="https://developer.android.com/reference/android/os/Parcel.html">Parcel</a></code> -in the calling process</li> -<li>Once in the kernel driver to copy the <code>Parcel</code> to the target -process</li> -<li>Once to unserialize the <code>Parcel</code> in the target process</li> -</ul> - -<p> -Android O uses -<a href="https://en.wikipedia.org/wiki/Vectored_I/O">scatter-gather -optimization</a> to reduce the number of copies from 3 to 1. Instead of -serializing data in a <code>Parcel</code> first, data remains in its original -structure and memory layout and the driver immediately copies it to the target -process. After the data is in the target process, the structure and memory -layout is the same and the data can be read without requiring another copy. -</p> - -<h3 id=locking>Fine-grained locking</h3> -<em>In common-3.18, common-4.4, common-4.9, and upstream</em> - -<p> -In previous Android releases, the binder driver used a global lock to protect -against concurrent access to critical data structures. While there was minimal -contention for the lock, the main problem was that if a low-priority thread -obtained the lock and then got preempted, it could seriously delay -higher-priority threads needing to obtain the same lock. This caused jank in the -platform. -</p> -<p> -Initial attempts to resolve this problem involved disabling preemption while -holding the global lock. However, this was more of a hack than a true solution, -and was eventually rejected by upstream and discarded. Subsequent attempts -focused on making locking more fine-grained, a version of which has been running -on Pixel devices since January 2017. While the majority of those changes were -made public, substantial improvements were made in future versions. -</p> -<p> -After identifying small issues in the fine-grained locking implementation, we -devised an improved solution with a different locking architecture and submitted -the changes in the 3.18, 4.4, and 4.9 common branches. We continue to test this -implementation on a large number of different devices; as we are unaware of any -outstanding issues, this is the recommended implementation for devices shipping -with Android O. -</p> -<p class="note"><strong>Note:</strong> We strongly encourage budgeting -sufficient testing hours for fine-grained locking. -</p> -<h3 id=rt-priority>Real-time priority inheritance</h3> -<em>In common-3.18, common-4.4, common-4.9 (upstream coming soon)</em> - -<p> -The binder driver has always supported nice priority inheritance. As an -increasing number of processes in Android run at real-time priority, in some -cases it now makes sense that if a real-time thread makes a binder call, the -thread in the process that handles that call also runs at real-time priority. To -support these use cases, Android O now implements real-time priority inheritance -in the binder driver. -</p> -<p> -In addition to transaction-level priority inheritance, <em>node priority -inheritance</em> allows a node (binder service object) to specify a minimum -priority at which calls into this node should be executed. Previous versions of -Android already supported node priority inheritance with nice values, but -Android O adds support for real-time scheduling policies node inheritance. -</p> -<p class="note"><strong>Note:</strong> The Android performance team found that -real-time priority inheritance caused unwanted side-effects in the framework -binder domain (<code>/dev/binder</code>), so real-time priority inheritance is -<strong>disabled</strong> for that domain. -</p> - -<h3 id=userspace>Userspace changes</h3> -<p> -Android O includes all userspace changes required to work with the current -binder driver in the common kernel with one exception: The original -implementation to disable real-time priority inheritance for -<code>/dev/binder</code> used an -<a href="https://android.googlesource.com/kernel/msm/+/868f6ee048c6ff51dbd92353dd5c68bea4419c78" class="external">ioctl</a>. Subsequent development switched control of priority -inheritance to a more fine-grained method that is per binder mode (and not per -context). Thus, the ioctl is not in the Android common branch and is instead -<a href="https://android-review.googlesource.com/#/c/421861/" class="external">submitted -in our common kernels</a>. -</p> -<p> -The effect of this change is that real-time priority inheritance is disabled by -default for <em>every</em> node. The Android performance team has found it -beneficial to enable real-time priority inheritance for all nodes in the -<code>hwbinder</code> domain. To achieve that same effect, cherry-pick -<a href="https://android-review.googlesource.com/#/c/440359/" class="external">this -change</a> in userspace. -</p> -<h3 id=shas>SHAs for common kernels</h3> -<p> -To obtain necessary changes to the binder driver, sync to the SHAs below (or -later): -</p> -<ul> -<li>Common-3.18<br> -cc8b90c121de ANDROID: binder: don't check prio permissions on restore.</li> -<li>Common-4.4<br> -76b376eac7a2 ANDROID: binder: don't check prio permissions on restore.</li> -<li>Common-4.9<br> -ecd972d4f9b5 ANDROID: binder: don't check prio permissions on restore.</li> -</ul> - -<h2 id=ipc>Using binder IPC</h2> -<p>Historically, vendor processes have used binder interprocess communication -(IPC) to communicate. In Android O, the <code>/dev/binder</code> device node -becomes exclusive to framework processes, meaning vendor processes no longer -have access to it. Vendor processes can access <code>/dev/hwbinder</code>, but -must convert their AIDL interfaces to use HIDL. For vendors who want to continue -using AIDL interfaces between vendor processes, Android supports binder IPC as -described below.</p> - -<h3 id=vndbinder>vndbinder</h3> -<p>Android O supports a new binder domain for use by vendor services, accessed -using <code>/dev/vndbinder</code> instead of <code>/dev/binder</code>. With the -addition of <code>/dev/vndbinder</code>, Android now has the following three -IPC domains:</p> - -<table> - <tr> - <th>IPC Domain</th> - <th>Description</th> - </tr> - <tr> - <td><code>/dev/binder</code></td> - <td>IPC between framework/app processes with AIDL interfaces</td> - </tr> - <tr> - <td><code>/dev/hwbinder</code></td> - <td>IPC between framework/vendor processes with HIDL interfaces - <br>IPC between vendor processes with HIDL interfaces</td> - </tr> - <tr> - <td><code>/dev/vndbinder</code></td> - <td>IPC between vendor/vendor processes with AIDL Interfaces</td> - </tr> -</table> - -<p>For <code>/dev/vndbinder</code> to appear, ensure the kernel configuration -item <code>CONFIG_ANDROID_BINDER_DEVICES</code> is set to -<code>"binder,hwbinder,vndbinder"</code> (this is the default in Android's -common kernel trees).</p> - -<p>Normally, vendor processes don't open the binder driver directly and instead -link against the <code>libbinder</code> userspace library, which opens the -binder driver. Adding a method for <code>::android::ProcessState()</code> -selects the binder driver for <code>libbinder</code>. Vendor processes should -call this method <strong>before</strong> calling into <code>ProcessState,</code> -<code>IPCThreadState</code>, or before making any binder calls in general. To -use, place the following call after the <code>main()</code> of a vendor process -(client and server):</p> - -<pre class="prettyprint">ProcessState::initWithDriver("/dev/vndbinder");</pre> - -<h3 id=vndservicemanager>vndservicemanager</h3> -<p>Previously, binder services were registered with <code>servicemanager</code>, -where they could be retrieved by other processes. In Android O, -<code>servicemanager</code> is now used exclusively by framework and app -processes and vendor processes can no longer access it.</p> - -<p>However, vendor services can now use <code>vndservicemanager</code>, a new -instance of <code>servicemanager</code> that uses <code>/dev/vndbinder</code> -instead of <code>/dev/binder</code> and which is built from the same sources as -framework <code>servicemanager</code>. Vendor processes do not need to make -changes to talk to <code>vndservicemanager</code>; when a vendor process opens -/<code>dev/vndbinder</code>, service lookups automatically go to -<code>vndservicemanager</code>.</p> - -<p>The <code>vndservicemanager</code> binary is included in Android's default -device makefiles.</p> - -<h2 id=selinux>SELinux policy</h2> -<p>Vendor processes that want to use binder functionality to communicate with -each other need the following:</p> -<ol> -<li>Access to <code>/dev/vndbinder</code>.</li> -<li>Binder <code>{transfer, call}</code> hooks into -<code>vndservicemanager</code>.</li> -<li><code>binder_call(A, B)</code> for any vendor domain A that wants to call -into vendor domain B over the vendor binder interface.</li> -<li>Permission to <code>{add, find}</code> services in -<code>vndservicemanager</code>.</li> -</ol> - -<p>To fulfill requirements 1 and 2, use the <code>vndbinder_use()</code> -macro:</p> - -<pre class="prettyprint">vndbinder_use(some_vendor_process_domain);</pre> - -<p>To fulfill requirement 3, the <code>binder_call(A, B)</code> for vendor -processes A and B that need to talk over binder can stay in place, and doesn't -need renaming.</p> - -<p>To fulfill requirement 4, you must make changes in the way service names, -service labels, and rules are handled.</p> - -<p>For details on SELinux, see <a href="/security/selinux/">Security-Enhanced -Linux in Android</a>. For details on SELinux in Android 8.0, see -<a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android -8.0</a>.</p> - -<h3 id=names>Service names</h3> -<p>Previously, vendor processes registered service names in a -<code>service_contexts</code> file and added corresponding rules for accessing -that file. Example <code>service_contexts</code> file from -<code>device/google/marlin/sepolicy</code>:</p> - -<pre class="devsite-click-to-copy"> -AtCmdFwd u:object_r:atfwd_service:s0 -cneservice u:object_r:cne_service:s0 -qti.ims.connectionmanagerservice u:object_r:imscm_service:s0 -rcs u:object_r:radio_service:s0 -uce u:object_r:uce_service:s0 -vendor.qcom.PeripheralManager u:object_r:per_mgr_service:s0 -</pre> - -<p>In Android O, <code>vndservicemanager</code> loads the -<code>vndservice_contexts</code> file instead. Vendor services migrating to -<code>vndservicemanager</code> (and which are already in the old -<code>service_contexts</code> file) should be added to the new -<code>vndservice_contexts</code> file.</p> - -<h3 id=labels>Service labels</h3> -<p>Previously, service labels such as <code>u:object_r:atfwd_service:s0</code> -were defined in a <code>service.te</code> file. Example:</p> - -<pre class="prettyprint">type atfwd_service, service_manager_type;</pre> - -<p>In Android O, you must change the type to -<code>vndservice_manager_type</code> and move the rule to the -<code>vndservice.te</code> file. Example:</p> - -<pre class="prettyprint">type atfwd_service, vndservice_manager_type;</pre> - -<h3 id=rules>Servicemanager rules</h3> -<p>Previously, rules granted domains access to add or find services from -<code>servicemanager</code>. Example:</p> - -<pre class="prettyprint"> -allow atfwd atfwd_service:service_manager find; -allow some_vendor_app atfwd_service:service_manager add; -</pre> - -<p>In Android O, such rules can stay in place and use the same class. Example: -</p> - -<pre class="prettyprint"> -allow atfwd atfwd_service:service_manager find; -allow some_vendor_app atfwd_service:service_manager add; -</pre> - - </body> -</html> diff --git a/en/devices/architecture/hidl/code-style.html b/en/devices/architecture/hidl/code-style.html deleted file mode 100644 index 5f451851..00000000 --- a/en/devices/architecture/hidl/code-style.html +++ /dev/null @@ -1,730 +0,0 @@ -<html devsite> - <head> - <title>Code Style Guide</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>The HIDL code style resembles C++ code in the Android framework, with 4-space -indents and mixed-case filenames. Package declarations, imports, and docstrings -are similar to those in Java, with slight modifications.</p> - -<p>The following examples for <code>IFoo.hal</code> and <code>types.hal</code> -illustrate HIDL code styles and provide quick links to details on each style -(<code>IFooClientCallback.hal</code>, <code>IBar.hal</code>, and -<code>IBaz.hal</code> have been omitted).</p> - -<table> -<tr><th><code>hardware/interfaces/foo/1.0/IFoo.hal</code></th></tr> -<tr><td><pre class="prettyprint"> -/* - * (License Notice) - */ - -<a href="#package-names">package</a> android.hardware.foo@<a href="#versions">1.0</a>; - -<a href="#imports">import</a> android.hardware.bar@1.0::IBar; - -import IBaz; -import IFooClientCallback; - -/** - * IFoo is an interface that… - */ -interface <a href="#interface-names">IFoo</a> { - - /** - * This is a <a href="#comments">multiline docstring</a>. - * - * <a href="#return">@return</a> result 0 if successful, nonzero otherwise. - */ - <a href="#function-declarations">foo() generates (FooStatus result);</a> - - /** - * Restart controller by power cycle. - * - * <a href="#param">@param</a> bar callback interface that… - * @return result 0 if successful, nonzero otherwise. - */ - <a href="#functions">powerCycle</a>(IBar bar) generates (FooStatus <a href="#functions">result</a>); - - /** <a href="#comments">Single line docstring</a>. */ - baz(); - - - /** - * The bar function. - * - * <a href="#param">@param</a> <a href="#functions">clientCallback</a> callback after function is called - * @param baz related baz object - * @param data input data blob - */ - bar(IFooClientCallback clientCallback, - IBaz baz, - FooData data); - -}; -</pre> -</td></tr></table> - -<table> -<tr><th><code>hardware/interfaces/foo/1.0/types.hal</code></th></tr> -<tr><td><pre class="prettyprint"> -/* - * (License Notice) - */ - -package android.hardware.foo@1.0; - -<a href="#comments">/** Replied status. */</a> -<a href="#enum-declarations">enum Status : int32_t</a> { - <a href="#enum-values">OK</a>, - ERR_ARG, <a href="#comments">// invalid arguments</a> - ERR_UNKNOWN = -1, // note, no transport related errors -}; - -<a href="#struct-declarations">struct ArgData</a> { - <a href="#array-declarations">int32_t[20] someArray;</a> - <a href="#vectors">vec<uint8_t> data;</a> -}; -</pre> -</td></tr></table> - -<h2 id=naming>Naming conventions</h2> -<p>Function names, variable names, and filenames should be descriptive; avoid -over-abbreviation. Treat acronyms as words (e.g., use <code>INfc</code> instead -of <code>INFC</code>).</p> - -<h3 id=dir-structure>Directory structure and file naming</h3> -<p>The directory structure should appear as follows:</p> -<ul> -<li><code><var>ROOT-DIRECTORY</var></code> - <ul> - <li><code><var>MODULE</var></code> - <ul> - <li><code><var>SUBMODULE</var></code> (optional, could be more than one - level) - <ul> - <li><code><var>VERSION</var></code> - <ul> - <li><code>Android.mk</code></li> - <li><code>I<var>INTERFACE_1</var>.hal</code></li> - <li><code>I<var>INTERFACE_2</var>.hal</code></li> - <li><code>…</code></li> - <li><code>I<var>INTERFACE_N</var>.hal</code></li> - <li><code>types.hal</code> (optional)</li> - </ul> - </li> - </ul> - </li> - </ul> - </li> - </ul> -</li> -</ul> - -<p>Where:</p> -<ul> -<li><code><var>ROOT-DIRECTORY</var></code> is: - <ul> - <li><code>hardware/interfaces</code> for core HIDL packages.</li> - <li><code>vendor/<var>VENDOR</var>/interfaces</code> for vendor packages, - where <code><var>VENDOR</var></code> refers to an SoC vendor or an - OEM/ODM.</li> - </ul> - </li> -<li><code><var>MODULE</var></code> should be one lowercase word that describes -the subsystem (e.g. <code>nfc</code>). If more than one word is needed, use -nested <code><var>SUBMODULE</var></code>. There can be more than one level of -nesting.</li> -<li><code><var>VERSION</var></code> should be the exact same version -(major.minor) as described in <a href="#versions">Versions</a>.</li> -<li><code>I<var>INTERFACE_X</var></code> should be the interface name with -<code>UpperCamelCase</code>/<code>PascalCase</code> (e.g. <code>INfc</code>) -as described in <a href="#interface-names">Interface names</a>.</li> -</ul> - -<p>Example:</p> -<ul> -<li><code>hardware/interfaces</code> - <ul> - <li><code>nfc</code> - <ul> - <li><code>1.0</code> - <ul> - <li><code>Android.mk</code></li> - <li><code>INfc.hal</code></li> - <li><code>INfcClientCallback.hal</code></li> - <li><code>types.hal</code></li> - </ul> - </li> - </ul> - </li> - </ul> -</li> -</ul> - -<p class="note"><strong>Note:</strong> All files must have non-executable -permissions (in Git). - -<h3 id=package-names>Package names</h3> -<p>Package names must use the following <a href="#fqn">fully-qualified name -(FQN)</a> format (referred to as <code><var>PACKAGE-NAME</var></code>):</p> - -<pre class="prettyprint"> -<var>PACKAGE</var>.<var>MODULE</var>[.<var>SUBMODULE</var>[.<var>SUBMODULE</var>[…]]]@<var>VERSION</var> -</pre> - -<p>Where:</p> -<ul> -<li><code><var>PACKAGE</var></code> is the package that maps to the -<code><var>ROOT-DIRECTORY</var></code>. In particular, -<code><var>PACKAGE</var></code> is: - <ul> - <li><code>android.hardware</code> for core HIDL packages (mapping to - <code>hardware/interfaces</code>).</li> - <li><code>vendor.<var>VENDOR</var>.hardware</code> for vendor packages, where - <code><var>VENDOR</var></code> refers to an SoC vendor or an OEM/ODM (mapping - to <code>vendor/<var>VENDOR</var>/interfaces</code>).</li> - </ul> -<li><code><var>MODULE</var>[.<var>SUBMODULE</var>[.<var>SUBMODULE</var>[…]]]@<var>VERSION</var></code> -are the exact same folder names in the structure described in -<a href="#dir-structure">Directory structure</a>.</li> -<li>Package names should be lowercase. If they are more than one word long, the -words should either be used as submodules or written in <code>snake_case</code>. -</li> -<li>No spaces are allowed.</li> -</ul> - -<p>The FQN is always used in package declarations.</p> - -<h3 id=versions>Versions</h3> -<p> -Versions should have the following format: -</p> - -<pre class="prettyprint"><var>MAJOR</var>.<var>MINOR</var></pre> - -<p>Both the <var>MAJOR</var> and the <var>MINOR</var> version should be a single -integer. HIDL uses <a href="http://semver.org/" class="external">semantic -versioning</a> rules.</p> - -<h3 id=imports>Imports</h3> -<p>An import has one of the following three formats:</p> -<ul> -<li>Whole-package imports: <code>import <var>PACKAGE-NAME</var>;</code></li> -<li>Partial imports: <code>import -<var>PACKAGE-NAME</var>::<var>UDT</var>;</code> (or, if the imported -type is in the same package,<code>import <var>UDT</var>;</code></li> -<li>Types-only imports: <code>import <var>PACKAGE-NAME</var>::types;</code></li> -</ul> - -<p>The <code><var>PACKAGE-NAME</var></code> follows the format in -<a href="#package-names">Package names</a>. The current package's -<code>types.hal</code> (if it exists) is automatically imported (do not import -it explicitly).</p> - -<h4 id=fqn>Fully qualified names (FQNs)</h4> -<p>Use fully qualified names for a user-defined type import only when necessary. -Omit <code><var>PACKAGE-NAME</var></code> if the import type is in the same -package. An FQN must not contain spaces. Example of a fully qualified name:</p> - -<pre class="prettyprint">android.hardware.nfc@1.0::INfcClientCallback</pre> - -<p>In another file under <code>android.hardware.nfc@1.0</code>, refer to the -above interface as <code>INfcClientCallback</code>. Otherwise, use only the -fully qualified name.</p> - -<h4 id=grouping>Grouping and ordering imports</h4> -<p>Use an empty line after package declaration (before the imports). Each import -should occupy a single line and should not be indented. Group imports in the -following order:</p> - -<ol> -<li>Other <code>android.hardware</code> packages (use fully qualified names). -</li> -<li>Other <code>vendor.<var>VENDOR</var></code> packages (use fully qualified -names). - <ul> - <li>Each vendor should be a group.</li> - <li>Order vendors alphabetically.</li> - </ul> - </li> -<li>Imports from other interfaces in the same package (use simple names).</li> -</ol> - -<p>Use an empty line between groups. Inside each group, sort imports -alphabetically. Example:</p> - -<pre class="prettyprint"> -import android.hardware.nfc@1.0::INfc; -import android.hardware.nfc@1.0::INfcClientCallback; - -// Importing the whole module. -import vendor.barvendor.bar@3.1; - -import vendor.foovendor.foo@2.2::IFooBar; -import vendor.foovendor.foo@2.2::IFooFoo; - -import IBar; -import IFoo; -</pre> - -<h3 id=interface-names>Interface names</h3> -<p>Interface names must start with an <code>I</code>, followed by an -<code>UpperCamelCase</code>/<code>PascalCase</code> name. An interface with name -<code>IFoo</code> must be defined in the file <code>IFoo.hal</code>. This file -can contain definitions only for the <code>IFoo</code> interface (the interface -<code>I<var>NAME</var></code> should be in <code>I<var>NAME</var>.hal</code> ). -</p> - -<h3 id=functions>Functions</h3> -<p>For function names, arguments, and return variable names, use -<code>lowerCamelCase</code>. Example:</p> - -<pre class="prettyprint"> -open(INfcClientCallback clientCallback) generates (int32_t retVal); -oneway pingAlive(IFooCallback cb); -</pre> - -<h3 id=struct-union>Struct/union field names</h3> -<p>For struct/union field names, use <code>lowerCamelCase</code>. Example:</p> - -<pre class="prettyprint"> -struct FooReply { - vec<uint8_t> replyData; -} -</pre> - -<h3 id=type-names>Type names</h3> -<p>Type names refer to struct/union definitions, enum type definitions, and -<code>typedef</code>s. For these name, use -<code>UpperCamelCase</code>/<code>PascalCase</code>. Examples:</p> - -<pre class="prettyprint"> -enum NfcStatus : int32_t { - /*...*/ -}; -struct NfcData { - /*...*/ -}; -</pre> - -<h3 id=enum-values>Enum values</h3> -<p>Enum values should be <code>UPPER_CASE_WITH_UNDERSCORES</code>. When passing -enum values as function arguments and returning them as function returns, use -the actual enum type (not the underlying integer type). Example:</p> - -<pre class="prettyprint"> -enum NfcStatus : int32_t { - HAL_NFC_STATUS_OK = 0, - HAL_NFC_STATUS_FAILED = 1, - HAL_NFC_STATUS_ERR_TRANSPORT = 2, - HAL_NFC_STATUS_ERR_CMD_TIMEOUT = 3, - HAL_NFC_STATUS_REFUSED = 4 -}; -</pre> - -<p class="note"><strong>Note:</strong> The underlying type of an enum type is -explicitly declared after the colon. As it is not compiler dependent, using the -actual enum type is clearer.</p> - -<p>For fully qualified names for enum values, a <strong>colon</strong> is used -between the enum type name and the enum value name:</p> - -<pre class="prettyprint"> -<var>PACKAGE-NAME</var>::<var>UDT</var>[.<var>UDT</var>[.<var>UDT</var>[…]]:<var>ENUM_VALUE_NAME</var> -</pre> - -<p>There must not be spaces inside a fully qualified name. Use a fully qualified -name only when necessary and omit unnecessary parts. Example:</p> - -<pre class="prettyprint"> -android.hardware.foo@1.0::IFoo.IFooInternal.FooEnum:ENUM_OK -</pre> - -<h2 id=comments>Comments</h2> -<p>For a single line comment, both <code>// </code>and <code>/** */</code> are -fine.</p> -<pre class="prettyprint"> -// This is a single line comment -/* This is also single line comment */ -/** This is documentation comment */ -</pre> - -<ul> -<li>Use <code>//</code> mainly for: - <ul> - <li>trailing comments</li> - <li>Comments that will not be used for generated documentation</li> - <li>TODOs</li> - </ul> -</li> -<li>Use <code>/** */</code> for generated documentation. These can be applied -only to type, method, field, and enum value declarations. Example: -<pre class="prettyprint"> -/** Replied status */ -enum TeleportStatus { - /** Object entirely teleported. */ - OK = 0, - /** Methods return this if teleportation is not completed. */ - ERROR_TELEPORT = 1, - /** - * Teleportation could not be completed due to an object - * obstructing the path. - */ - ERROR_OBJECT = 2, - ... -} -</pre> -<li>Multi-line comments should start a new line with <code>/**</code>, use -<code>*</code> at the beginning of each line, and place <code>*/</code> on the -last line all on its own (asterisks should align). Example: -<pre class="prettyprint"> -/** - * My multi-line - * comment - */ -</pre> -</li> -<li>Licensing notice and changelogs should start a new line with <code>/*</code> -(a single asterisk), use <code>*</code> at the beginning of each line, and place -<code>*/</code> on the last line all on its own (asterisks should align). -Example: -<pre class="prettyprint"> -/* - * Copyright (C) 2017 The Android Open Source Project - * ... - */ - -/* - * Changelog: - * ... - */ -</pre> -</li> -</ul> - -<h3 id=file-comments>File comments</h3> -<p>Start each file with the appropriate licensing notice. For core HALs, this -should be the AOSP Apache license in -<a href="https://android.googlesource.com/platform/development/+/master/docs/copyright-templates/c.txt" class="external"><code>development/docs/copyright-templates/c.txt</code></a>. -Remember to update the year and use <code>/* */</code> style multi-line comments -as explained above.</p> - -<p>You can optionally place an empty line after the license notice, followed -by a changelog/versioning information. Use <code>/* */</code> style -multi-line comments as explained above, place the empty line after the -changelog, then follow with the package declaration.</p> - -<h3 id=todo-comments>TODO comments</h3> -<p>TODOs should include the string <code>TODO</code> in all caps followed by a -colon. Example:</p> -<pre>// TODO: remove this code before foo is checked in.</pre> - -<p class="alert">TODO comments are allowed only during development; they must -not exist in published interfaces.</p> - -<h3 id=docstrings>Interface/Function comments (docstrings)</h3> -<p>Use <code>/** */</code> for multi-line and single line docstrings. Do not use -<code>//</code> for docstrings.</p> - -<p>Docstrings for interfaces should describe general mechanisms of the -interface, design rationale, purpose, etc. Docstrings for functions should be -specific to the function (package-level documentation goes in a README file in -the package directory).</p> - -<pre class="prettyprint"> -/** - * IFooController is the controller for foos. - */ -interface IFooController { - /** - * Opens the controller. - * - * @return status HAL_FOO_OK if successful. - */ - open() generates (FooStatus status); - - /** Close the controller. */ - close(); -}; -</pre> - -<p>You must add <code>@param</code>s and <code>@return</code>s for each -parameter/return value:</p> - -<ul> -<li id=param><code>@param</code> must be added for each parameter. It should be -followed by the name of the parameter then the docstring.</li> -<li id=return><code>@return</code> must be added for each return value. It -should be followed by the name of the return value then the docstring.</li> -</ul> -<p>Example:</p> - -<pre class="prettyprint"> -/** - * Explain what foo does. - * - * @param arg1 explain what arg1 is - * @param arg2 explain what arg2 is - * @return ret1 explain what ret1 is - * @return ret2 explain what ret2 is - */ -foo(T arg1, T arg2) generates (S ret1, S ret2); -</pre> - -<h2>Formatting</h2> -<p>General formatting rules include:</p> -<ul> -<li><strong>Line length</strong>. Each line of text should be at most -<strong>80</strong> columns long.</li> -<li><strong>Whitespaces</strong>. No trailing whitespace on lines; empty lines -must not contain whitespaces.</li> -<li><strong>Spaces vs. tabs</strong>. Use only spaces.</li> -<li><strong>Indent size</strong>. Use <strong>4</strong> spaces for blocks and -<strong>8</strong> spaces for line wraps</li> -<li><strong>Bracing</strong>. Except for <a href="#annotations">annotation -values</a>, an <strong>open</strong> brace goes on the same line as preceding -code but a <strong>close</strong> brace and the following semicolon occupies -the entire line. Example: -<pre class="prettyprint"> -interface INfc { - close(); -}; -</pre> -</li> -</ul> - -<h3 id=package-declarations>Package declaration</h3> -<p>Package declaration should be at the top of the file after the license -notice, should occupy the entire line, and should not be indented. Packages are -declared using the following format (for name formatting, see -<a href="#package-names">Package names</a>):</p> - -<pre class="prettyprint"> -package <var>PACKAGE-NAME</var>; -</pre> - -<p>Example:</p> - -<pre class="prettyprint"> -package android.hardware.nfc@1.0; -</pre> - -<h3 id=function-declarations>Function declarations</h3> -<p>Function name, parameters, <code>generates</code>, and return values should -be on the same line if they fit. Example:</p> -<pre class="prettyprint"> -interface IFoo { - /** ... */ - easyMethod(int32_t data) generates (int32_t result); -}; -</pre> - -<p>If they don't fit on the same line, attempt to put parameters and return -values in the same indent level and distinguish <code>generate</code> to help -the reader quickly see the parameters and return values. Example:</p> - -<pre class="prettyprint"> -interface IFoo { - suchALongMethodThatCannotFitInOneLine(int32_t theFirstVeryLongParameter, - int32_t anotherVeryLongParameter); - anEvenLongerMethodThatCannotFitInOneLine(int32_t theFirstLongParameter, - int32_t anotherVeryLongParameter) - generates (int32_t theFirstReturnValue, - int32_t anotherReturnValue); - superSuperSuperSuperSuperSuperSuperLongMethodThatYouWillHateToType( - int32_t theFirstVeryLongParameter, // 8 spaces - int32_t anotherVeryLongParameter - ) generates ( - int32_t theFirstReturnValue, - int32_t anotherReturnValue - ); - // method name is even shorter than 'generates' - foobar(AReallyReallyLongType aReallyReallyLongParameter, - AReallyReallyLongType anotherReallyReallyLongParameter) - generates (ASuperLongType aSuperLongReturnValue, // 4 spaces - ASuperLongType anotherSuperLongReturnValue); -} -</pre> - -<p>Additional details:</p> -<ul> -<li>An open parenthesis is always on the same line as the function name.</li> -<li>No spaces between the function name and the open parenthesis.</li> -<li>No spaces between the parentheses and parameters <em>except</em> when there -are line feeds between them.</li> -<li>If <code>generates</code> is on the same line as the previous closing -parenthesis, use a preceding space. If <code>generates</code> is on the same -line as the next open parenthesis, follow with a space.</li> -<li>Align all parameters and return values (if possible).</li> -<li>Default indentation is 4 spaces.</li> -<li>Wrapped parameters are aligned to the first parameters on the previous line, -otherwise they have an 8-space indent.</li> -</ul> - -<h3 id=annotations>Annotations</h3> -<p>Use the following format for annotations:</p> - -<pre class="prettyprint"> -@annotate(keyword = value, keyword = {value, value, value}) -</pre> - -<p>Sort annotations in alphabetical order, and use spaces around equal signs. -Example:</p> - -<pre class="prettyprint"> -@callflow(key = value) -@entry -@exit -</pre> - -<p>Ensure an annotation occupies the entire line. Examples:</p> -<pre class="prettyprint"> -// Good -@entry -@exit - -// Bad -@entry @exit -</pre> - -<p>If annotations cannot fit on the same line, indent with 8 spaces. -Example:</p> - -<pre class="prettyprint"> -@annotate( - keyword = value, - keyword = { - value, - value - }, - keyword = value) -</pre> - -<p>If the entire value array cannot fit in the same line, put line breaks after -open braces <code>{</code> and after each comma inside the array. Place closing -parenthesis immediately after the last value. Do not put the braces if there is -only one value.</p> - -<p>If the entire value array can fit in the same line, do not use spaces after -open braces and before closing braces and use one space after each comma. -Examples:</p> - -<pre class="prettyprint"> -// Good -@callflow(key = {"val", "val"}) - -// Bad -@callflow(key = { "val","val" }) -</pre> - -<p>There must NOT be empty lines between annotations and the function -declaration. Examples:</p> -<pre class="prettyprint"> -// Good -@entry -foo(); - -// Bad -@entry - -foo(); -</pre> - -<h3 id=enum-declarations>Enum declarations</h3> -<p>Use the following rules for enum declarations:</p> -<ul> -<li>If enum declarations are shared with another package, put the declarations -in <code>types.hal</code> rather than embedding inside an interface.</li> -<li>Use a space before and after the colon, and space after the underlying type -before the open brace.</li> -<li>The last enum value may or may not have an extra comma.</li> -</ul> - -<h3 id=struct-declarations>Struct declarations</h3> -<p>Use the following rules for struct declarations:</p> -<ul> -<li>If struct declarations are shared with another package, put the declarations -in <code>types.hal</code> rather than embedding inside an interface.</li> -<li>Use a space after the struct type name before the open brace.</li> -<li>Align field names (optional). Example: -<pre class="prettyprint"> -struct MyStruct { - vec<uint8_t> data; - int32_t someInt; -} -</pre> -</li> -</ul> - -<h3 id=array-declarations>Array declarations</h3> -<p>Do not put spaces between the following:</p> -<ul> -<li>Element type and open square bracket.</li> -<li>Open square bracket and array size.</li> -<li>Array size and close square bracket.</li> -<li>Close square bracket and the next open square bracket, if more than one -dimension exists.</li> -</ul> - -<p>Examples:</p> -<pre class="prettyprint"> -// Good -int32_t[5] array; - -// Good -int32_t[5][6] multiDimArray; - -// Bad -int32_t [ 5 ] [ 6 ] array; -</pre> - -<h3 id=vectors>Vectors</h3> -<p>Do not put spaces between the following:</p> -<ul> -<li><code>vec</code> and open angle bracket.</li> -<li>Open angle bracket and element type (<em>Exception: element type is also a -<code>vec</code></em>).</li> -<li>Element type and close angle bracket (<em>Exception: element type is also a -<code>vec</code>)</em>.</li> -</ul> - -<p>Examples:</p> -<pre class="prettyprint"> -// Good -vec<int32_t> array; - -// Good -vec<vec<int32_t>> array; - -// Good -vec< vec<int32_t> > array; - -// Bad -vec < int32_t > array; - -// Bad -vec < vec < int32_t > > array; -</pre> - - </body> -</html> diff --git a/en/devices/architecture/hidl/converting.html b/en/devices/architecture/hidl/converting.html deleted file mode 100644 index d4dbacea..00000000 --- a/en/devices/architecture/hidl/converting.html +++ /dev/null @@ -1,87 +0,0 @@ -<html devsite> - <head> - <title>Converting HAL Modules</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>You can update pre-existing HAL modules to HIDL HAL modules by converting the -header in <code>hardware/libhardware/include/hardware</code>.</p> - -<h2 id=c2hal>Using c2hal</h2> -<p>The -<code><a href="https://android.googlesource.com/platform/system/tools/hidl/+/master/c2hal/">c2hal</code></a> -tool handles most of the conversion work, reducing the number of required manual -changes. For example, to generate a HIDL <code>.hal</code> file for the NFC -HAL:</p> -<pre class="devsite-click-to-copy"> -<code class="devsite-terminal">make c2hal</code> -c2hal -r android.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport -p android.hardware.nfc@1.0 hardware/libhardware/include/hardware/nfc.h -</pre> - -<p>These commands add files in <code>hardware/interfaces/nfc/1.0/</code>. Running -<code>hardware/interfaces/update-makefiles.sh</code> from the $ANDROID_BUILD_TOP -directory will also add the required makefile to the HAL. From here, you can -make manual changes to fully convert the HAL.</p> - -<h2 id=activities>c2hal activities</h2> -<p>When you run <code>c2hal</code>, everything in the header file is transferred -to <code>.hal</code> files.</p> - -<p><code>c2hal</code> identifies structs that contain function pointers in the -provided header file and converts each struct into a separate interface file. -For example, <code>alloc_device_t</code> is converted to the -<code>IAllocDevice</code> HAL module (in the file -<code>IAllocDevice.hal</code>).</p> - -<p>All other data types are copied over into a <code>types.hal</code> file. -Pound-defines are moved into enums, and items not a part of HIDL or not -convertible (such as static-function declarations) are copied into comments -marked with the text "<code>NOTE</code>".</p> - -<h2 id=manual>Manual activities</h2> -<p>The <code>c2hal</code> tool does not know what to do when it encounters -certain constructs. For example, HIDL has no concept of raw pointers; because of -this, when <code>c2hal</code> encounters a pointer in header files, it doesn't -know whether the pointer should be interpreted as an array or as a reference to -another object. Void pointers are also similarly opaque.</p> - -<p>Field such as <code>int reserved[7]</code> must be manually removed during -the transition to HIDL. Items such as the name of the return value should be -updated to something more meaningful; for example, converting the return -parameter of methods such as <code>write</code> in NFC from the autogenerated -<code>int32_t write_ret</code> to <code>Status status</code> (where -<code>Status</code> is a new enum containing possible NFC statuses).</p> - -<h2 id=implement>Implementing the HAL</h2> -<p>After you have created <code>.hal</code> files to represent your HAL, you -must generate the makefiles (Make or Soong) that create the language support in -C++ and Java (unless the HAL uses a feature unsupported in Java). The -<code>./hardware/interfaces/update-makefiles.sh</code> script can automatically -generate makefiles for HALs located in the <code>hardware/interfaces</code> -directory (for HALs in other locations, simply update the script).</p> - -<p>When the makefiles are up to date, you are ready to generate header files and -implement methods. For details on implementing the generated interface, see -<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a> (for C++ -implementations) or <a href="/devices/architecture/hidl-java/index.html">HIDL -Java</a> (for Java implementations).</p> - - </body> -</html> diff --git a/en/devices/architecture/hidl/fmq.html b/en/devices/architecture/hidl/fmq.html deleted file mode 100644 index 1573b071..00000000 --- a/en/devices/architecture/hidl/fmq.html +++ /dev/null @@ -1,433 +0,0 @@ -<html devsite> - <head> - <title>Fast Message Queue (FMQ)</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's remote procedure call (RPC) infrastructure uses Binder mechanisms, -meaning calls involve overhead, require kernel operations, and may trigger -scheduler action. However, for cases where data must be transferred between -processes with less overhead and no kernel involvement, the Fast Message Queue -(FMQ) system is used.</p> - -<p>FMQ creates message queues with the desired properties. An -<code>MQDescriptorSync</code> or <code>MQDescriptorUnsync</code> object can be -sent over a HIDL RPC call and used by the receiving process to access the -message queue.</p> - -<p class="caution">Fast Message Queues are supported only in C++.</p> - -<h2 id=flavors>MessageQueue types</h2> -<p>Android supports two queue types (known as <em>flavors</em>):</p> -<ul> -<li><em>Unsynchronized</em> queues are allowed to overflow, and can have many -readers; each reader must read data in time or lose it. -<li><em>Synchronized</em> queues are not allowed to overflow, and can have only -one reader.</li> -</ul> - -<p>Both queue types are not allowed to underflow (read from an empty queue will -fail) and can only have one writer.</p> - -<h3 id=unsync>Unsynchronized</h3> -<p>An unsynchronized queue has only one writer, but can have any number of -readers. There is one write position for the queue; however, each reader keeps -track of its own independent read position.</p> - -<p>Writes to the queue always succeed (are not checked for overflow) as long as -they are no larger than the configured queue capacity (writes larger than the -queue capacity fail immediately). As each reader may have a different read -position, rather than waiting for every reader to read every piece of data, data -is allowed to fall off the queue whenever new writes need the space.</p> - -<p>Reads are responsible for retrieving data before it falls off the end of -the queue. A read that attempts to read more data than is available either -fails immediately (if nonblocking) or waits for enough data to be available (if -blocking). A read that attempts to read more data than the queue capacity always -fails immediately.</p> - -<p>If a reader fails to keep up with the writer, so that the amount of data -written and not yet read by that reader is larger than the queue capacity, the -next read does not return data; instead, it resets the readers read -position to equal the latest write position then returns failure. If the -data available to read is checked after overflow but before the next read, it -shows more data available to read than the queue capacity, indicating -overflow has occurred. (If the queue overflows between checking available data -and attempting to read that data, the only indication of overflow is that the -read fails.)</p> - -<h3 id=sync>Synchronized</h3> -<p>A synchronized queue has one writer and one reader with a single write -position and a single read position. It is impossible to write more data than -the queue has space for or read more data than the queue currently holds. -Depending on whether the blocking or nonblocking write or read function is -called, attempts to exceed available space or data either return failure -immediately or block until the desired operation can be completed. Attempts to -read or write more data than the queue capacity will always fail immediately. -</p> - -<h2 id=setup>Setting up an FMQ</h2> -<p>A message queue requires multiple <code>MessageQueue</code> objects: one to -be written to, and one or more to be read from. There is no explicit -configuration of which object is used for writing or reading; it is up to the -user to ensure that no object is used for both reading and writing, that there -is at most one writer, and, for synchronized queues, that there is at most one -reader.</p> - -<h3 id=first-object>Creating the first MessageQueue object</h3> -<p>A message queue is created and configured with a single call:</p> - -<pre class="prettyprint"> -#include <fmq/MessageQueue.h> -using android::hardware::kSynchronizedReadWrite; -using android::hardware::kUnsynchronizedWrite; -using android::hardware::MQDescriptorSync; -using android::hardware::MQDescriptorUnsync; -using android::hardware::MessageQueue; -.... -// For a synchronized non-blocking FMQ -mFmqSynchronized = - new (std::nothrow) MessageQueue<uint16_t, kSynchronizedReadWrite> - (kNumElementsInQueue); -// For an unsynchronized FMQ that supports blocking -mFmqUnsynchronizedBlocking = - new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite> - (kNumElementsInQueue, true /* enable blocking operations */); -</pre> - -<ul> -<li>The <code>MessageQueue<T, flavor>(numElements)</code> initializer -creates and initializes an object that supports the message queue functionality. -</li> -<li>The <code>MessageQueue<T, flavor>(numElements, -configureEventFlagWord)</code> initializer creates and initializes an object -that supports the message queue functionality with blocking.</li> -<li><code>flavor</code> can be either <code>kSynchronizedReadWrite</code> for a -synchronized queue or <code>kUnsynchronizedWrite</code> for an unsynchronized -queue.</li> -<li><code>uint16_t</code> (in this example) can be any -<a href="/devices/architecture/hidl-cpp/types.html">HIDL-defined type</a> that -does not involve nested buffers (no <code>string</code> or <code>vec</code> -types), handles, or interfaces.</li> -<li><code>kNumElementsInQueue</code> indicates the size of queue in number of -entries; it determines the size of shared memory buffer that will be allocated -for the queue.</li> -</ul> - -<h3 id=second-object>Creating the second MessageQueue object</h3> -<p>The second side of the message queue is created using an -<code>MQDescriptor</code> object obtained from the first side. The -<code>MQDescriptor</code> object is sent over a HIDL RPC call to the process -that will hold the second end of the message queue. The -<code>MQDescriptor</code> contains information about the queue, including:</p> - -<ul> -<li>Information to map the buffer and write pointer.</li> -<li>Information to map the read pointer (if the queue is synchronized).</li> -<li>Information to map the event flag word (if the queue is blocking).</li> -<li>Object type (<code><T, flavor></code>), which includes the -<a href="/devices/architecture/hidl-cpp/types.html">HIDL-defined type</a> of -queue elements and the queue flavor (synchronized or unsynchronized).</li> -</ul> - -<p>The <code>MQDescriptor</code> object can be used to construct a -<code>MessageQueue</code> object:</p> - -<pre class="prettyprint"> -MessageQueue<T, flavor>::MessageQueue(const MQDescriptor<T, flavor>& Desc, bool resetPointers) -</pre> - -<p>The <code>resetPointers</code> parameter indicates whether to reset the read -and write positions to 0 while creating this <code>MessageQueue</code> object. -In an unsynchronized queue, the read position (which is local to each -<code>MessageQueue</code> object in unsynchronized queues) is always set to 0 -during creation. Typically, the <code>MQDescriptor</code> is initialized during -creation of the first message queue object. For extra control over the shared -memory, you can set up the <code>MQDescriptor</code> manually -(<code>MQDescriptor</code> is defined in -<a href="https://android.googlesource.com/platform/system/libhidl/+/master/base/include/hidl/MQDescriptor.h" class="external"><code>system/libhidl/base/include/hidl/MQDescriptor.h</code></a>) -then create every <code>MessageQueue</code> object as described in this section. -</p> - -<h3 id=blocking>Blocking queues and event flags</h3> -<p>By default, queues do not support blocking reads/writes. There are two kinds -of blocking read/write calls:</p> -<ul> -<li><em>Short form</em>, with three parameters (data pointer, number of items, -timeout). Supports blocking on individual read/write operations on a single -queue. When using this form, the queue will handle the event flag and bitmasks -internally, and the <a href="#first-object">first message queue object</a> must -be initialized with a second parameter of <code>true</code>. For example: -<pre> -// For an unsynchronized FMQ that supports blocking -mFmqUnsynchronizedBlocking = - new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite> - (kNumElementsInQueue, true /* enable blocking operations */); -<pre> -</li> -<li><em>Long form</em>, with six parameters (includes event flag and bitmasks). -Supports using a shared <code>EventFlag</code> object between multiple queues -and allows specifying the notification bit masks to be used. In this case, the -event flag and bitmasks must be supplied to each read and write call.</li> -</ul> - -<p>For the long form, the <code>EventFlag</code> can be supplied explicitly in -each <code>readBlocking()</code> and <code>writeBlocking()</code> call. One of -the queues may be initialized with an internal event flag, which must then be -extracted from that queue's <code>MessageQueue</code> objects using -<code>getEventFlagWord()</code> and used to create <code>EventFlag</code> -objects in each process for use with other FMQs. Alternatively, the -<code>EventFlag</code> objects can be initialized with any suitable shared -memory.</p> - -<p>In general, each queue should use only one of non-blocking, short-form -blocking, or long-form blocking. It is not an error to mix them, but careful -programming is required to get the desired result.</p> - -<h2 id=using>Using the MessageQueue</h2> -<p>The public API of the <code>MessageQueue</code> object is:</p> - -<pre class="prettyprint"> -size_t availableToWrite() // Space available (number of elements). -size_t availableToRead() // Number of elements available. -size_t getQuantumSize() // Size of type T in bytes. -size_t getQuantumCount() // Number of items of type T that fit in the FMQ. -bool isValid() // Whether the FMQ is configured correctly. -const MQDescriptor<T, flavor>* getDesc() // Return info to send to other process. - -bool write(const T* data) // Write one T to FMQ; true if successful. -bool write(const T* data, size_t count) // Write count T's; no partial writes. - -bool read(T* data); // read one T from FMQ; true if successful. -bool read(T* data, size_t count); // Read count T's; no partial reads. - -bool writeBlocking(const T* data, size_t count, int64_t timeOutNanos = 0); -bool readBlocking(T* data, size_t count, int64_t timeOutNanos = 0); - -// Allows multiple queues to share a single event flag word -std::atomic<uint32_t>* getEventFlagWord(); - -bool writeBlocking(const T* data, size_t count, uint32_t readNotification, -uint32_t writeNotification, int64_t timeOutNanos = 0, -android::hardware::EventFlag* evFlag = nullptr); // Blocking write operation for count Ts. - -bool readBlocking(T* data, size_t count, uint32_t readNotification, -uint32_t writeNotification, int64_t timeOutNanos = 0, -android::hardware::EventFlag* evFlag = nullptr) // Blocking read operation for count Ts; - -//APIs to allow zero copy read/write operations -bool beginWrite(size_t nMessages, MemTransaction* memTx) const; -bool commitWrite(size_t nMessages); -bool beginRead(size_t nMessages, MemTransaction* memTx) const; -bool commitRead(size_t nMessages); -</pre> - -<p><code>availableToWrite()</code> and <code>availableToRead()</code> can be used -to determine how much data can be transferred in a single operation. In an -unsynchronized queue:</p> - -<ul> -<li><code>availableToWrite()</code> always returns the capacity of the queue. -<li>Each reader has its own read position and does its own calculation for -<code>availableToRead()</code>.</li> -<li>From the point of view of a slow reader, the queue is allowed to overflow; -this may result in <code>availableToRead()</code> returning a value larger than -the size of the queue. The first read after an overflow will fail and result in -the read position for that reader being set equal to the current write pointer, -whether or not the overflow was reported through -<code>availableToRead()</code>.</li> -</ul> - -<p>The <code>read()</code> and <code>write()</code> methods return -<code>true</code> if all requested data could be (and was) transferred to/from -the queue. These methods do not block; they either succeed (and return -<code>true</code>), or return failure (<code>false</code>) immediately.</p> - -<p>The <code>readBlocking()</code> and <code>writeBlocking()</code> methods wait -until the requested operation can be completed, or until they timeout (a -<code>timeOutNanos</code> value of 0 means never timeout).</p> - -<p>Blocking operations are implemented using an event flag word. By default, -each queue creates and uses its own flag word to support the short form of -<code>readBlocking()</code> and <code>writeBlocking()</code>. It is possible for -multiple queues to share a single word, so that a process can wait on writes or -reads to any of the queues. A pointer to a queue's event flag word can be -obtained by calling <code>getEventFlagWord()</code>, and that pointer (or any -pointer to a suitable shared memory location) can be used to create an -<code>EventFlag</code> object to pass into the long form of -<code>readBlocking()</code> and <code>writeBlocking()</code>for a different -queue. The <code>readNotification</code> and <code>writeNotification</code> -parameters tell which bits in the event flag should be used to signal reads and -writes on that queue. <code>readNotification</code> and -<code>writeNotification</code> are 32-bit bitmasks.</p> - -<p><code>readBlocking()</code> waits on the <code>writeNotification</code> bits; -if that parameter is 0, the call always fails. If the -<code>readNotification</code> value is 0, the call will not fail, but a -successful read will not set any notification bits. In a synchronized queue, -this would mean that the corresponding <code>writeBlocking()</code> call will -never wake up unless the bit is set elsewhere. In an unsynchronized queue, -<code>writeBlocking()</code> will not wait (it should still be used to set the -write notification bit), and it is appropriate for reads to not set any -notification bits. Similarly, <code>writeblocking()</code> will fail if -<code>readNotification</code> is 0, and a successful write sets the specified -<code>writeNotification</code> bits.</p> - -<p>To wait on multiple queues at once, use an <code>EventFlag</code> object's -<code>wait()</code> method to wait on a bitmask of notifications. The -<code>wait()</code> method returns a status word with the bits that caused the -wake up set. This information is then used to verify the corresponding queue has -enough space or data for the desired write/read operation and perform a -nonblocking <code>write()</code>/<code>read()</code>. To get a post operation -notification, use another call to the <code>EventFlag</code>'s -<code>wake()</code> method. For a definition of the <code>EventFlag</code> -abstraction, refer to -<a href="https://android.googlesource.com/platform/system/libfmq/+/master/include/fmq/EventFlag.h" class="external"><code>system/libfmq/include/fmq/EventFlag.h</code></a>. -</p> - -<h2 id=zero>Zero copy operations</h2> -<p>The -<code>read</code>/<code>write</code>/<code>readBlocking</code>/<code>writeBlocking()</code> -APIs take a pointer to an input/output buffer as an argument and use -<code>memcpy()</code> calls internally to copy data between the same and the -FMQ ring buffer. To improve performance, Android 8.0 and higher include a set of -APIs that provide direct pointer access into the ring buffer, eliminating the -need to use <code>memcpy</code> calls.</p> - -<p>Use the following public APIs for zero copy FMQ operations:</p> - -<pre class="prettyprint"> -bool beginWrite(size_t nMessages, MemTransaction* memTx) const; -bool commitWrite(size_t nMessages); - -bool beginRead(size_t nMessages, MemTransaction* memTx) const; -bool commitRead(size_t nMessages); -</pre> - -<ul> -<li>The <code>beginWrite</code> method provides base pointers into the FMQ ring -buffer. After the data is written, commit it using <code>commitWrite()</code>. -The<code>beginRead</code>/<code>commitRead</code> methods act the same way.</li> -<li>The <code>beginRead</code>/<code>Write</code> methods take as input the -number of messages to be read/written and return a boolean indicating if the -read/write is possible. If the read or write is possible the <code>memTx</code> -struct is populated with base pointers that can be used for direct pointer -access into the ring buffer shared memory.</li> -<li>The <code>MemRegion</code> struct contains details about a block of memory, -including the base pointer (base address of the memory block) and the length in -terms of <code>T</code> (length of the memory block in terms of the HIDL-defined -type of the message queue).</li> -<li>The <code>MemTransaction</code> struct contains two <code>MemRegion</code> -structs, <code>first</code> and <code>second</code> as a read or write into -the ring buffer may require a wrap around to the beginning of the queue. This -would mean that two base pointers are needed to read/write data into the FMQ -ring buffer.</li> -</ul> - -<p>To get the base address and length from a <code>MemRegion</code> struct:</p> - -<pre class="prettyprint"> -T* getAddress(); // gets the base address -size_t getLength(); // gets the length of the memory region in terms of T -size_t getLengthInBytes(); // gets the length of the memory region in bytes -</pre> - -<p>To get references to the first and second <code>MemRegion</code>s within a -<code>MemTransaction</code> object:</p> - -<pre class="prettyprint"> -const MemRegion& getFirstRegion(); // get a reference to the first MemRegion -const MemRegion& getSecondRegion(); // get a reference to the second MemRegion -</pre> - -<p>Example write to the FMQ using zero copy APIs:</p> - -<pre class="prettyprint"> -MessageQueueSync::MemTransaction tx; -if (mQueue->beginRead(dataLen, &tx)) { - auto first = tx.getFirstRegion(); - auto second = tx.getSecondRegion(); - - foo(first.getAddress(), first.getLength()); // method that performs the data write - foo(second.getAddress(), second.getLength()); // method that performs the data write - - if(commitWrite(dataLen) == false) { - // report error - } -} else { - // report error -} -</pre> - -<p>The following helper methods are also part of <code>MemTransaction</code>: -</p> - -<ul> -<li><code>T* getSlot(size_t idx);</code> -<br>Returns a pointer to slot <code>idx</code> within the -<code>MemRegions</code> that are part of this <code>MemTransaction</code> -object. If the <code>MemTransaction</code> object is representing the memory -regions to read/write N items of type T, then the valid range of -<code>idx</code> is between 0 and N-1.</li> -<li><code>bool copyTo(const T* data, size_t startIdx, size_t nMessages = 1);</code> -<br>Write <code>nMessages</code>' items of type T into the memory regions -described by the object, starting from index <code>startIdx</code>. This method -uses <code>memcpy()</code> and is not to meant to be used for a zero copy -operation. If the <code>MemTransaction</code> object represents memory to -read/write N items of type T, then the valid range of <code>idx</code> is -between 0 and N-1.</li> -<li><code>bool copyFrom(T* data, size_t startIdx, size_t nMessages = 1);</code> -<br>Helper method to read <code>nMessages</code>' items of type T from the -memory regions described by the object starting from <code>startIdx</code>. This -method uses <code>memcpy()</code> and is not meant to be used for a zero copy -operation.</li> -</ul> - -<h2 id=sending>Sending the queue over HIDL</h2> -<p>On the creating side:</p> -<ol> -<li>Create message queue object as described above.</li> -<li>Verify the object is valid with <code>isValid()</code>.</li> -<li>If you will be waiting on multiple queues by passing an -<code>EventFlag</code> into the long form of -<code>readBlocking()</code>/<code>writeBlocking()</code>, you can extract the -event flag pointer (using <code>getEventFlagWord()</code>) from a -<code>MessageQueue</code> object that was initialized to create the flag, and -use that flag to create the necessary <code>EventFlag</code> object.</li> -<li>Use the <code>MessageQueue</code> <code>getDesc()</code> method to get a -descriptor object.</li> -<li>In the <code>.hal</code> file, give the method a parameter of type -<code>fmq_sync<T></code> or <code>fmq_unsync<T></code> where <code>T</code> is a -suitable HIDL-defined type. Use this to send the object returned by -<code>getDesc()</code> to the receiving process.</li> -</ol> - -<p>On the receiving side:</p> -<ol> -<li>Use the descriptor object to create a <code>MessageQueue</code> object. Be -sure to use the same queue flavor and data type, or the template will fail to -compile.</li> -<li>If you extracted an event flag, extract the flag from the corresponding -<code>MessageQueue</code> object in the receiving process.</li> -<li>Use the <code>MessageQueue</code> object to transfer data.</li> -</ol> - - </body> -</html> diff --git a/en/devices/architecture/hidl/hashing.html b/en/devices/architecture/hidl/hashing.html deleted file mode 100644 index 3debea85..00000000 --- a/en/devices/architecture/hidl/hashing.html +++ /dev/null @@ -1,167 +0,0 @@ -<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> diff --git a/en/devices/architecture/hidl/index.html b/en/devices/architecture/hidl/index.html deleted file mode 100644 index 35b166dd..00000000 --- a/en/devices/architecture/hidl/index.html +++ /dev/null @@ -1,338 +0,0 @@ -<html devsite> - <head> - <title>HIDL</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>HAL interface definition language or HIDL (pronounced "hide-l") is an -interface description language (IDL) to specify the interface between a HAL and -its users. It allows specifying types and method calls, collected into -interfaces and packages. More broadly, HIDL is a system for communicating -between codebases that may be compiled independently.</p> - -<p>HIDL is intended to be used for inter-process communication (IPC). -Communication between processes is referred to as -<a href="/devices/architecture/hidl/binder-ipc"><em>Binderized</em></a>. For -libraries that must be linked to a process, a <a href="#passthrough">passthrough -mode</a> is also available (not supported in Java).</p> - -<p>HIDL specifies data structures and method signatures, organized in interfaces -(similar to a class) that are collected into packages. The syntax of HIDL will -look familiar to C++ and Java programmers, though with a different set of -keywords. HIDL also uses Java-style annotations.</p> - -<h2 id=design>HIDL design</h2> -<p>The goal of HIDL is that the framework can be replaced without having to -rebuild HALs. HALs will be built by vendors or SOC makers and put in a -<code>/vendor</code> partition on the device, enabling the framework, in its own -partition, to be replaced with an OTA without recompiling the HALs.</p> - -<p>HIDL design balances the following concerns:</p> -<ul> -<li><strong>Interoperability</strong>. Create reliably interoperable interfaces -between processes which may be compiled with various architectures, toolchains, -and build configurations. HIDL interfaces are versioned and cannot be changed -after they are published.</li> -<li><strong>Efficiency</strong>. HIDL tries to minimize the number of copy -operations. HIDL-defined data is delivered to C++ code in C++ standard layout -data structures that can be used without unpacking. HIDL also provides shared -memory interfaces and, as RPCs are inherently somewhat slow, HIDL supports two -ways to transfer data without using an RPC call: shared memory and a Fast -Message Queue (FMQ).</li> -<li><strong>Intuitive</strong>. HIDL avoids thorny issues of memory ownership by -using only <code>in</code> parameters for RPC (see -<a href="https://developer.android.com/guide/components/aidl.html" class="external">Android -Interface Definition Language (AIDL)</a>); values that cannot be efficiently -returned from methods are returned via callback functions. Neither passing data -into HIDL for transfer nor receiving data from HIDL changes the ownership of the -data—ownership always remains with the calling function. Data needs to -persist only for the duration of the called function and may be destroyed -immediately after the called function returns.</li> -</ul> - -<h2 id=passthrough>Using passthrough mode</h2> -<p>To update devices running earlier versions of Android to Android O, you can -wrap both conventional (and legacy) HALs in a new HIDL interface that serves the -HAL in binderized and same-process (passthrough) modes. This wrapping is -transparent to both the HAL and the Android framework.</p> - -<p>Passthrough mode is available only for C++ clients and implementations. -Devices running earlier versions of Android do not have HALs written in Java, so -Java HALs are inherently binderized.</p> - -<h3 id=header>Passthrough header files</h3> -<p>When a <code>.hal</code> file is compiled, <code>hidl-gen</code> produces an -extra passthrough header file <code>BsFoo.h</code> in addition to the headers -used for binder communication; this header defines functions to be -<code>dlopen</code>ed. As passthrough HALs run in the same process in which -they are called, in most cases passthrough methods are invoked by direct -function call (same thread). <code>oneway</code> methods run in their own thread -as they are not intended to wait for the HAL to process them (this means any HAL -that uses <code>oneway</code> methods in passthrough mode must be thread-safe). -</p> - -<p>Given an <code>IFoo.hal</code>, <code>BsFoo.h</code> wraps the HIDL-generated -methods to provide additional features (such as making <code>oneway</code> -transactions run in another thread). This file is similar to -<code>BpFoo.h</code>, however instead of passing on calls IPC using binder, the -desired functions are directly invoked. Future implementations of HALs -<strong>may provide</strong> multiple implementations, such as FooFast HAL and a -FooAccurate HAL. In such cases, a file for each additional implementation would -be created (e.g., <code>PTFooFast.cpp</code> and -<code>PTFooAccurate.cpp</code>).</p> - -<h3 id=binderized>Binderizing passthrough HALs</h3> -<p>You can binderize HAL implementations that support passthrough mode. Given a -HAL interface <code>a.b.c.d@M.N::IFoo</code>, two packages are created:</p> - -<ul> -<li><code>a.b.c.d@M.N::IFoo-impl</code>. Contains the implementation of the HAL -and exposes function <code>IFoo* HIDL_FETCH_IFoo(const char* name)</code>. On -legacy devices, this package is <code>dlopen</code>ed and the implementation is -instantiated using <code>HIDL_FETCH_IFoo</code>. You can generate the base code -using <code>hidl-gen</code> and <code>-Lc++-impl</code> and -<code>-Landroidbp-impl</code>.</li> -<li><code>a.b.c.d@M.N::IFoo-service</code>. Opens the passthrough HAL and -registers itself as a binderized service, enabling the same HAL implementation -to be used as both passthrough and binderized.</li> -</ul> - -<p>Given the type <code>IFoo</code>, you can call <code>sp<IFoo> -IFoo::getService(string name, bool getStub)</code> to get access to an instance -of <code>IFoo</code>. If <code>getStub</code> is true, <code>getService</code> -attempts to open the HAL only in passthrough mode. If <code>getStub</code> is -false, <code>getService</code> attempts to find a binderized service; if that -fails, it then tries to find the passthrough service. The <code>getStub</code> -parameter should never be used except in -<code>defaultPassthroughServiceImplementation</code>. (Devices launching with -Android O are fully binderized devices, so opening a service in passthrough mode -is disallowed.)</p> - -<h2 id=grammar>HIDL grammar</h2> -<p>By design, the HIDL language is similar to C (but does not use the C -preprocessor). All punctuation not described below (aside from the obvious use -of <code>=</code> and <code>|</code>) is part of the grammar.</p> - -<p class=note><strong>Note:</strong> For details on HIDL code style, see the -<a href="code-style.html">Code Style Guide</a>.</p> - -<ul> -<li><code>/** */</code> indicates a documentation comment. These can be applied -only to type, method, field, and enum value declarations.</li> -<li><code>/* */</code> indicates a multiline comment.</li> -<li><code>//</code> indicates a comment to end of line. Aside from -<code>//</code>, newlines are the same as any other whitespace. </li> -<li>In the example grammar below, text from <code>//</code> to the end of the -line is not part of the grammar but is instead a comment on the grammar.</li> -<li><code>[empty]</code> means that the term may be empty. </li> -<li><code>?</code> following a literal or term means it is optional.</li> -<li><code>...</code> indicates sequence containing zero or more items with -separating punctuation as indicated. There are no variadic arguments in HIDL.</li> -<li>Commas separate sequence elements.</li> -<li>Semicolons terminate each element, including the last element.</li> -<li>UPPERCASE is a nonterminal.</li> -<li><code><em>italics</code></em> is a token family such as -<code><em>integer</code></em> or <code><em>identifier</code></em> (standard C -parsing rules).</li> -<li><code><em>constexpr</em> </code>is a C style constant expression (such as -<code>1 + 1</code> and <code>1L << 3</code>).</li> -<li><code><em>import_name</code></em> is a package or interface name, qualified -as described in <a href="/devices/architecture/hidl/versioning.html"> HIDL -Versioning</a>.</li> -<li>Lowercase <code>words</code> are literal tokens.</li> -</ul> -<p>Example:</p> -<pre class="prettyprint"> -ROOT = - PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... } // not for types.hal - PREAMBLE = interface identifier EXTENDS - | PACKAGE IMPORTS ITEM ITEM... // only for types.hal; no method definitions - -ITEM = - ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?; - | struct identifier { SFIELD; SFIELD; ...}; // Note - no forward declarations - | union identifier { UFIELD; UFIELD; ...}; - | enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar - | typedef TYPE identifier; - -VERSION = integer.integer; - -PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION; - -PREAMBLE = interface identifier EXTENDS - -EXTENDS = <empty> | extends import_name // must be interface, not package - -GENERATES = generates (FIELD, FIELD ...) - -// allows the Binder interface to be used as a type -// (similar to typedef'ing the final identifier) -IMPORTS = - [empty] - | IMPORTS import import_name; - -TYPE = - uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t | - float | double | bool | string -| identifier // must be defined as a typedef, struct, union, enum or import - // including those defined later in the file -| memory -| pointer -| vec<TYPE> -| bitfield<TYPE> // TYPE is user-defined enum -| fmq_sync<TYPE> -| fmq_unsync<TYPE> -| TYPE[SIZE] - -FIELD = - TYPE identifier - -UFIELD = - TYPE identifier - | struct identifier { FIELD; FIELD; ...} identifier; - | union identifier { FIELD; FIELD; ...} identifier; - -SFIELD = - TYPE identifier - | struct identifier { FIELD; FIELD; ...}; - | union identifier { FIELD; FIELD; ...}; - | struct identifier { FIELD; FIELD; ...} identifier; - | union identifier { FIELD; FIELD; ...} identifier; - -SIZE = // Must be greater than zero - constexpr - -ANNOTATIONS = - [empty] - | ANNOTATIONS ANNOTATION - -ANNOTATION = - | @identifier - | @identifier(VALUE) - | @identifier(ANNO_ENTRY, ANNO_ENTRY ...) - -ANNO_ENTRY = - identifier=VALUE - -VALUE = - "any text including \" and other escapes" - | constexpr - | {VALUE, VALUE ...} // only in annotations - -ENUM_ENTRY = - identifier - | identifier = constexpr -</pre> - -<h2 id=terms>Terminology</h2> -<p>This section uses the following HIDL-related terms:</p> - -<table> -<tbody> - -<tr> -<th>binderized</th> -<td>Indicates HIDL is being used for remote procedure calls between processes, -implemented over a Binder-like mechanism. See also <em>passthrough</em>.</td> -</tr> - -<tr> -<th>callback, asynchronous</th> -<td>Interface served by a HAL user, passed to the HAL (via a HIDL method), and -called by the HAL to return data at any time.</td> -</tr> - -<tr> -<th>callback, synchronous</th> -<td>Returns data from a server's HIDL method implementation to the client. -Unused for methods that return void or a single primitive value.</td> -</tr> - -<tr> -<th>client</th> -<td>Process that calls methods of a particular interface. A HAL or framework -process may be a client of one interface and a server of another. See also -<em>passthrough</em>.</td> -</tr> - -<tr> -<th>extends</th> -<td>Indicates an interface that adds methods and/or types to another interface. -An interface can extend only one other interface. Can be used for a minor -version increment in the same package name or for a new package (e.g. a vendor -extension) to build on an older package.</td> -</tr> - -<tr> -<th>generates</th> -<td>Indicates an interface method that returns values to the client. To return -one non-primitive value, or more than one value, a synchronous callback function -is generated.</td> -</tr> - -<tr> -<th>interface</th> -<td>Collection of methods and types. Translated into a class in C++ or Java. All -methods in an interface are called in the same direction: a client process -invokes methods implemented by a server process.</td> -</tr> - -<tr> -<th>oneway</th> -<td>When applied to a HIDL method, indicates the method returns no values and -does not block.</td> -</tr> - -<tr> -<th>package</th> -<td>Collection of interfaces and data types sharing a version.</td> -</tr> - -<tr> -<th>passthrough</th> -<td>Mode of HIDL in which the server is a shared library, <code>dlopen</code>ed -by the client. In passthrough mode, client and server are the same process but -separate codebases. Used only to bring legacy codebases into the HIDL model. -See also <em>Binderized</em>.</td> -</tr> - -<tr> -<th>server</th> -<td>Process that implements methods of an interface. See also -<em>passthrough</em>.</td> -</tr> - -<tr> -<th>transport</th> -<td>HIDL infrastructure that moves data between the server and client.</td> -</tr> - -<tr> -<th>version</th> -<td>Version of a package. Consists of two integers, major and minor. Minor -version increments may add (but not change) types and methods.</td> -</tr> - -</tbody> -</table> - - </body> -</html> diff --git a/en/devices/architecture/hidl/interfaces.html b/en/devices/architecture/hidl/interfaces.html deleted file mode 100644 index 483b521a..00000000 --- a/en/devices/architecture/hidl/interfaces.html +++ /dev/null @@ -1,316 +0,0 @@ -<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 android.hardware.example.extension.light@2.0</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>android.hidl.base@1.0::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 android.hardware.nfc@1.0; // import a whole package -import android.hardware.example@1.0::IQuux; // import an interface and types.hal -import android.hardware.example@1.0::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>Multiple major or minor versions of a HAL can be present on a device -simultaneously. However, a minor version should be preferred over a major -version because client code that works with a previous minor version interface -will also work with later minor versions of that same interface. 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>android.hardware.foo@1.0::IFoo</code>.</td> -</tr> -<tr> -<td>Package</td> -<td>Package containing a HIDL interface and types. Example: -<code>android.hardware.foo@1.0</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>android.hardware.foo@1.0</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>vendor.awesome.foo@1.0::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> diff --git a/en/devices/architecture/hidl/memoryblock.md b/en/devices/architecture/hidl/memoryblock.md deleted file mode 100644 index de2b3493..00000000 --- a/en/devices/architecture/hidl/memoryblock.md +++ /dev/null @@ -1,302 +0,0 @@ -Project: /_project.yaml -Book: /_book.yaml - -{% include "_versions.html" %} - -<!-- - 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. ---> - -# HIDL Memory Block - -The HIDL MemoryBlock is an abstract layer built on `hidl_memory`, `HIDL -@1.0::IAllocator`, and `HIDL @1.0::IMapper`. It is designed for HIDL services -that have multiple memory blocks to share a single memory heap. - - -## Performance improvements - -Using MemoryBlock in applications can significantly reduce the number of -`mmap`/`munmap` and user space segmentation faults, thus improving performance. -For example: - -* Using per `hidl_memory` for each buffer allocation averages 238 us/1 allocation. -* Using `MemoryBlock` and sharing a single `hidl_memory` averages 2.82 us/1 allocation. - - -## Architecture - -The HIDL MemoryBlock architecture includes HIDL services with multiple memory -blocks sharing a single memory heap: - -![HIDL MemoryBlock](/devices/architecture/images/hidl_memoryblock_arch.png) - -**Figure 1.** HIDL MemoryBlock architecture - - -## Normal usage - -This section provides an example of using MemoryBlock by first declaring the HAL -then implementing the HAL. - - -### Declaring the HAL - -For the following example IFoo HAL: - -``` -import android.hidl.memory.block@1.0::MemoryBlock; - -interface IFoo { - getSome() generates(MemoryBlock block); - giveBack(MemoryBlock block); -}; -``` - -The `Android.bp` is as follows: - -``` -hidl_interface { - ... - srcs: [ - "IFoo.hal", - ], - interfaces: [ - "android.hidl.memory.block@1.0", - ... -}; -``` - -### Implementing the HAL - -To implement the example HAL: - -1. Get the `hidl_memory` (for details, refer to [HIDL C++](/devices/architecture/hidl-cpp/)). - - - ``` - #include <android/hidl/allocator/1.0/IAllocator.h> - - using ::android::hidl::allocator::V1_0::IAllocator; - using ::android::hardware::hidl_memory; - ... - sp<IAllocator> allocator = IAllocator::getService("ashmem"); - allocator->allocate(2048, [&](bool success, const hidl_memory& mem) - { - if (!success) { /* error */ } - // you can now use the hidl_memory object 'mem' or pass it - })); - ``` - -1. Make a `HidlMemoryDealer` with the acquired `hidl_memory`: - - ``` - #include <hidlmemory/HidlMemoryDealer.h> - - using ::android::hardware::HidlMemoryDealer - /* The mem argument is acquired in the Step1, returned by the ashmemAllocator->allocate */ - sp<HidlMemoryDealer> memory_dealer = HidlMemoryDealer::getInstance(mem); - ``` - -1. Allocate `MemoryBlock`, which is a struct defined with HIDL. - - Example `MemoryBlock`: - - ``` - struct MemoryBlock { - IMemoryToken token; - uint64_t size; - uint64_t offset; - }; - ``` - - Example using the `MemoryDealer` to allocate a `MemoryBlock`: - - - ``` - #include <android/hidl/memory/block/1.0/types.h> - - using ::android::hidl::memory::block::V1_0::MemoryBlock; - - Return<void> Foo::getSome(getSome_cb _hidl_cb) { - MemoryBlock block = memory_dealer->allocate(1024); - if(HidlMemoryDealer::isOk(block)){ - _hidl_cb(block); - ... - ``` - -1. Deallocate `MemoryBlock`: - - ``` - Return<void> Foo::giveBack(const MemoryBlock& block) { - memory_dealer->deallocate(block.offset); - ... - ``` - -1. Manipulate the data: - - ``` - #include <hidlmemory/mapping.h> - #include <android/hidl/memory/1.0/IMemory.h> - - using ::android::hidl::memory::V1_0::IMemory; - - sp<IMemory> memory = mapMemory(block); - uint8_t* data = - - static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())); - ``` - -1. Config `Android.bp`: - - ``` - shared_libs: [ - "android.hidl.memory@1.0", - - "android.hidl.memory.block@1.0" - - "android.hidl.memory.token@1.0", - "libhidlbase", - "libhidlmemory", - ``` - -1. Review the flow to determine if you need to `lockMemory`. - - Normally, the MemoryBlock uses reference count to maintain the shared - `hidl_memory` which is `mmap()`-ed the first time one of its `MemoryBlock`s gets - mapped and is `munmap()`-ed when nothing refers to it. To keep the `hidl_memory` - always mapped, you can use `lockMemory`, a RAII style object that keeps the - corresponding `hidl_memory` mapped throughout the lock life cycle. Example: - - ``` - #include <hidlmemory/mapping.h> - - sp<RefBase> lockMemory(const sp<IMemoryToken> key); - ``` - -## Extended usage - -This section provides details about the extended usage of `MemoryBlock`. - - -### Using reference count to manage Memoryblock - -In most situations, the most efficient way to use MemoryBlock is to explicitly -allocate/deallocate. However, in complicated applications using reference count -for garbage collection might be a better idea. To have reference count on -MemoryBlock, you can bind MemoryBlock with a binder object, which helps to count -the references and deallocate the MemoryBlock when the count decreases to zero. - - -### Declaring the HAL - -When declaring the HAL, describe a HIDL struct that contains a MemoryBlock and a -IBase: - - -``` -import android.hidl.memory.block@1.0::MemoryBlock; - -struct MemoryBlockAllocation { - MemoryBlock block; - IBase refcnt; -}; -``` - -Use the `MemoryBlockAllocation` to replace `MemoryBlock` and remove the method -to give back the `MemoryBlock`. It will be deallocated by reference counting -with the `MemoryBlockAllocation`. Example: - - -``` -interface IFoo { - allocateSome() generates(MemoryBlockAllocation allocation); -}; -``` - -### Implementing the HAL - -Example of the service side implementation of the HAL: - - -``` -class MemoryBlockRefCnt: public virtual IBase { - MemoryBlockRefCnt(uint64_t offset, sp<MemoryDealer> dealer) - : mOffset(offset), mDealer(dealer) {} - ~MemoryBlockRefCnt() { - mDealer->deallocate(mOffset); - } - private: - uint64_t mOffset; - sp<MemoryDealer> mDealer; -}; - -Return<void> Foo::allocateSome(allocateSome_cb _hidl_cb) { - MemoryBlockAllocation allocation; - allocation.block = memory_dealer->allocate(1024); - if(HidlMemoryDealer::isOk(block)){ - allocation.refcnt= new MemoryBlockRefCnt(...); - _hidl_cb(allocation); -``` - - -Example of the client side implementation of the HAL: - - -``` -ifoo->allocateSome([&](const MemoryBlockAllocation& allocation){ - ... -); -``` - -### Attaching/retrieving metadata - -Some applications need additional data to bind with the allocated `MemoryBlock`. -You can append/retrieve metadata using two methods: - - -* If the application accesses the metadata as often as the block itself, - append the metadata and pass them all in a struct. Example: - - ``` - import android.hidl.memory.block@1.0::MemoryBlock; - - struct MemoryBlockWithMetaData{ - MemoryBlock block; - MetaDataStruct metaData; - }; - ``` - -* If the application accesses the metadata much less frequently than the - block, it is more efficient to pass the metadata passively with an - interface. Example: - - ``` - import android.hidl.memory.block@1.0::MemoryBlock; - - struct MemoryBlockWithMetaData{ - MemoryBlock block; - IMetaData metaData; - }; - ``` - - Next, bind the metadata with the MemoryBlock using the Memory Dealer. Example: - - ``` - MemoryBlockWithMetaData memory_block; - memory_block.block = dealer->allocate(size); - if(HidlMemoryDealer::isOk(block)){ - memory_block.metaData = new MetaData(...); - ``` diff --git a/en/devices/architecture/hidl/network-stack.html b/en/devices/architecture/hidl/network-stack.html deleted file mode 100644 index 88377324..00000000 --- a/en/devices/architecture/hidl/network-stack.html +++ /dev/null @@ -1,176 +0,0 @@ -<html devsite> - <head> - <title>Network Stack Configuration Tools</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>The Android operating system contains standard Linux networking utilities -such as <code>ifconfig</code>, <code>ip</code>, and <code>ip6tables</code>. -These utilities reside on the system image and enable configuration of the -entire Linux networking stack. On devices running Android 7.x and earlier, -vendor code is allowed to call these binaries directly, which presents the -following problems:</p> - -<ul> -<li>Because network utilities are updated in the system image, they do not -provide a stable implementation.</li> -<li>The scope of the networking utilities is so broad it is difficult to evolve -the system image while guaranteeing predictable behaviour.</li> -</ul> - -<p>On devices running Android 8.0, the vendor partition can remain the same -while the system partition receives an update. To achieve this, Android 8.0 -provides the ability to define a stable, versioned interface while also using -SELinux restrictions to keep the interdependency of vendor and system image to a -known good set.</p> - -<p>Vendors can use the platform-provided network configuration utilities to -configure the Linux networking stack, but these utilities do not yet include a -HIDL interface wrapper. To define such an interface, Android 8.0 includes the -<code>netutils-wrapper-1.0</code> tool. -</p> - -<h2 id="netutils-wrapper">Netutils wrapper</h2> -<p>The <code>netutils</code> wrapper utility provides a subset of the Linux -network stack configuration that is not affected by system partition updates. -Android 8.0 contains version 1.0 of the wrappers, which allows you to pass the -same arguments as the wrapped utilities, installed in the system partition at -<code>/system/bin</code> as follows:</p> - -<pre class="prettyprint"> -u:object_r:system_file:s0 /system/bin/ip-wrapper-1.0 -> netutils-wrapper-1.0 -u:object_r:system_file:s0 /system/bin/ip6tables-wrapper-1.0 -> netutils-wrapper-1.0 -u:object_r:system_file:s0 /system/bin/iptables-wrapper-1.0 -> netutils-wrapper-1.0 -u:object_r:system_file:s0 /system/bin/ndc-wrapper-1.0 -> netutils-wrapper-1.0 -u:object_r:netutils_wrapper_exec:s0 /system/bin/netutils-wrapper-1.0 -u:object_r:system_file:s0 /system/bin/tc-wrapper-1.0 -> netutils-wrapper-1.0 -</pre> - -<p>Symlinks show the networking utilities wrapped by the <code>netutils</code> -wrapper, which include:</p> -<ul> -<li><code>ip</code></li> -<li><code>iptables</code></li> -<li><code>ip6tables</code></li> -<li><code>ndc</code></li> -<li><code>tc</code></li> -</ul> - -<p>To use these utilities in Android 8.0 and later, vendor implementations must -adhere to the following rules:</p> -<ul> -<li>Vendor processes must not execute -<code>/system/bin/netutils-wrapper-1.0</code> directly; attempts to do so will -result in error.</li> -<li>All utilities wrapped by <code>netutils-wrapper-1.0</code> must be launched -using their symlinks. For example, change the vendor code that did this before -(<code>/system/bin/ip <FOO> <BAR></code>) to -<code>/system/bin/ip-wrapper-1.0 <FOO> <BAR></code>.</li> -<li>Executing the wrappers without domain transition is prohibited in platform -SELinux policy. This rule must not be changed and is tested against in the -<a href="/compatibility/cts.html">Android Compatibility Test Suite (CTS)</a>. -</li> -<li>Executing the utilities directly (e.g., -<code>/system/bin/ip <FOO> <BAR></code>) from the vendor processes -is also prohibited in the platform SELinux policies. This rule must not be -changed and is tested against in CTS.</li> -<li>Any vendor domain (process) that needs to launch a wrapper must add the -following domain transition rule in the SELinux policy: -<code>domain_auto_trans(<var>VENDOR-DOMAIN-NAME</var>, netutils_wrapper_exec, -netutils_wrapper)</code>.</li> -</ul> - -<aside class="note"><strong>Note:</strong> For details on Android 8.0 SELinux, -see <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android -8.0</a>.</aside> - -<h2 id="netutils-wrapper-filters">Netutils wrapper filters</h2> -<p>Wrapped utilities can be used to configure almost any aspect of the Linux -networking stack. However, to ensure it is possible to maintain a stable -interface and allow updates to the system partition, only certain combinations -of command line arguments are allowed; other commands will be rejected.</p> - -<h3 id="vendor-interfaces-and-chains">Vendor interfaces and chains</h3> -<p>The wrapper has a concept of <em>vendor interfaces</em>. These are interfaces -typically managed by vendor code, such as cellular data interfaces. Typically, -other types of interfaces (such as Wi-Fi) are managed by the HALs and the -framework. The wrapper recognizes vendor interfaces by name (using a regular -expression) and allows vendor code to perform many operations on them. -Currently, vendor interfaces are:</p> -<ul> -<li>Interfaces whose names end in "oem" followed by a number, such as -<code>oem0</code> or <code>r_oem1234</code>.</li> -<li>Interfaces used by current SOC and OEM implementations, such as -<code>rmnet_data[0-9]</code>.</li> -</ul> - -<p>Names of interfaces that are typically managed by the framework (such as -<code>wlan0</code>) are never vendor interfaces.</p> - -<p>The wrapper has a similar concept of <em>vendor chains</em>. These are used -in <code>iptables</code> commands and are also recognized by name. Currently, -vendor chains:</p> -<ul> -<li>Start with <code>oem_</code>.</li> -<li>Are used by current SOC and OEM implementations, e.g., chains starting in -<code>nm_</code> or <code>qcom_</code>.</li> -</ul> - -<h3 id="allowed-commands">Allowed commands</h3> -<p>Currently allowed commands are listed below. Restrictions are implemented via -a set of regular expressions on the executed command lines. For details, refer -to <code>system/netd/netutils_wrappers/NetUtilsWrapper-1.0.cpp</code>.</p> - -<h4 id="ip">ip</h4> -<p>The <code>ip</code> command is used to configure IP addresses, routing, IPsec -encryption, and a number of other network parameters. The wrapper allows the -following commands:</p> -<ul> -<li>Add and remove IP addresses from vendor-managed interfaces.</li> -<li>Configure IPsec encryption.</li> -</ul> - -<h4 id="iptables-ip6tables">iptables/ip6tables</h4> -<p>The <code>iptables</code> and <code>ip6tables</code> commands are used to -configure firewalling, packet mangling, NAT, and other per-packet processing. -The wrapper allows the following commands:</p> -<ul> -<li>Add and delete vendor chains.</li> -<li>Add and delete rules in any chain that refers to packets going into -(<code>-i</code>) or out of (<code>-o</code>) a vendor interface.</li> -<li>Jump to a vendor chain from any point in any other chain.</li> -</ul> - -<h4 id="ndc">ndc</h4> -<p><code>ndc</code> is used to communicate to the <code>netd</code> daemon that -performs most network configuration on Android. The wrapper allows the following -commands:</p> -<ul> -<li>Create and destroy OEM networks (<code>oemXX</code>).</li> -<li>Add vendor-managed interfaces to OEM networks.</li> -<li>Add routes to OEM networks.</li> -<li>Enable or disable IP forwarding globally and on vendor interfaces.</li> -</ul> - -<h4 id="tc">tc</h4> -<p>The <code>tc</code> command is used to configure traffic queueing and shaping -on vendor interfaces.</p> - - </body> -</html> diff --git a/en/devices/architecture/hidl/services.html b/en/devices/architecture/hidl/services.html deleted file mode 100644 index f441c8e2..00000000 --- a/en/devices/architecture/hidl/services.html +++ /dev/null @@ -1,236 +0,0 @@ -<html devsite> - <head> - <title>Services & Data Transfer</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 section describes how to register and discover services and how to send -data to a service by calling methods defined in interfaces in <code>.hal</code> -files.</p> - -<h2 id=register>Registering services</h2> -<p>HIDL interface servers (objects implementing the interface) can be registered -as named services. The registered name need not be related to the interface or -package name. If no name is specified, the name "default" is used; this should -be used for HALs that do not need to register two implementations of the same -interface. For example, the C++ call for service registration defined in each -interface is:</p> - -<pre class="prettyprint"> -status_t status = myFoo->registerAsService(); -status_t anotherStatus = anotherFoo->registerAsService("another_foo_service"); // if needed -</pre> - -<p>The version of a HIDL interface is included in the interface itself. It is -automatically associated with service registration and can be retrieved via a -method call (<code>android::hardware::IInterface::getInterfaceVersion()</code>) -on every HIDL interface. Server objects need not be registered and can be passed -via HIDL method parameters to another process that will make HIDL method calls -into the server.</p> - -<h2 id=discover>Discovering services</h2> -<p>Requests by client code are made for a given interface by name and by -version, calling <code>getService</code> on the desired HAL class:</p> - -<pre class="prettyprint"> -// C++ -sp<V1_1::IFooService> service = V1_1::IFooService::getService(); -sp<V1_1::IFooService> alternateService = V1_1::IFooService::getService("another_foo_service"); -// Java -V1_1.IFooService service = V1_1.IFooService.getService(true /* retry */); -V1_1.IFooService alternateService = V1_1.IFooService.getService("another", true /* retry */); -</pre> - -<p>Each version of a HIDL interface is treated as a separate interface. Thus, -<code>IFooService</code> version 1.1 and <code>IFooService</code> version 2.2 -can both be registered as "foo_service" and -<code>getService("foo_service")</code> on either interface gets the registered -service for that interface. This is why, in most cases, no name parameter needs -to be supplied for registration or discovery (meaning name "default").</p> - -<p>The Vendor Interface Object also plays a part in the transport method of the -returned interface. For an interface <code>IFoo</code> in package -<code>android.hardware.foo@1.0</code>, the returned interface by -<code>IFoo::getService</code> always use the transport method declared for -<code>android.hardware.foo</code> in the device manifest if the entry exists; -and if the transport method is not available, nullptr is returned.</p> - -<p> In some cases, it may be necessary to continue immediately even without -getting the service. This can happen (for instance) when a client wants to -manage service notifications itself or in a diagnostic program (such as -<code>atrace</code>) which needs to get all hwservices and retrieve them. In -this case, additional APIs are provided such as <code>tryGetService</code> in C++ or -<code>getService("instance-name", false)</code> in Java. The legacy API -<code>getService</code> provided in Java also must be used with service -notifications. Using this API does not avoid the race condition where a server -registers itself after the client requests it with one of these no-retry APIs.</p> - -<h2 id=death>Service death notifications</h2> -<p>Clients who want to be notified when a service dies can receive death -notifications delivered by the framework. To receive notifications, the client -must:</p> -<ol> -<li>Subclass the HIDL class/interface <code>hidl_death_recipient</code> (in C++ -code, not in HIDL).</li> -<li>Override its <code>serviceDied()</code> method.</li> -<li>Instantiate an object of the <code>hidl_death_recipient</code> subclass. -</li> -<li>Call the <code>linkToDeath()</code> method on the service to monitor, -passing in the <code>IDeathRecipient</code>'s interface object. Note that this -method does not take ownership of the death recipient or the proxy on which it -is called.</li> -</ol> - -<p>A pseudocode example (C++ and Java are similar):</p> - -<pre class="prettyprint"> -class IMyDeathReceiver : hidl_death_recipient { - virtual void serviceDied(uint64_t cookie, - wp<IBase>& service) override { - log("RIP service %d!", cookie); // Cookie should be 42 - } -}; -.... -IMyDeathReceiver deathReceiver = new IMyDeathReceiver(); -m_importantService->linkToDeath(deathReceiver, 42); -</pre> - -<p>The same death recipient may be registered on multiple different services. -</p> - -<h2 id=data-transwer>Data transfer</h2> -<p>Data may be sent to a service by calling methods defined in interfaces in -<code>.hal</code> files. There are two kinds of methods:</p> - -<ul> -<li><strong>Blocking</strong> methods wait until the server has produced a -result.</li> -<li><strong>Oneway</strong> methods send data in only one direction and do not -block. If the amount of data in-flight in RPC calls exceeds implementation -limits, the calls may either block or return an error indication (behavior is -not yet determined).</li> -</ul> - -<p>A method that does not return a value but is not declared as -<code>oneway</code> is still blocking.</p> - -<p>All methods declared in a HIDL interface are called in a single direction, -either from the HAL or into the HAL. The interface does not specify which -direction it will be called in. Architectures that need calls to originate from -the HAL should provide two (or more) interfaces in the HAL package and serve the -appropriate interface from each process. The words <em>client</em> and -<em>server</em> are used with respect to the calling direction of the interface -(i.e. the HAL can be a server of one interface and a client of another -interface).</p> - -<h3 id=callbacks>Callbacks</h3> -<p>The word <em>callback</em> refers to two different concepts, distinguished by -<em>synchronous callback</em> and <em>asynchronous callback</em>.</p> - -<p><em>Synchronous callbacks</em> are used in some HIDL methods that return -data. A HIDL method that returns more than one value (or returns one value of -non-primitive type) returns its results via a callback function. If only one -value is returned and it is a primitive type, a callback is not used and the -value is returned from the method. The server implements the HIDL methods and -the client implements the callbacks.</p> - -<p><em>Asynchronous callbacks</em> allow the server of a HIDL interface to -originate calls. This is done by passing an instance of a second interface -through the first interface. The client of the first interface must act as the -server of the second. The server of the first interface can call methods on the -second interface object. For example, a HAL implementation may send information -asynchronously back to the process that is using it by calling methods on an -interface object created and served by that process. Methods in interfaces used -for asynchronous callback may be blocking (and may return values to the caller) -or <code>oneway</code>. For an example, see "Asynchronous callbacks" in -<a href="/devices/architecture/hidl-cpp/interfaces.html">HIDL C++</a>.</p> - -<p>To simplify memory ownership, method calls and callbacks take only -<code>in</code> parameters and do not support <code>out</code> or -<code>inout</code> parameters.</p> - -<h3 id=limits>Per-transaction limits</h3> -<p>Per-transaction limits are not imposed on the amount of data sent in HIDL -methods and callbacks. However, calls exceeding 4KB per transaction are -considered excessive. If this is seen, re-architecting the given HIDL interface -is recommended. Another limitation is the resources available to the HIDL -infrastructure to handle multiple simultaneous transactions. Multiple -transactions can be in-flight simultaneously due to multiple threads or -processes sending calls to a process or multiple <code>oneway</code> calls that -are not handled quickly by the receiving process. The maximum total space -available for all concurrent transactions is 1MB by default.</p> - -<p>In a well-designed interface, exceeding these resource limitations should not -happen; if it does, the call which exceeded them may either block until -resources become available or signal a transport error. Each occurrence of -exceeding per-transaction limits or overflowing HIDL implementation resources by -aggregate in-flight transactions is logged to facilitate debugging.</p> - -<h3 id=method-implement>Method implementations</h3> -<p>HIDL generates header files declaring the necessary types, methods, and -callbacks in the target language (C++ or Java). The prototype of HIDL-defined -methods and callbacks is the same for both client and server code. The HIDL -system provides <strong>proxy</strong> implementations of the methods on the -caller side that organize the data for IPC transport, and <strong>stub</strong> -code on the callee side that passes the data into developer implementations of -the methods.</p> - -<p>The caller of a function (HIDL method or callback) has ownership of the data -structures passed into the function, and retains ownership after the call; in -all cases the callee does not need to free or release the storage.</p> - -<ul> -<li>In C++, the data may be read-only (attempts to write to it may cause a -segmentation fault) and are valid for the duration of the call. The client can -deep-copy the data to propagate it beyond the call.</li> -<li>In Java, the code receives a local copy of the data (a normal Java object), -which it may keep and modify or allow to be garbage-collected.</li> -</ul> - -<h3 id=non-rpc>Non-RPC data transfer</h3> -<p>HIDL has two ways to transfer data without using an RPC call: shared -memory and a Fast Message Queue (FMQ), both supported only in C++.</p> - -<ul> -<li><strong>Shared memory</strong>. The built-in HIDL type <code>memory</code> -is used to pass an object representing shared memory that has been allocated. -Can be used in a receiving process to map the shared memory.</li> -<li><strong>Fast Message Queue (FMQ)</strong>. HIDL provides a templated message -queue type that implements no-wait message-passing. It does not use the kernel -or scheduler in passthrough or binderized mode (inter-device communication will -not have these properties). Typically, the HAL sets up its end of the queue, -creating an object that can be passed through RPC via a parameter of built-in -HIDL type <code>MQDescriptorSync</code> or <code>MQDescriptorUnsync</code>. This -object can be used by the receiving process to set up the other end of the queue. -<ul> -<li><em>Sync</em> queues are not allowed to overflow, and can only have one -reader.</li> -<li><em>Unsync</em> queues are allowed to overflow, and can have many readers, -each of which must read data in time or lose it.</li> -</ul> -Neither type is allowed to underflow (read from an empty queue will fail), and -each type can only have one writer.</li></ul> - -<p>For more details on FMQ, see -<a href="/devices/architecture/hidl/fmq.html">Fast Message Queue (FMQ)</a>.</p> - - </body> -</html> diff --git a/en/devices/architecture/hidl/threading.html b/en/devices/architecture/hidl/threading.html deleted file mode 100644 index fef555ad..00000000 --- a/en/devices/architecture/hidl/threading.html +++ /dev/null @@ -1,178 +0,0 @@ -<html devsite> - <head> - <title>Threading Models</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>Methods marked as <code>oneway</code> do not block. For methods not marked as -<code>oneway</code>, a client's method call will block until the server has -completed execution or called a synchronous callback (whichever comes first). -Server method implementations may call at most one synchronous callback; extra -callback calls are discarded and logged as errors. If a method is supposed to -return values via callback and does not call its callback, this is logged as an -error and reported as a transport error to the client.</p> - -<h2 id=passthrough>Threads in passthrough mode</h2> -<p>In passthrough mode, most calls are synchronous. However, to preserve the -intended behavior that <code>oneway</code> calls do not block the client, a -thread is created for each process. For details, see the -<a href="/devices/architecture/hidl/index.html#passthrough">HIDL overview</a>. -</p> - -<h2 id=binderized>Threads in binderized HALs</h2> -<p>To serve incoming RPC calls (including asynchronous callbacks from HALs to -HAL users) and death notifications, a threadpool is associated with each process -that uses HIDL. If a single process implements multiple HIDL interfaces and/or -death notification handlers, its threadpool is shared between all of them. When -a process receives an incoming method call from a client, it picks a free thread -from the threadpool and executes the call on that thread. If no free thread is -available, it blocks until one is available.</p> - -<p>If the server has only one thread, then calls into the server are completed -in order. A server with more than one thread may complete calls out of order -even if the client has only one thread. However, for a given interface object, -<code>oneway</code> calls are guaranteed to be ordered (see -<a href="#model">Server threading model</a>). For a multi-threaded server that -hosts multiple interfaces, <code>oneway</code> calls to different interfaces -may be processed concurrently with each other or other blocking calls.</p> - -<p>Multiple nested calls will be sent on the same hwbinder thread. For instance, -if a process (A) makes a synchronous call from a hwbinder thread into process (B), -and then process (B) makes a synchronous call back into process (A), the call will -be executed on the original hwbinder thread in (A) which is blocked on the original -call. This optimization makes it possible to have a single threaded server able to -handle nested calls, but it does not extend to cases where the calls travel through -another sequence of IPC calls. For instance, if process (B) had made a -binder/vndbinder call which called into a process (C) and then process (C) calls -back into (A), it cannot be served on the original thread in (A).</p> - -<h2 id=model>Server threading model</h2> -<p>Except for passthrough mode, server implementations of HIDL interfaces live -in a different process than the client and need one or more threads waiting for -incoming method calls. These threads are the server's threadpool; the server may -decide how many threads it wants running in its threadpool, and can use a -threadpool size of one to serialize all calls on its interfaces. If the server -has more than one thread in the threadpool, it can receive concurrent incoming -calls on any of its interfaces (in C++, this means that shared data must be -carefully locked).</p> - -<p>Oneway calls into the same interface are serialized. If a multi-threaded -client calls <code>method1</code> and <code>method2</code> on interface -<code>IFoo</code>, and <code>method3</code> on interface <code>IBar</code>, -<code>method1</code> and <code>method2</code> will always be serialized, but -<code>method3</code> may run in parallel with <code>method1</code> and -<code>method2</code>.</p> - -<p>A single client thread of execution can cause concurrent execution on a -server with multiple threads in two ways:</p> - -<ul> -<li><code>oneway</code> calls do not block. If a <code>oneway</code> call is -executed and then a non-<code>oneway</code> is called, the server may execute -the <code>oneway</code> call and the non-<code>oneway</code> call -simultaneously.</li> -<li>Server methods that pass data back with synchronous callbacks can unblock -the client as soon as the callback is called from the server.</li> -</ul> - -<p>For the second way, any code in the server function that executes after the -callback is called may execute concurrently, with the server handling subsequent -calls from the client. This includes code in the server function and automatic -destructors that execute at the end of the function. If the server has more than -one thread in its threadpool, concurrency issues arise even if calls are coming -in from only one single client thread. (If any HAL served by a process needs -multiple threads, all HALs will have multiple threads because the threadpool is -shared per-process.)</p> - -<p>As soon as the server calls the provided callback, the transport can call the -implemented callback on the client and unblock the client. The client proceeds -in parallel with whatever the server implementation does after it calls the -callback (which may include running destructors). Code in the server function -after the callback is no longer blocking the client (as long as the server -threadpool has enough threads to handle incoming calls), but may be executed -concurrently with future calls from the client (unless the server threadpool has -only one thread).</p> - -<p>In addition to synchronous callbacks, <code>oneway</code> calls from a -single-threaded client may be handled concurrently by a server with multiple -threads in its threadpool, but only if those <code>oneway</code> calls are -executed on different interfaces. <code>oneway</code> calls on the same -interface are always serialized.</p> - -<p class=note><strong>Note:</strong> We strongly encourage server functions to -return as soon as they have called the callback function.</p> - -<p>For example (in C++):</p> - -<pre class="prettyprint"> -Return<void> someMethod(someMethod_cb _cb) { - // Do some processing, then call callback with return data - hidl_vec<uint32_t> vec = ... - _cb(vec); - // At this point, the client's callback will be called, - // and the client will resume execution. - ... - return Void(); // is basically a no-op -}; -</pre> - -<h2 id=client>Client threading model</h2> -<p>The threading model on the client differs between non-blocking calls -(functions that are marked with the <code>oneway</code> keyword) and blocking -calls (functions that do not have the <code>oneway</code> keyword specified).</p> - -<h3 id=block>Blocking calls</h3> -<p>For blocking calls, the client blocks until one of the following happens:</p> - -<ul> -<li>Transport error occurs; the <code>Return</code> object contains an error -state that can be retrieved with <code>Return::isOk()</code>.</li> -<li>Server implementation calls the callback (if there was one).</li> -<li>Server implementation returns a value (if there was no callback parameter). -</li> -</ul> - -<p>In case of success, the callback function the client passes as an argument is -always called by the server before the function itself returns. The callback is -executed on the same thread that the function call is made on, so implementers -must be careful with holding locks during function calls (and avoid them -altogether when possible). A function without a <code>generates</code> statement -or a <code>oneway</code> keyword is still blocking; the client blocks until the -server returns a <code>Return<void></code> object.</p> - -<h3 id=oneway>Oneway calls</h3> -<p>When a function is marked <code>oneway</code>, the client returns immediately -and does not wait for the server to complete its function call invocation. At the -surface (and in aggregate), this means the function call takes half the -time because it is executing half the code, but when writing implementations that -are performance sensitive, this has some scheduling implications. Normally, -using a oneway call causes the caller to continue to be scheduled whereas -using a normal synchronous call causes the scheduler to immediately transfer -from the caller to the callee process. This is a performance optimization in -binder. For services where the oneway call must be executed in the target process -with a high priority, the scheduling policy of the receiving service can be -changed. In C++, using <code>libhidltransport</code>'s method -<code>setMinSchedulerPolicy</code> with the scheduler priorities and policies -defined in <code>sched.h</code> ensures that all calls into the service run at -least at the set scheduling policy and priority.</p> - - </body> -</html> diff --git a/en/devices/architecture/hidl/types.html b/en/devices/architecture/hidl/types.html deleted file mode 100644 index 943d355e..00000000 --- a/en/devices/architecture/hidl/types.html +++ /dev/null @@ -1,410 +0,0 @@ -<html devsite> - <head> - <title>Data Types</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 section describes HIDL data types. For implementation details, see -<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a> (for C++ -implementations) or <a href="/devices/architecture/hidl-java/index.html">HIDL -Java</a> (for Java implementations).</p> - -<p>Similarities to C++ include:</p> -<ul> -<li><code>structs</code> use C++ syntax; <code>unions</code> support C++ syntax -by default. Both must be named; anonymous structs and unions are not supported. -</li> -<li>Typedefs are allowed in HIDL (as they are in C++).</li> -<li>C++-style comments are allowed and are copied to the generated header file. -</li> -</ul> - -<p>Similarities to Java include:</p> -<ul> -<li>For each file, HIDL defines a Java-style namespace that must begin with -<code>android.hardware.</code>. The generated C++ namespace is -<code>::android::hardware::…</code>.</li> -<li>All definitions of the file are contained within a Java-style -<code>interface</code> wrapper.</li> -<li>HIDL array declarations follow the Java style, not the C++ style. Example: -<pre class="prettyprint"> -struct Point { - int32_t x; - int32_t y; -}; -Point[3] triangle; // sized array -</pre> -</li> -<li>Comments are similiar to the javadoc format.</li> -</ul> - -<h2 id=represent>Data representation</h2> -<p>A <code>struct</code> or <code>union</code> composed of -<a href="http://en.cppreference.com/w/cpp/language/data_members#Standard_layout">Standard-Layout</a> -(a subset of the requirement of plain-old-data types) has a consistent memory -layout in generated C++ code, enforced with explicit alignment attributes on -<code>struct</code> and <code>union</code> members.</p> - -<p>Primitive HIDL types, as well as <code>enum</code> and <code>bitfield</code> -types (which always derive from primitive types), map to standard C++ types -such as <code>std::uint32_t</code> from -<a href="http://en.cppreference.com/w/cpp/types/integer">cstdint</a>.</p> - -<p>As Java does not support unsigned types, unsigned HIDL types are mapped to -the corresponding signed Java type. <em>Structs</em> map to Java classes; -<em>arrays</em> map to Java arrays; <em>unions</em> are not currently supported -in Java. <em>Strings</em> are stored internally as UTF8. Since Java supports -only UTF16 strings, string values sent to or from a Java implementation are -translated, and may not be identical on re-translation as the character sets do -not always map smoothly.</p> - -<p>Data received over IPC in C++ is marked <code>const</code> and is in -read-only memory that persists only for the duration of the function call. Data -received over IPC in Java has already been copied into Java objects, so it can -be retained without additional copying (and may be modified).</p> - -<h2 id=annotations>Annotations</h2> -<p>Java-style annotations may be added to type declarations. Annotations are -parsed by the Vendor Test Suite (VTS) backend of the HIDL compiler but none of -such parsed annotations are actually understood by the HIDL compiler. Instead, -parsed VTS annotations are handled by the VTS Compiler (VTSC).</p> - -<p>Annotations use Java syntax: <code>@annotation</code> or -<code>@annotation(value)</code> or <code>@annotation(id=value, id=value…)</code> -where value may be either a constant expression, a string, or a list of values -inside <code>{}</code>, just as in Java. Multiple annotations of the same name -can be attached to the same item.</p> - -<h2 id=forward>Forward declarations</h2> -<p>In HIDL, structs may not be forward-declared, making user-defined, -self-referential data types impossible (e.g., you cannot describe a linked list -or a tree in HIDL). Most existing (pre-Android 8.x) HALs have limited use of -forward declarations, which can be removed by rearranging data structure -declarations.</p> - -<p>This restriction allows data structures to be copied by-value with a simple -deep-copy, rather than keeping track of pointer values that may occur multiple -times in a self-referential data structure. If the same data is passed twice, -such as with two method parameters or <code>vec<T></code>s that point to -the same data, two separate copies are made and delivered.</p> - -<h2 id=nested>Nested declarations</h2> -<p>HIDL supports nested declarations to as many levels as desired (with one -exception noted below). For example:</p> - -<pre class="prettyprint"> -interface IFoo { - uint32_t[3][4][5][6] multidimArray; - - vec<vec<vec<int8_t>>> multidimVector; - - vec<bool[4]> arrayVec; - - struct foo { - struct bar { - uint32_t val; - }; - bar b; - } - struct baz { - foo f; - foo.bar fb; // HIDL uses dots to access nested type names - } - … -</pre> - -<p>The exception is that interface types can only be embedded in -<code>vec<T></code> and only one level deep (no -<code>vec<vec<IFoo>></code>).</p> - -<h2 id=raw-pointer>Raw pointer syntax</h2> -<p>The HIDL language does not use <strong>*</strong> and does not support the -full flexibility of C/C++ raw pointers. For details on how HIDL encapsulates -pointers and arrays/vectors, see <a href="#vec">vec<T> template</a>.</p> - -<h2 id=interfaces>Interfaces</h2> -<p>The <code>interface</code> keyword has two usages.</p> - -<ul> -<li>It opens the definition of an interface in a .hal file.</li> -<li>It can be used as a special type in struct/union fields, method parameters, -and returns. It is viewed as a general interface and synonym to -<code>android.hidl.base@1.0::IBase</code>.</li> -</ul> - -<p>For example, <code>IServiceManager</code> has the following method:</p> -<pre class="prettyprint"> -get(string fqName, string name) generates (interface service); -</pre> - -<p>The method promises to lookup <em>some interface</em> by name. It is also -identical to replace interface with <code>android.hidl.base@1.0::IBase</code>. -</p> - -<p>Interfaces can be only passed in two ways: as top-level parameters, or as -members of a <code>vec<IMyInterface></code>. They cannot be members of -nested vecs, structs, arrays, or unions.</p> - -<h2 id=mqdescriptor>MQDescriptorSync & MQDescriptorUnsync</h2> -<p>The <code>MQDescriptorSync</code> and <code>MQDescriptorUnsync</code> types -pass a synchronized or unsynchronized Fast Message Queue (FMQ) descriptors -across a HIDL interface. For details, see -<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a> (FMQs are not -supported in Java).</p> - -<h2 id=memory>memory type</h2> -<p>The <code>memory</code> type is used to represent unmapped shared memory in -HIDL. It is only supported in C++. A value of this type can be used on the -receiving end to initialize an <code>IMemory</code> object, mapping the memory -and making it usable. For details, see -<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++</a>.</p> - -<p class=warning><strong>Warning:</strong> Structured data placed in shared -memory MUST be a type whose format will never change for the lifetime of the -interface version passing the <code>memory</code>. Otherwise, HALs may suffer -fatal compatibility problems.</p> - -<h2 id=pointer>pointer type</h2> -<p>The <code>pointer</code> type is for HIDL internal use only.</p> - -<h2 id=bitfield>bitfield<T> type template</h2> -<p><code>bitfield<T></code> in which <code>T</code> is a -<a href="#enum">user-defined enum</a> suggests the value is a bitwise-OR of the -enum values defined in <code>T</code>. In generated code, -<code>bitfield<T></code> appears as the underlying type of T. For -example:</p> - -<pre class="prettyprint"> -enum Flag : uint8_t { - HAS_FOO = 1 << 0, - HAS_BAR = 1 << 1, - HAS_BAZ = 1 << 2 -}; -typedef bitfield<Flag> Flags; -setFlags(Flags flags) generates (bool success); -</pre> - -<p>The compiler handles the type Flags the same as <code>uint8_t</code>.</p> - -<p>Why not use -<code>(u)int8_t</code>/<code>(u)int16_t</code>/<code>(u)int32_t</code>/<code>(u)int64_t</code>? -Using <code>bitfield</code> provides additional HAL information to the reader, -who now knows that <code>setFlags</code> takes a bitwise-OR value of Flag (i.e. -knows that calling <code>setFlags</code> with 16 is invalid). Without -<code>bitfield</code>, this information is conveyed only via documentation. In -addition, VTS can actually check if the value of flags is a bitwise-OR of Flag. -</p> - -<h2 id=handle-primitive>handle primitive type</h2> - -<p class=warning><strong>WARNING:</strong> Addresses of any kind (even physical -device addresses) must never be part of a native handle. Passing this -information between processes is dangerous and makes them susceptible to attack. -Any values passed between processes must be validated before they are used to -look up allocated memory within a process. Otherwise, bad handles may cause bad -memory access or memory corruption.</p> - -<p>HIDL semantics are copy-by-value, which implies that parameters are copied. -Any large pieces of data, or data that needs to be shared between processes -(such as a sync fence), are handled by passing around file descriptors pointing -to persistent objects: <code>ashmem</code> for shared memory, actual files, or -anything else that can hide behind a file descriptor. The binder driver -duplicates the file descriptor into the other process.</p> - -<h3 id=handle_t>native_handle_t</h3> -<p>Android supports <code>native_handle_t</code>, a general handle concept -defined in <code>libcutils</code>.</p> - -<pre class="prettyprint"> -typedef struct native_handle -{ - int version; /* sizeof(native_handle_t) */ - int numFds; /* number of file-descriptors at &data[0] */ - int numInts; /* number of ints at &data[numFds] */ - int data[0]; /* numFds + numInts ints */ -} native_handle_t; -</pre> - -<p>A native handle is a collection of ints and file descriptors that gets passed -around by value. A single file descriptor can be stored in a native handle with -no ints and a single file descriptor. Passing handles using native handles -encapsulated with the <code>handle</code> primitive type ensures that native -handles are directly included in HIDL.</p> - -<p>As a <code>native_handle_t</code> has variable size, it cannot be included -directly in a struct. A handle field generates a pointer to a separately -allocated <code>native_handle_t</code>.</p> - -<p>In earlier versions of Android, native handles were created using the same -functions present in -<a href="https://android.googlesource.com/platform/system/core/+/master/libcutils/native_handle.c">libcutils</a>. -In Android 8.0 and higher, these functions are now copied to the -<code>android::hardware::hidl</code> namespace or moved to the NDK. HIDL -autogenerated code serializes and deserializes these functions automatically, -without involvement from user-written code.</p> - -<h3 id=ownership>Handle and file descriptor ownership</h3> -<p>When you call a HIDL interface method that passes (or returns) a -<code>hidl_handle</code> object (either top-level or part of a compound type), -the ownership of the file descriptors contained in it is as follows:</p> - -<ul> -<li>The <strong>caller</strong> passing a <code>hidl_handle</code> object as an -argument retains ownership of the file descriptors contained in the -<code>native_handle_t</code> it wraps; the caller must close these file -descriptors when it is done with them.</li> -<li>The <strong>process</strong> returning a <code>hidl_handle</code> -object (by passing it into a <code>_cb</code> function) retains ownership of the -file descriptors contained in the <code>native_handle_t</code> wrapped by the -object; the process must close these file descriptors when it is done with them. -</li> -<li>A <strong>transport</strong> that receives a <code>hidl_handle</code> has -ownership of the file descriptors inside the <code>native_handle_t</code> -wrapped by the object; the receiver can use these file descriptors as-is during -the transaction callback, but must clone the native handle to use the file -descriptors beyond the callback. The transport will automatically -<code>close()</code> the file descriptors when the transaction is done.</li> -</ul> - -<p>HIDL does not support handles in Java (as Java doesn't support handles at -all).</p> - -<h2 id=sized-arrays>Sized arrays</h2> -<p>For sized arrays in HIDL structs, their elements can be of any type a struct -can contain:</p> - -<pre class="prettyprint"> -struct foo { -uint32_t[3] x; // array is contained in foo -}; -</pre> - -<h2 id=strings>Strings</h2> -<p>Strings appear differently in C++ and Java, but the underlying transport -storage type is a C++ structure. For details, see -<a href="/devices/architecture/hidl-cpp/types.html">HIDL C++ Data Types</a> or -<a href="/devices/architecture/hidl-java/types.html">HIDL Java Data Types</a>. -</p> - -<p class=note><strong>Note:</strong> Passing a string to or from Java through a -HIDL interface (including Java to Java) will cause character set conversions -that may not exactly preserve the original encoding.</p> - -<h2 id=vec>vec<T> type template</h2> -<p>The <code>vec<T></code> template represents a variable-sized buffer -containing instances of <code>T</code>. <code>T</code> can be any HIDL-provided -or user-defined type except handle. (A <code>vec<></code> of -<code>vec<T></code> will point to an array of the -<code>vec<T></code> structs, not an array of the inner T buffers.)</p> - -<p><code>T</code> can be one of the following:</p> -<ul> -<li>Primitive types (e.g. uint32_t)</li> -<li>Strings</li> -<li>User-defined enums</li> -<li>User-defined structs</li> -<li>Interfaces, or the <code>interface</code> keyword -(<code>vec<IFoo></code>, <code>vec<interface></code> is supported -only as a top-level parameter)</li> -<li>Handles</li> -<li>bitfield<U></li> -<li>vec<U>, where U is in this list except interface (e.g. -<code>vec<vec<IFoo>></code> is not supported)</li> -<li>U[] (sized array of U), where U is in this list except interface</li> -</ul> - -<h2 id=user>User-defined types</h2> -<p>This section describes user-defined types.</p> - -<h3 id=enum>Enum</h3> -<p>HIDL does not support anonymous enums. Otherside, enums in HIDL are similar -to C++11:</p> -<pre class="prettyprint"> -enum name : type { enumerator , enumerator = constexpr , … } -</pre> - -<p>Enums are defined in terms of one of the primitive types in HIDL, or as an -extension of other enums. For example:</p> -<pre class="prettyprint"> -enum Color : uint32_t { RED = 0, GREEN, BLUE = 2 } // GREEN == 1 -</pre> - -<p>Values of enums are referred to with the colon syntax (not dot syntax as -nested types). The syntax is <code>Type:VALUE_NAME</code>. No need to specify -type if the value is referred in the same enum type or child types. Example:</p> -<pre class="prettyprint"> -enum Grayscale : uint32_t { BLACK = 0, WHITE = BLACK + 1 }; -enum Color : Grayscale { RED = WHITE + 1 }; -enum Unrelated : uint32_t { FOO = Color:RED + 1 }; -</pre> - -<h3 id=struct>Struct</h3> -<p>HIDL does not support anonymous structs. Otherwise, structs in HIDL are very -similar to C.</p> - -<p>HIDL does not support variable-length data structures contained wholly within -a struct. This includes the indefinite-length array that is sometimes used as -the last field of a struct in C/C++ (sometimes seen with a size of -<code>[0]</code>). HIDL <code>vec<T></code> represents dynamically-sized -arrays with the data stored in a separate buffer; such instances are represented -with an instance of the <code>vec<T></code> in the <code>struct</code>. -</p> - -<p>Similarly, <code>string</code> can be contained in a <code>struct</code> -(associated buffers are separate). In the generated C++, instances of the HIDL -handle type are represented via a pointer to the actual native handle as -instances of the underlying data type are variable-length.</p> - -<h3 id=union>Union</h3> -<p>HIDL does not support anonymous unions. Otherwise, unions are similar to C. -</p> - -<p>Unions cannot contain fix-up types (pointers, file descriptors, binder -objects, etc.). They do not need special fields or associated types and are -simply copied via <code>memcpy()</code> or equivalent. An union may not directly -contain (or contain via other data structures) anything that requires setting -binder offsets (i.e., handle or binder-interface references). For example:</p> - -<pre class="prettyprint"> -union UnionType { -uint32_t a; -// vec<uint32_t> r; // Error: can't contain a vec<T> -uint8_t b;1 -}; -fun8(UnionType info); // Legal -</pre> - -<p>Unions can also be declared inside of structs. For example:</p> -<pre class="prettyprint"> -struct MyStruct { - union MyUnion { - uint32_t a; - uint8_t b; - }; // declares type but not member - - union MyUnion2 { - uint32_t a; - uint8_t b; - } data; // declares type but not member - } -</pre> - - </body> -</html> diff --git a/en/devices/architecture/hidl/versioning.html b/en/devices/architecture/hidl/versioning.html deleted file mode 100644 index fe4ec95d..00000000 --- a/en/devices/architecture/hidl/versioning.html +++ /dev/null @@ -1,703 +0,0 @@ -<html devsite> - <head> - <title>Versioning</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 requires every interface written in HIDL be versioned. After a HAL -interface is published, it is frozen and any further changes must be made to a -new version of that interface. While a given published interface may not be -modified, it can be extended by another interface.</p> - -<h2 id=code-structure>HIDL code structure</h2> - -<p> -<a href="/reference/hidl/index.html">HIDL code is organized</a> in user-defined -types, interfaces, and packages:</p> - -<ul> -<li><strong>User-defined types (UDTs)</strong>. HIDL provides access to a set of -primitive data types that can be used to compose more complex types via -structures, unions, and enumerations</a>. UDTs are passed to methods of -interfaces, and can be defined at the level of a package (common to all -interfaces) or locally to an interface.</li> -<li><strong>Interfaces</strong>. As a basic building block of HIDL, an interface -consists of UDT and method declarations. Interfaces can also inherit from -another interface.</li> -<li><strong>Packages</strong>. Organizes related HIDL interfaces and the data -types on which they operate. A package is identified by a name and a version and -includes the following: -<ul> - <li>Data-type definition file called <code>types.hal</code>.</li> - <li>Zero or more interfaces, each in their own <code>.hal</code> file.</li> -</ul> -</li> -</ul> - -<p>The data-type definition file <code>types.hal</code> contains only UDTs (all -package-level UDTs are kept in a single file). Representations in the target -language are available to all interfaces in the package.</p> - -<h2 id=philosophy>Versioning philosophy</h2> -<p>A HIDL package (such as <code>android.hardware.nfc</code>), after being -published for a given version (such as <code>1.0</code>), is immutable; it -cannot be changed. Modifications to the interfaces in the package or any -changes to its UDTs can take place only in <em>another</em> package.</p> - -<p>In HIDL, versioning applies at the package level, not at the interface level, -and all interfaces and UDTs in a package share the same version. Package -versions follow <a href="http://semver.org/" class="external">semantic -versioning</a> without the patch level and build-metadata components. Within a -given package, a <strong>minor version</strong> bump implies the new version of -the package is backwards-compatible with the old package and a <strong>major -version</strong> bump implies the new version of the package is not -backwards-compatible with the old package.</p> - -<p>Conceptually, a package can relate to another package in one of several ways: -</p> - -<ul> -<li><strong>Not at all</strong>.</li> -<li><strong>Package-level backwards-compatible extensibility</strong>. This -occurs for new minor-version uprevs (next incremented revision) of a package; -the new package has the same name and major version as the old package, but a -higher minor version. Functionally, the new package is a superset of the old -package, meaning: -<ul> - <li>Top-level interfaces of the parent package are present in the new package, - though the interfaces may have new methods, new interface-local UDTs (the - interface-level extension described below), and new UDTs in - <code>types.hal</code>.</li> - <li>New interfaces may also be added to the new package.</li> - <li>All data types of the parent package are present in the new package and - can be handled by the (possibly reimplemented) methods from the old package. - </li> - <li>New data types may also be added for use by either new methods of uprev'ed - existing interfaces, or by new interfaces.</li> -</ul> -</li> - -<li><strong>Interface-level backwards-compatible extensibility</strong>. The new -package can also extend the original package by consisting of logically separate -interfaces that simply provide additional functionality, and not the core one. -For this purpose, the following may be desirable: -<ul> - <li>Interfaces in the new package need recourse to the data types of the old - package.</li> - <li>Interfaces in new package may extend interfaces of one or more old - packages.</li> -</ul> -</li> -<li><strong>Extend the original backwards-incompatibility</strong>. This is a -major-version uprev of the package and there need not be any correlation between -the two. To the extent that there is, it can be expressed with a combination of -types from the older version of the package, and inheritance of a subset of -old-package interfaces.</li> -</ul> - -<h2 id=structuring>Structuring interfaces</h2> - -<p>For a well structured interface, adding new types of functionality that -are not part of the original design should require a modification to the HIDL -interface. Conversely, if you can or expect to make a change on both sides of -the interface that introduces new functionality without changing the interface -itself, then the interface is not structured.</p> - -<p>Treble supports separately-compiled vendor and system components in which the -<code>vendor.img</code> on a device and the <code>system.img</code> can be -compiled separately. All interactions between <code>vendor.img</code> and -<code>system.img</code> must be explicitly and thoroughly defined so they can -continue to work for many years. This includes many API surfaces, but a major -surface is the IPC mechanism HIDL uses for interprocess communication on the -<code>system.img</code>/<code>vendor.img</code> boundary.</p> - -<h3 id="structuring-requirements">Requirements</h3> -<p>All data passed through HIDL must be explicitly defined. To ensure an -implementation and client can continue to work together even when compiled -separately or developed on independently, data must adhere to the following -requirements:</p> - -<ul> -<li>Can be described in HIDL directly (using structs enums, etc.) with -semantic names and meaning.</li> -<li>Can be described by a public standard such as ISO/IEC 7816.</li> -<li>Can be described by a hardware standard or physical layout of hardware.</li> -<li>Can be opaque data (such as public keys, ids, etc.) if necessary.</li> -</ul> - -<p>If opaque data is used, it must be read only by one side of the HIDL -interface. For example, if <code>vendor.img</code> code gives a component on the -<code>system.img</code> a string message or <code>vec<uint8_t></code> -data, that data cannot be parsed by the <code>system.img</code> itself; it can -only be passed back to <code>vendor.img</code> to interpret. <strong>When -passing a value from <code>vendor.img</code> to vendor code on -<code>system.img</code> or to another device, the format of the data and how it -is to be interpreted must be exactly described and is still part of the -interface</strong>.</p> - -<h3 id="structuring-guidelines">Guidelines</h3> - -<p>You should be able to write an implementation or client of a HAL using only -the .hal files (i.e. you should not need to look at the Android source or public -standards). We recommend specifying the exact required behavior. Statements such -as "an implementation may do A or B" encourage implementations to become -intertwined with the clients they are developed with.</p> - -<h2 id=code-layout>HIDL code layout</h2> -<p>HIDL includes core and vendor packages.</p> - -<p>Core HIDL interfaces are those specified by Google. The packages they belong -to start with <code>android.hardware.</code> and are named by subsystem, -potentially with nested levels of naming. For example, the NFC package is named -<code>android.hardware.nfc</code> and the camera package is -<code>android.hardware.camera</code>. In general, a core package has the name -<code>android.hardware.</code>[<code>name1</code>].[<code>name2</code>]…. -HIDL packages have a version in addition to their name. For example, the package -<code>android.hardware.camera</code> may be at version <code>3.4</code>; this is -important, as the version of a package affects its placement in the source tree. -</p> - -<p>All core packages are placed under <code>hardware/interfaces/</code> in the -build system. The package -<code>android.hardware.</code>[<code>name1</code>].[<code>name2</code>]… -at version <code>$m.$n</code> is under -<code>hardware/interfaces/name1/name2/</code>…<code>/$m.$n/</code>; package -<code>android.hardware.camera</code> version <code>3.4</code> is in directory -<code>hardware/interfaces/camera/3.4/.</code> A hard-coded mapping exists -between the package prefix <code>android.hardware.</code> and the path -<code>hardware/interfaces/</code>.</p> - -<p>Non-core (vendor) packages are those produced by the SoC vendor or ODM. The -prefix for non-core packages is <code>vendor.$(VENDOR).hardware.</code> where -<code>$(VENDOR)</code>refers to an SoC vendor or OEM/ODM. This maps to the path -<code>vendor/$(VENDOR)/interfaces</code> in the tree (this mapping is also -hard-coded).</p> - -<h2 id=fqn>Fully-qualified user-defined-type names</h2> -<p>In HIDL, every UDT has a fully-qualified name that consists of the UDT name, -the package name where the UDT is defined, and the package version. The -fully-qualified name is used only when instances of the type are declared and -not where the type itself is defined. For example, assume package -<code>android.hardware.nfc,</code> version <code>1.0</code> defines a struct -named <code>NfcData</code>. At the site of the declaration (whether in -<code>types.hal</code> or within an interface's declaration), the declaration -simply states:</p> - -<pre class="prettyprint"> -struct NfcData { - vec<uint8_t> data; -}; -</pre> - -<p>When declaring an instance of this type (whether within a data structure or -as a method parameter), use the fully-qualified type name:</p> - -<pre class="prettyprint">android.hardware.nfc@1.0::NfcData</pre> - -<p>The general syntax is -<code><var>PACKAGE</var>@<var>VERSION</var>::<var>UDT</var></code>, where:</p> - -<ul> -<li><code><var>PACKAGE</var></code> is the dot-separated name of a HIDL package -(e.g., <code>android.hardware.nfc</code>).</li> -<li><code><var>VERSION</var></code> is the dot-separated major.minor-version -format of the package (e.g., <code>1.0</code>).</li> -<li><code><var>UDT</var></code> is the dot-separated name of a HIDL UDT. -Since HIDL supports nested UDTs and HIDL interfaces can contain UDTs (a type of -nested declaration), dots are used to access the names.</li> -</ul> - -<p>For example, if the following nested declaration was defined in the common -types file in package <code>android.hardware.example</code> version -<code>1.0</code>:</p> - -<pre class="prettyprint"> -// types.hal -package android.hardware.example@1.0; -struct Foo { - struct Bar { - // … - }; - Bar cheers; -}; -</pre> - -<p>The fully-qualified name for <code>Bar</code> is -<code>android.hardware.example@1.0::Foo.Bar</code>. If, in addition to being in -the above package, the nested declaration were in an interface called -<code>IQuux</code>:</p> - -<pre class="prettyprint"> -// IQuux.hal -package android.hardware.example@1.0; -interface IQuux { - struct Foo { - struct Bar { - // … - }; - Bar cheers; - }; - doSomething(Foo f) generates (Foo.Bar fb); -}; -</pre> - -<p>The fully-qualified name for <code>Bar</code> is -<code>android.hardware.example@1.0::IQuux.Foo.Bar</code>.</p> - -<p>In both cases, <code>Bar</code> can be referred to as <code>Bar</code> only -within the scope of the declaration of <code>Foo</code>. At the package or -interface level, you must refer to <code>Bar</code> via <code>Foo</code>: -<code>Foo.Bar</code>, as in the declaration of method <code>doSomething</code> -above. Alternatively, you could declare the method more verbosely as:</p> - -<pre class="prettyprint"> -// IQuux.hal -doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb); -</pre> - -<h2 id=enumeration>Fully-qualified enumeration values</h2> -<p>If a UDT is an enum type, then each value of the enum type has a -fully-qualified name that starts with the fully-qualified name of the enum type, -followed by a colon, then followed by the name of the enum value. For example, -assume package <code>android.hardware.nfc,</code> version <code>1.0</code> -defines an enum type <code>NfcStatus</code>:</p> - -<pre class="prettyprint"> -enum NfcStatus { - STATUS_OK, - STATUS_FAILED -}; -</pre> - -<p>When referring to <code>STATUS_OK</code>, the fully qualified name is:</p> - -<pre class="prettyprint">android.hardware.nfc@1.0::NfcStatus:STATUS_OK</pre> - -<p>The general syntax is -<code><var>PACKAGE</var>@<var>VERSION</var>::<var>UDT</var>:<var>VALUE</var></code>, -where: - -<ul> -<li><code><var>PACKAGE</var>@<var>VERSION</var>::<var>UDT</var></code> is the -exact same fully qualified name for the enum type.</li> -<li><code><var>VALUE</var></code> is the value's name.</li> -</ul> - -<h2 id=auto-interference>Auto-inference rules</h2> -<p>A fully-qualified UDT name does not need to be specified. A UDT name can -safely omit the following:</p> -<ul> -<li>The package, e.g. <code>@1.0::IFoo.Type</code></li> -<li>Both package and version, e.g. <code>IFoo.Type</code></li> -</ul> - -<aside class="caution"><strong>Caution:</strong> UDT names missing a version but -specifying a package present are not allowed.</aside> - -<p>HIDL attempts to complete the name using auto-interference rules (lower rule -number means higher priority).</p> - -<h3 id=rule1>Rule 1</h3> -<p>If no package and version is provided, a local name lookup is attempted. -Example:</p> - -<pre class="prettyprint"> -interface Nfc { - typedef string NfcErrorMessage; - send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m); -}; -</pre> - -<p><code>NfcErrorMessage</code> is looked up locally, and the <code>typedef</code> -above it is found. <code>NfcData</code> is also looked up locally, but as it is -not defined locally, rule 2 and 3 are used. <code>@1.0::NfcStatus</code> -provides a version, so rule 1 does not apply.</p> - -<h3 id=rule2>Rule 2</h3> -<p>If rule 1 fails and a component of the fully-qualified name is missing -(package, version, or package and version), the component is autofilled with -information from the current package. The HIDL compiler then looks in the -current file (and all imports) to find the autofilled fully-qualified name. -Using the example above, assume the declaration of <code>ExtendedNfcData</code> -was made in the same package (<code>android.hardware.nfc</code>) at the same -version (<code>1.0</code>) as <code>NfcData</code>, as follows:</p> - -<pre class="prettyprint"> -struct ExtendedNfcData { - NfcData base; - // … additional members -}; -</pre> - -<p>The HIDL compiler fills out the package name and version name from the -current package to produce the fully-qualified UDT name -<code>android.hardware.nfc@1.0::NfcData</code>. As the name exists in the -current package (assuming it is imported properly), it is used for the -declaration.</p> - -<p>A name in the current package is imported only if one of the following is -true:</p> -<ul> -<li>It is imported explicitly with an <code>import</code> statement.</li> -<li>It is defined in <code>types.hal</code> in the current package</li> -</ul> - -<p>The same process is followed if <code>NfcData</code> was qualified by only -the version number:</p> - -<pre class="prettyprint"> -struct ExtendedNfcData { - // autofill the current package name (android.hardware.nfc) - @1.0::NfcData base; - // … additional members -}; -</pre> - -<h3 id=rule3>Rule 3</h3> -<p>If rule 2 fails to produce a match (the UDT is not defined in the current -package), the HIDL compiler scans for a match within all imported packages. -Using the above example, assume <code>ExtendedNfcData</code> is declared in -version <code>1.1</code> of package <code>android.hardware.nfc</code>, -<code>1.1</code> imports <code>1.0</code> as it should (see -<a href="#package-ext">Package-Level Extensions</a>), and the definition -specifies only the UDT name:</p> - -<pre class="prettyprint"> -struct ExtendedNfcData { - NfcData base; - // … additional members -}; -</pre> - -<p>The compiler looks for any UDT named <code>NfcData</code> and finds one in -<code>android.hardware.nfc</code> at version <code>1.0</code>, resulting in a -fully-qualified UDT of <code>android.hardware.nfc@1.0::NfcData</code>. If more -than one match is found for a given partially-qualified UDT, the HIDL compiler -throws an error.</p> - -<h3 id=rule-example>Example</h3> -<p>Using rule 2, an imported type defined in the current package is favored over -an imported type from another package:</p> - -<pre class="prettyprint"> -// hardware/interfaces/foo/1.0/types.hal -package android.hardware.foo@1.0; -struct S {}; - -// hardware/interfaces/foo/1.0/IFooCallback.hal -package android.hardware.foo@1.0; -interface IFooCallback {}; - -// hardware/interfaces/bar/1.0/types.hal -package android.hardware.bar@1.0; -typedef string S; - -// hardware/interfaces/bar/1.0/IFooCallback.hal -package android.hardware.bar@1.0; -interface IFooCallback {}; - -// hardware/interfaces/bar/1.0/IBar.hal -package android.hardware.bar@1.0; -import android.hardware.foo@1.0; -interface IBar { - baz1(S s); // android.hardware.bar@1.0::S - baz2(IFooCallback s); // android.hardware.foo@1.0::IFooCallback -}; -</pre> - -<ul> -<li><strong><code>S</code></strong> is interpolated as -<code>android.hardware.bar@1.0::S</code>, and is found in -<code>bar/1.0/types.hal</code> (because <code>types.hal</code> is automatically -imported).</li> -<li><strong><code>IFooCallback</code></strong> is interpolated as -<code>android.hardware.bar@1.0::IFooCallback</code> using rule 2, but it -cannot be found because <code>bar/1.0/IFooCallback.hal</code> is not imported -automatically (as <code>types.hal</code> is). Thus, rule 3 resolves it to -<code>android.hardware.foo@1.0::IFooCallback</code> instead, which is imported -via <code>import android.hardware.foo@1.0;</code>).</li> -</ul> - -<h2 id=types>types.hal</h2> -<p>Every HIDL package contains a <code>types.hal</code> file containing UDTs -that are shared among all interfaces participating in that package. HIDL types -are always public; regardless of whether a UDT is declared in -<code>types.hal</code> or within an interface declaration, these types are -accessible outside of the scope where they are defined. <code>types.hal</code> -is not meant to describe the public API of a package, but rather to host UDTs -used by all interfaces within the package. Due to the nature of HIDL, all UDTs -are a part of the interface.</p> - -<p><code>types.hal</code> consists of UDTs and <code>import</code> statements. -Because <code>types.hal</code> is made available to every interface of the -package (it is an implicit import), these <code>import</code> statements are -package-level by definition. UDTs in <code>types.hal</code> may also incorporate -UDTs and interfaces thus imported.</p> - -<p>For example, for an <code>IFoo.hal</code>:</p> - -<pre class="prettyprint"> -package android.hardware.foo@1.0; -// whole package import -import android.hardware.bar@1.0; -// types only import -import android.hardware.baz@1.0::types; -// partial imports -import android.hardware.qux@1.0::IQux.Quux; -// partial imports -import android.hardware.quuz@1.0::Quuz; -</pre> - -<p>The following are imported:</p> -<ul> -<li><code>android.hidl.base@1.0::IBase</code> (implicitly)</li> -<li><code>android.hardware.foo@1.0::types</code> (implicitly)</li> -<li>Everything in <code>android.hardware.bar@1.0</code> (including all -interfaces and its <code>types.hal</code>)</li> -<li><code>types.hal</code> from <code>android.hardware.baz@1.0::types</code> -(interfaces in <code>android.hardware.baz@1.0</code> are not imported)</li> -<li><code>IQux.hal</code> and <code>types.hal</code> from -<code>android.hardware.qux@1.0</code></li> -<li><code>Quuz</code> from <code>android.hardware.quuz@1.0</code> (assuming -<code>Quuz</code> is defined in <code>types.hal</code>, the entire -<code>types.hal</code> file is parsed, but types other than <code>Quuz</code> -are not imported).</li> -</ul> - -<h2 id=interface-version>Interface-level versioning</h2> -<p>Each interface within a package resides in its own file. The package the -interface belongs to is declared at the top of the interface using the -<code>package</code> statement. Following the package declaration, zero or more -interface-level imports (partial or whole-package) may be listed. For example: -</p> - -<pre class="prettyprint">package android.hardware.nfc@1.0;</pre> - -<p>In HIDL, interfaces can inherit from other interfaces using the -<code>extends</code> keyword. For an interface to extend another interface, it -must have access to it via an <code>import</code> statement. The name of the -interface being extended (the base interface) follows the rules for type-name -qualification explained above. An interface may inherit only from one interface; -HIDL does not support multiple inheritance.</p> - -<p>The uprev versioning examples below use the following package:</p> - -<pre class="prettyprint"> -// types.hal -package android.hardware.example@1.0 -struct Foo { - struct Bar { - vec<uint32_t> val; - }; -}; - -// IQuux.hal -package android.hardware.example@1.0 -interface IQuux { - fromFooToBar(Foo f) generates (Foo.Bar b); -} -</pre> - -<h3 id=rules>Uprev rules</h3> -<p>To define a package <code>package@major.minor</code>, either A or all of B -must be true:</p> - -<table> -<tr> -<th width="10%">Rule A</th> -<td>"Is a start minor version": All previous minor versions, -<code>package@major.0</code>, <code>package@major.1</code>, …, -<code>package@major.(minor-1)</code> must not be defined. -</td> -</tr> -</table> - -<strong>OR</strong> - -<table> -<tr> -<th width="10%">Rule B</th> -<td><p>All of the following is true:</p> - -<ol> -<li>"Previous minor version is valid": <code>package@major.(minor-1)</code> -must be defined and follow the same rule A (none of -<code>package@major.0</code> through <code>package@major.(minor-2)</code> -are defined) or rule B (if it is an uprev from <code>@major.(minor-2)</code>); -<br><br> -AND -<br><br> -</li> -<li>"Inherit at least one interface with the same name": There exists an -interface <code>package@major.minor::IFoo</code> that extends -<code>package@major.(minor-1)::IFoo</code> (if the previous package has an interface); -<br><br> -AND -<br><br> -</li> -<li>"No inherited interface with a different name": There must not exist -<code>package@major.minor::IBar</code> that extends -<code>package@major.(minor-1)::IBaz</code>, where <code>IBar</code> and -<code>IBaz</code> are two different names. If there is an interface with the -same name, <code>package@major.minor::IBar</code> must extend -<code>package@major.(minor-k)::IBar</code> such that no IBar exists with a -smaller k.</li> -</ol> -</td> -</tr> -</table> - -<p>Because of rule A:</p> -<ul> -<li>The package can start with any minor version number (for example, -<code>android.hardware.biometrics.fingerprint</code> starts at -<code>@2.1</code>.)</li> -<li>The requirement "<code>android.hardware.foo@1.0</code> is not defined" means -the directory <code>hardware/interfaces/foo/1.0</code> should not even exist. -</li> -</ul> - -<p>However, rule A does not affect a package with the same package name but a -different <em>major</em> version (for example, -<code>android.hardware.camera.device</code> has both <code>@1.0</code> and -<code>@3.2</code> defined; <code>@3.2</code> doesn't need to interact with -<code>@1.0</code>.) Hence, <code>@3.2::IExtFoo</code> can extend -<code>@1.0::IFoo</code>.</p> - -<p>Provided the package name is different, -<code>package@major.minor::IBar</code> may extend from an interface with a -different name (for example, <code>android.hardware.bar@1.0::IBar</code> can -extend <code>android.hardware.baz@2.2::IBaz</code>). If an interface does not -explicitly declare a super type with the <code>extend</code> keyword, it will -extend <code>android.hidl.base@1.0::IBase</code> (except <code>IBase</code> -itself).</p> - -<p>B.2 and B.3 must be followed at the same time. For example, even if -<code>android.hardware.foo@1.1::IFoo</code> extends -<code>android.hardware.foo@1.0::IFoo</code> to pass rule B.2, if an -<code>android.hardware.foo@1.1::IExtBar</code> extends -<code>android.hardware.foo@1.0::IBar</code>, this is still not a valid uprev. -</p> - -<h3 id=uprev>Upreving interfaces</h3> -<p>To uprev <code>android.hardware.example@1.0</code> (defined above) to -<code>@1.1</code>:</p> - -<pre class="prettyprint"> -// types.hal -package android.hardware.example@1.1; -<strong>import android.hardware.example@1.0;</strong> - -// IQuux.hal -package android.hardware.example@1.1 -interface IQuux <strong>extends @1.0::IQuux</strong> { - <strong>fromBarToFoo(Foo.Bar b) generates (Foo f);</strong> -} -</pre> - -<p>This is a package-level <code>import</code> of version <code>1.0</code> of -<code>android.hardware.example</code> in <code>types.hal</code>. While no new -UDTs are added in version <code>1.1</code> of the package, references to UDTs in -version <code>1.0</code> are still needed, hence the package-level import -in <code>types.hal</code>. (The same effect could have been achieved with an -interface-level import in <code>IQuux.hal</code>.)</p> - -<p>In <code>extends @1.0::IQuux</code> in the declaration of -<code>IQuux</code>, we specified the version of <code>IQuux</code> that is being -inherited (disambiguation is required because <code>IQuux</code> is used to -declare an interface and to inherit from an interface). As declarations are -simply names that inherit all package and version attributes at the site of the -declaration, the disambiguation must be in the name of the base interface; we -could have used the fully-qualified UDT as well, but that would have been -redundant.</p> - -<p>The new interface <code>IQuux</code> does not re-declare method -<code>fromFooToBar()</code> it inherits from <code>@1.0::IQuux</code>; it simply -lists the new method it adds <code>fromBarToFoo()</code>. In HIDL, inherited -methods may <strong>not</strong> be declared again in the child interfaces, so -the <code>IQuux</code> interface cannot declare the <code>fromFooToBar()</code> -method explicitly.</p> - -<aside class="key-point"><strong>Key Point:</strong> In HIDL, every inherited -method from a base class must be explicitly implemented in the inheriting class. -If a method implementation needs to fall back to the method implementation of -the base class, the fallback must be in the implementation.</aside> - -<h3 id=conventions>Uprev conventions</h3> -<p>Sometimes interface names must rename the extending interface. We recommend -that enum extensions, structs, and unions have the same name as what they extend -unless they are sufficiently different to warrant a new name. Examples:</p> - -<pre class="prettyprint"> -// in parent hal file -enum Brightness : uint32_t { NONE, WHITE }; - -// in child hal file extending the existing set with additional similar values -enum Brightness : @1.0::Brightness { AUTOMATIC }; - -// extending the existing set with values that require a new, more descriptive name: -enum Color : @1.0::Brightness { HW_GREEN, RAINBOW }; -</pre> - -<p>If a method can have a new semantic name (for instance -<code>fooWithLocation</code>) then that is preferred. Otherwise, it should be -named similarly to what it is extending. For example, the method -<code>foo_1_1</code> in <code>@1.1::IFoo</code> may replace the functionality -of the <code>foo</code> method in <code>@1.0::IFoo</code> if there is no better -alternative name.</p> - -<h2 id=package-ext>Package-level versioning</h2> -<p>HIDL versioning occurs at the package level; after a package is published, it -is immutable (its set of interfaces and UDTs cannot be changed). Packages can -relate to each other in several ways, all of which are expressible via a -combination of interface-level inheritance and building of UDTs by composition. -</p> - -<p>However, one type of relationship is strictly-defined and must be enforced: -<em>Package-level backwards-compatible inheritance</em>. In this scenario, the -<em>parent</em> package is the package being inherited from and the -<em>child</em> package is the one extending the parent. Package-level -backwards-compatible inheritance rules are as follows:</p> - -<ol> -<li>All top-level interfaces of the parent package are inherited from by interfaces in the -child package.</li> -<li>New interfaces may also be added the new package (no restrictions about -relationships to other interfaces in other packages).</li> -<li>New data types may also be added for use by either new methods of uprev'ed -existing interfaces, or by new interfaces.</li> -</ol> - -<p>These rules can be implemented using HIDL interface-level inheritance and UDT -composition, but require meta-level knowledge to know these relationships -constitute a backwards-compatible package extension. This knowledge is inferred -as follows:</p> - -<aside class="key-point"><strong>Key Point:</strong> For package -<code>package</code> at version <code>major.minor</code>, if a -<code>package</code> exists at <code>major.(minor-1)</code>, then -<code>package@major.minor</code> is a minor uprev, and must follow the rules for -backwards-compatibility.</aside> - -<p>If a package meets this requirement, <code>hidl-gen</code> enforces -backwards-compatibility rules.</p> - - </body> -</html> |