diff options
author | Gina Dimino <gdimino@google.com> | 2021-07-15 23:27:11 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-07-15 23:27:11 +0000 |
commit | 72e0ae8d8207042452f75874221103f4f6b3014a (patch) | |
tree | 7fa97b880b85be7de5b713d233cdc407c20b88cd /en/devices/architecture/hidl-cpp | |
parent | e55b3193405187e091a4ac7730ef04360ec04504 (diff) | |
parent | fc5fc0e74df003b0ee454d3418b88cd722282c49 (diff) | |
download | source.android.com-master.tar.gz |
Diffstat (limited to 'en/devices/architecture/hidl-cpp')
-rw-r--r-- | en/devices/architecture/hidl-cpp/functions.html | 153 | ||||
-rw-r--r-- | en/devices/architecture/hidl-cpp/index.html | 148 | ||||
-rw-r--r-- | en/devices/architecture/hidl-cpp/interfaces.html | 271 | ||||
-rw-r--r-- | en/devices/architecture/hidl-cpp/packages.html | 202 | ||||
-rw-r--r-- | en/devices/architecture/hidl-cpp/types.html | 323 |
5 files changed, 0 insertions, 1097 deletions
diff --git a/en/devices/architecture/hidl-cpp/functions.html b/en/devices/architecture/hidl-cpp/functions.html deleted file mode 100644 index 5d52b31d..00000000 --- a/en/devices/architecture/hidl-cpp/functions.html +++ /dev/null @@ -1,153 +0,0 @@ -<html devsite> - <head> - <title>Functions</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>Functions in a HIDL interface are mapped to methods in the autogenerated -<code>IFoo</code> C++ class declaration. The name of each function remains the -same in C++; the following sections describe how HIDL arguments and return -values are translated to C++.</p> - -<h2 id=parameters>Function parameters</h2> -<p>The arguments listed in the <code>.hal</code> file map to C++ data types. -Arguments that do not map to a primitive C++ type are passed by const -reference.</p> - -<p>For every HIDL function that has a return value (has a <code>generates</code> -statement), the C++ parameter list for that function has an additional argument: -a callback function that is called with the return values of the HIDL function. -There is <strong>one exception</strong>: If the <code>generates</code> clause -contains a single parameter that directly maps to a C++ primitive, callback -<em>elision</em> is used (the callback is removed and the return value is -returned from the function through a normal <code>return</code> statement).</p> - -<h2 id=return-values>Function return values</h2> -<p>The following functions have return values.</p> - -<h3 id=transport>Transport errors and return type</h3> -<p>The <code>generates</code> statement can result in three types of function -signatures:</p> - -<ul> -<li>For only one return value that is a C++ primitive, the -<code>generates</code> return value is returned by value from the function in a -<code>Return<T></code> object.</li> -<li>For more complicated cases, the <code>generates</code> return value(s) are -returned through the callback parameter provided with the function call itself, -and the function returns <code>Return<void></code>.</li> -<li>For when no <code>generates</code> statement exists, the function returns -<code>Return<void></code>.</li> -</ul> - -<p>RPC calls can occasionally encounter transport errors, e.g. when the server -dies, when transport resources are insufficient to complete the call, or when -the parameters passed do not permit completing the call (such as missing a -required callback function). <code>Return</code> objects store transport error -indications as well as a <code>T</code> value (except -<code>Return<void></code>).</p> - -<p>As the client-side and server-side functions have the same signature, the -server-side function must return a <code>Return</code> type even though its -implementation does not signal transport errors. <code>Return<T></code> -objects are constructed with <code>Return(myTValue)</code> (or can be implicitly -constructed from <code>mTValue</code>, such as in <code>return</code> -statements) and <code>Return<void></code> objects are constructed with -<code>Void()</code>.</p> - -<p><code>Return<T></code> objects have implicit conversion to and from -their <code>T</code> value. The <code>Return</code> object can be checked for -transport errors by calling its <code>isOk()</code> method. This check is not -required; however, if an error occurs and is not checked by the time the -<code>Return</code> object is destroyed, or a <code>T</code> value conversion is -attempted, the client process will be killed and an error logged. If -<code>isOk()</code> indicates a transport error or a call failure due to a logic -error in developer code (such as passing <code>nullptr</code> as a synchronous -callback), then <code>description()</code> can be called on the Return object to -return a string suitable for logging. In such cases, there is no way to -determine how much code may have executed on the server as a result of the -failed call. The method <code>isDeadObject()</code> is also provided. This -method indicates that <code>!isOk()</code> is because the remote object has -crashed or no longer exists. <code>isDeadObject()</code> always implies -<code>!isOk()</code>.</p> - -<h3 id=return-by>Return by value</h3> -<p>If the <code>generates</code> statement maps to a single C++ primitive, no -callback parameter is in the parameter list. Instead, an implementation provides -the return value <code>T</code> in a <code>Return<T></code> object, which -can be implicitly generated from the primitive type <code>T</code>. For -example:</p> - -<pre class="prettyprint"> -Return<uint32_t> someMethod() { - uint32_t return_data = ...; // Compute return_data - return return_data; -}; -</pre> - -<p>The method <code>Return<*>::withDefault</code> is also provided. This -method provides a value in cases where the return value is <code>!isOk()</code>. -This method also automatically marks the return object as okay so the client -process will not be killed.</p> - -<h3 id=return-callback>Return using callback parameter</h3> -<p>A callback can pass the return value of the HIDL function back to the caller. -The prototype of the callback is a <code>std::function</code> object with -parameters (taken from the <code>generates</code> statement) mapped to C++ -types. Its return value is void—the callback itself doesn't return a value.</p> - -<p>The return value of a C++ function with a callback parameter has type -<code>Return<void></code>. The server implementation is responsible only -for providing the return value. As the return values are already transferred -using the callback, the <code>T</code> template parameter is <code>void</code>: -</p> - -<pre class="prettyprint"> -Return<void> someMethod(someMethod_cb _cb); -</pre> - -<p>From their C++ implementation, server implementations should return -<code>Void()</code>, which is a static inlined function returning a -<code>Return<void></code> object. Example of a typical server method -implementation with a callback parameter:</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); - return Void(); -}; -</pre> - -<h2 id=no-return>Functions without return values</h2> -<p>The C++ signature of a function without a <code>generates</code> statement -will not have a callback parameter in the parameter list. Its return type will -be <code>Return<void>.</code></p> - -<h2 id=oneway>Oneway functions</h2> -<p>Functions marked with the <code>oneway</code> keyword are asynchronous -functions (clients won't block on their execution) and do not have return -values. The C++ signature of a <code>oneway</code> function will not have a -callback parameter in the parameter list, and its C++ return value will be -<code>Return<void></code>.</p> - - </body> -</html> diff --git a/en/devices/architecture/hidl-cpp/index.html b/en/devices/architecture/hidl-cpp/index.html deleted file mode 100644 index 340d5766..00000000 --- a/en/devices/architecture/hidl-cpp/index.html +++ /dev/null @@ -1,148 +0,0 @@ -<html devsite> - <head> - <title>HIDL C++</title> - <meta name="project_path" value="/_project.yaml" /> - <meta name="book_path" value="/_book.yaml" /> - </head> - <body> - <!-- - Copyright 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<p>Android O re-architects the Android OS to define clear interfaces between the -device-independent Android platform and device- and vendor-specific code. -Android already defines many such interfaces in the form of HAL interfaces, -defined as C headers in <code>hardware/libhardware</code>. HIDL replaces these -HAL interfaces with stable, versioned interfaces, which can be client- and -server-side HIDL interfaces in C++ (described below) or -<a href="/devices/architecture/hidl-java/index.html">Java</a>.</p> - -<p>The pages in this section describe C++ implementations of HIDL interfaces, -including details about the files auto-generated from the HIDL <code>.hal</code> -files by the <code>hidl-gen</code> compiler, how these files are packaged, and -how to integrate these files with the C++ code that uses them.</p> - -<h2 id=client-server>Client & server implementations</h2> -<p>HIDL interfaces have client and server implementations:</p> - -<ul> -<li>A <strong>client</strong> of a HIDL interface is the code that uses the -interface by calling methods on it.</li> -<li>A <strong>server</strong> is an implementation of a HIDL interface that -receives calls from clients and returns results (if necessary).</li> -</ul> - -<p>In transitioning from <code>libhardware</code> HALs to HIDL HALs, the HAL -implementation becomes the server and the process calling into the HAL becomes -the client. Default implementations can serve both passthrough and binderized -HALs, and can change over time:</p> - -<p><img src="../images/treble_cpp_legacy_hal_progression.png"></p> -<p><strong>Figure 1.</strong> Development progression for legacy HALs.</p> - -<h2>Creating the HAL client</h2> -<p>Start by including the HAL libraries in the makefile:</p> - -<ul> -<li>Make: <code>LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0</code></li> -<li>Soong: <code>shared_libs: [ …, android.hardware.nfc@1.0 ]</code></li> -</ul> - -<p>Next, include the HAL header files:</p> - -<pre class="prettyprint"> -#include <android/hardware/nfc/1.0/IFoo.h> -… -// in code: -sp<IFoo> client = IFoo::getService(); -client->doThing(); -</pre> - -<h2>Creating the HAL server</h2> -<p>To create the HAL implementation, you must have the <code>.hal</code> files -that represent your HAL and have already generated makefiles for your HAL using -<code>-Lmakefile</code> or <code>-Landroidbp</code> on <code>hidl-gen</code> -(<code>./hardware/interfaces/update-makefiles.sh</code> does this for internal -HAL files and is a good reference). When transferring over HALs from -<code>libhardware</code>, you can do a lot of this work easily using c2hal.</p> - -<p>To create the necessary files to implement your HAL:</p> - -<pre class="prettyprint"> -PACKAGE=android.hardware.nfc@1.0 -LOC=hardware/interfaces/nfc/1.0/default/ -m -j hidl-gen -hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \ - -randroid.hidl:system/libhidl/transport $PACKAGE -hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \ - -randroid.hidl:system/libhidl/transport $PACKAGE -</pre> - -<p>For the HAL to work in passthrough mode (for legacy devices), you must have -the function <em>HIDL_FETCH_IModuleName</em> residing in -<code>/(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl($OPTIONAL_IDENTIFIER).so</code> -where <code>$OPTIONAL_IDENTIFIER</code> is a string identifying the passthrough -implementation. The passthrough mode requirements are met automatically by the -above commands, which also create the <code>android.hardware.nfc@1.0-impl</code> -target, but any extension can be used. For instance -<code>android.hardware.nfc@1.0-impl-foo</code> uses <code>-foo</code> to -differentiate itself.</p> - -<p>Next, fill out the stubs with functionality and setup a daemon. Example -daemon code (supporting passthrough):</p> - -<pre class="prettyprint"> -#include <hidl/LegacySupport.h> - -int main(int /* argc */, char* /* argv */ []) { - return defaultPassthroughServiceImplementation<INfc>("nfc"); -} -</pre> - -<p><code>defaultPassthroughServiceImplementation</code> will -<code>dlopen()</code> the provided <code>-impl</code> library and provide it as -a binderized service. Example daemon code (for pure binderized service):</p> - -<pre class="prettyprint"> -int main(int /* argc */, char* /* argv */ []) { - // This function must be called before you join to ensure the proper - // number of threads are created. The threadpool will never exceed - // size one because of this call. - ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/); - - sp<INfc> nfc = new Nfc(); - const status_t status = nfc->registerAsService(); - if (status != ::android::OK) { - return 1; // or handle error - } - - // Adds this thread to the threadpool, resulting in one total - // thread in the threadpool. We could also do other things, but - // would have to specify 'false' to willJoin in configureRpcThreadpool. - ::android::hardware::joinRpcThreadpool(); - return 1; // joinRpcThreadpool should never return -} -</pre> - -<p>This daemon usually lives in <code>$PACKAGE + "-service-suffix"</code> (for -example, <code>android.hardware.nfc@1.0-service</code>), but it could be anywhere. -The <a href="/security/selinux/device-policy.html">sepolicy</a> for a specific -class of HALs is the attribute <code>hal_<module></code> (for instance, -<code>hal_nfc)</code>. This attribute must be applied to the daemon that runs a -particular HAL (if the same process serves multiple HALs, multiple attributes -can be applied to it).</p> - -</body> -</html> diff --git a/en/devices/architecture/hidl-cpp/interfaces.html b/en/devices/architecture/hidl-cpp/interfaces.html deleted file mode 100644 index c236a171..00000000 --- a/en/devices/architecture/hidl-cpp/interfaces.html +++ /dev/null @@ -1,271 +0,0 @@ -<html devsite> - <head> - <title>Interfaces</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>Every interface defined in a HIDL package has its own autogenerated C++ class -inside its package's namespace. Clients and servers deal with interfaces in -different ways:</p> - -<ul> -<li><strong>Servers</strong> implement interfaces.</li> -<li><strong>Clients</strong> call methods on interfaces.</li> -</ul> - -<p>Interfaces can either be registered by name by the server or passed as -parameters to HIDL-defined methods. For example, framework code may serve an -interface to receive asynchronous messages from the HAL and pass that interface -directly to the HAL without registering it.</p> - -<h2 id=server>Server implementation</h2> -<p>A server implementing the <code>IFoo</code> interface must include the -<code>IFoo</code> header file that was autogenerated:</p> - -<pre class="prettyprint"> -#include <android/hardware/samples/1.0/IFoo.h> -</pre> - -<p>The header is automatically exported by the shared library of the -<code>IFoo</code> interface to link against. Example <code>IFoo.hal</code>:</p> - -<pre class="prettyprint"> -// IFoo.hal -interface IFoo { - someMethod() generates (vec<uint32_t>); - ... -} -</pre> - -<p>Example skeleton for a server implementation of the IFoo interface:</p> - -<pre class="prettyprint"> -// From the IFoo.h header -using android::hardware::samples::V1_0::IFoo; - -class FooImpl : public IFoo { - Return<void> someMethod(foo my_foo, someMethod_cb _cb) { - vec<uint32_t> return_data; - // Compute return_data - _cb(return_data); - return Void(); - } - ... -}; -</pre> - -<p>To make the implementation of a server interface available to a client, you -can:</p> - -<ol> -<li><strong>Register</strong> the interface implementation with the -<code>hwservicemanager</code> (see details below), -<br><br> -OR<br><br> -</li> -<li><strong>Pass</strong> the interface implementation as an argument of an -interface method (for detals, see <a href="#asynchronous">Asynchronous -callbacks</a>).</li> -</ol> - -<p>When registering the interface implementation, the -<code>hwservicemanager</code> process keeps track of registered HIDL interfaces -running on the device by name and version. Servers can register a HIDL interface -implementation by name and clients can request service implementations by name -and version. This process serves the HIDL interface -<code>android.hidl.manager@1.0::IServiceManager</code>.</p> - -<p>Each auto-generated HIDL interface header file (such as <code>IFoo.h</code>) -has a <code>registerAsService()</code> method that can be used to register the -interface implementation with the <code>hwservicemanager</code>. The only -required argument is the name of the interface implementations as clients will -use this name to retrieve the interface from the <code>hwservicemanager</code> -later:</p> - -<pre class="prettyprint"> -::android::sp<IFoo> myFoo = new FooImpl(); -::android::sp<IFoo> mySecondFoo = new FooAnotherImpl(); -status_t status = myFoo->registerAsService(); -status_t anotherStatus = mySecondFoo->registerAsService("another_foo"); -</pre> - -<p>The <code>hwservicemanager</code> treats the combination of -<code>[package@version::interface, instance_name]</code> as unique to enable -different interfaces (or different versions of the same interface) to register -with identical instance names without conflicts. If you call -<code>registerAsService()</code> with the exact same package version, interface, -and instance name, the <code>hwservicemanager</code> drops its reference to the -previously registered service and uses the new one.</p> - -<h2 id=client>Client implementation</h2> -<p>Just as the server does, a client must <code>#include</code> every interface -it refers to:</p> - -<pre class="prettyprint"> -#include <android/hardware/samples/1.0/IFoo.h> -</pre> - -<p>A client can obtain an interface in two ways:</p> - -<ul> -<li>Through <code>I<InterfaceName>::getService</code> (via the -<code>hwservicemanager</code>)</li> -<li>Through an interface method</li> -</ul> - -<p>Each autogenerated interface header file has a static <code>getService</code> -method that can be used to retrieve a service instance from the -<code>hwservicemanager</code>:</p> - -<pre class="prettyprint"> -// getService will return nullptr if the service can't be found -sp<IFoo> myFoo = IFoo::getService(); -sp<IFoo> myAlternateFoo = IFoo::getService("another_foo"); -</pre> - -<p>Now the client has an an <code>IFoo</code> interface, and can call methods to -it as if it were a local class implementation. In reality, the implementation -may run in the same process, a different process, or even on another device -(with HAL remoting). Because the client called <code>getService</code> on an -<code>IFoo</code> object included from version <code>1.0 </code>of the package, -the <code>hwservicemanager</code> returns a server implementation only if that -implementation is compatible with <code>1.0</code> clients. In practice, this -means only server implementations with version <code>1.n</code> (version -<code>x.(y+1)</code> of an interface must extend (inherit from) -<code>x.y</code>).</p> - -<p>Additionally the method <code>castFrom</code> is provided to cast between -different interfaces. This method works by making an IPC call to the remote -interface to make sure the underlying type is the same as the type that is being -requested. If the requested type is unavailable, then <code>nullptr</code> is -returned.</p> - -<pre class="prettyprint"> -sp<V1_0::IFoo> foo1_0 = V1_0::IFoo::getService(); -sp<V1_1::IFoo> foo1_1 = V1_1::IFoo::castFrom(foo1_0); -</pre> - -<h2 id=asynchronous>Asynchronous callbacks</h2> -<p>Many existing HAL implementations talk to asynchronous hardware, which means -they need an asynchronous way to notify clients of new events that have -occurred. A HIDL interface can be used as an asynchronous callback because HIDL -interface functions can take HIDL interface objects as parameters.</p> - -<p>Example interface file <code>IFooCallback.hal</code>:</p> - -<pre class="prettyprint"> -package android.hardware.samples@1.0; -interface IFooCallback { - sendEvent(uint32_t event_id); - sendData(hidl_vec<uint8_t> data); -} -</pre> - -<p>Example new method in <code>IFoo</code> that takes an -<code>IFooCallback</code> parameter:</p> - -<pre class="prettyprint"> -package android.hardware.samples@1.0; -interface IFoo { - struct Foo { - int64_t some_value; - Handle my_handle; - }; - - someMethod(Foo foo) generates (int32_t ret); - another_method() generates (hidl_vec<uint32_t>); - register_callback(IFooCallback callback); -}; -</pre> - -<p>The <em>client</em> using the <code>IFoo</code> interface is the -<em>server</em> of the <code>IFooCallback</code> interface; it provides an -implementation of <code>IFooCallback</code>:</p> - -<pre class="prettyprint"> -class FooCallback : public IFooCallback { - Return<void> sendEvent(uint32_t event_id) { - // process the event from the HAL - } - Return<void> sendData(hidl_vec<uint8_t> data) { - // process data from the HAL - } -}; -</pre> - -<p>It can also simply pass that over an existing instance of the -<code>IFoo</code> interface:</p> -<pre class="prettyprint"> -sp<IFooCallback> myFooCallback = new FooCallback(); -myFoo.registerCallback(myFooCallback); -</pre> - -<p>The server implementing <code>IFoo</code> receives this as an -<code>sp<IFooCallback></code> object. It can store the callback, and call -back into the client whenever it wants to use this interface.</p> - -<h2 id=death>Death recipients</h2> -<p>As service implementations can run in a different process, it can happen -that the process implementing an interface dies while the client stays alive. -Any calls on an interface object hosted in a process that has died will fail -with a transport error (<code>isOK()</code> will return false). The only way to -recover from such a failure is to request a new instance of the service by -calling <code>I<InterfaceName>::getService()</code>. This works only if -the process that crashed has restarted and re-registered its services with the -<code>servicemanager</code> (which is generally true for HAL implementations). -</p> - -<p>Instead of dealing with this reactively, clients of an interface can also -register a <em>death recipient</em> to get a notification when a service dies. -To register for such notifications on a retrieved <code>IFoo</code> interface, a -client can do the following:</p> - -<pre class="prettyprint"> -foo->linkToDeath(recipient, 1481 /* cookie */); -</pre> - -<p>The <code>recipient</code> parameter must be an implementation of the -<code>android::hardware::hidl_death_recipient</code> interface provided by HIDL, -which contains a single method <code>serviceDied()</code> that will be called -from a thread in the RPC threadpool when the process hosting the interface dies: -</p> - -<pre class="prettyprint"> -class MyDeathRecipient : public android::hardware::hidl_death_recipient { - virtual void serviceDied(uint64_t cookie, const android::wp<::android::hidl::base::V1_0::IBase>& who) { - // Deal with the fact that the service died - } -} -</pre> - -<p>The <code>cookie</code> parameter contains the cookie that was passed in with -<code>linkToDeath()</code>, whereas the <code>who</code> parameter contains a -weak pointer to the object representing the service in the client. With the -sample call given above, <code>cookie</code> equals 1481, and <code>who</code> -equals <code>foo</code>.</p> - -<p>It's also possible to unregister a death recipient after registering it:</p> - -<pre class="prettyprint"> -foo->unlinkToDeath(recipient); -</pre> - - </body> -</html> diff --git a/en/devices/architecture/hidl-cpp/packages.html b/en/devices/architecture/hidl-cpp/packages.html deleted file mode 100644 index 2c8e096d..00000000 --- a/en/devices/architecture/hidl-cpp/packages.html +++ /dev/null @@ -1,202 +0,0 @@ -<html devsite> - <head> - <title>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 class=note><strong>Note:</strong> This section uses sample <code>.hal</code> -files to illustrate how HIDL language constructs map to C++.</p> - -<p>With few exceptions, HIDL interface packages are located in -<code>hardware/interfaces</code> or the <code>vendor/</code> directory. The -<code>hardware/interfaces</code> top-level maps directly to the -<code>android.hardware</code> package namespace; the version is a subdirectory -under the package (not interface) namespace.</p> - -<p>The <code>hidl-gen</code> compiler compiles the <code>.hal</code> files into -a set of a <code>.h</code> and <code>.cpp</code> files. From these autogenerated -files a shared library that client/server implementations link against is built. -The <code>Android.bp</code> file that builds this shared library is -autogenerated by the <code>hardware/interfaces/update-makefiles.sh</code> -script. Every time you add a new package to <code>hardware/interfaces</code>, or -add/remove <code>.hal</code> files to/from an existing package, you must rerun -the script to ensure the generated shared library is up-to-date.</p> - -<p>For example, the <code>IFoo.hal</code> sample file should be located in -<code>hardware/interfaces/samples/1.0</code>. The sample -<code><strong>IFoo.hal</code></strong> file creates an IFoo interface in the -<strong>samples</strong> package:</p> - -<pre class="prettyprint"> -package android.hardware.samples@1.0; -interface IFoo { - struct Foo { - int64_t someValue; - handle myHandle; - }; - - someMethod() generates (vec<uint32_t>); - anotherMethod(Foo foo) generates (int32_t ret); -}; -</pre> - -<h2 id=generated-files>Generated files</h2> - -<p>Autogenerated files in a HIDL package are linked into a single shared -library with the same name as the package (for example, -<code>android.hardware.samples@1.0</code>). The shared library also exports a -single header, <code>IFoo.h</code>, which can be included by clients and -servers. Using the <code>hidl-gen</code> compiler with the <code>IFoo.hal</code> -interface file as an input, binderized mode has the following autogenerated -files:</p> - -<p><img src="../images/treble_cpp_compiler_generated_files.png"></p> -<p><strong>Figure 1.</strong> Files generated by compiler.</p> - -<ul> -<li><code><strong>IFoo.h</code></strong>. Describes the pure <code>IFoo</code> -interface in a C++ class; it contains the methods and types defined in the -<code>IFoo</code> interface in the <code>IFoo.hal</code> file, translated to C++ -types where necessary. <strong>Does not contain</strong> details related to the -RPC mechanism (e.g., <code>HwBinder</code>) used to implement this interface. -The class is namespaced with the package and version, e.g. -<code>::android::hardware::samples::IFoo::V1_0</code>. Both clients and servers -include this header: Clients for calling methods on it and servers for -implementing those methods.</li> -<li><code><strong>IHwFoo.h</code></strong>. Header file that contains -declarations for functions that serialize data types used in the interface. -Developers should never include his header directly (it does not contain any -classes).</li> -<li><code><strong>BpFoo.h</code></strong>. A class that inherits from -<code>IFoo</code> and describes the <code>HwBinder</code> proxy (client-side) -implementation of the interface. Developers should never refer to this class -directly.</li> -<li><code><strong>BnFoo.h</code></strong>.<strong> </strong>A class that holds a -reference to an <code>IFoo</code> implementation and describes the -<code>HwBinder</code> stub (server-side) implementation of the interface. -Developers should never refer to this class directly.</li> -<li><code><strong>FooAll.cpp</code></strong>. A class that contains the -implementations for both the <code>HwBinder</code> proxy and the -<code>HwBinder</code> stub. When a client calls an interface method, the proxy -automatically marshals the arguments from the client and sends the transaction -to the binder kernel driver, which delivers the transaction to the stub on the -other side (which then calls the actual server implementation).</li> -</ul> - -<p>The files are structured similarly to the files generated by -<code>aidl-cpp</code> (for details, see "Passthrough mode" in the -<a href="/devices/architecture/hidl/index.html">HIDL Overview</a>). The only -autogenerated file that is independent of the RPC mechanism used by HIDL is -<code>IFoo.h</code>; all other files are tied to the HwBinder RPC mechanism used -by HIDL. Therefore, client and server implementations <strong>should never -directly refer to anything other than <code>IFoo</code></strong>. To achieve -this, include only <code>IFoo.h</code> and link against the generated shared -library.</p> - -<p class=note><strong>Note</strong>: HwBinder is only one possible transport; -new transports may be added in the future.</p> - -<h2 id=link-libraries>Linking to shared libraries</h2> -<p>A client or server that uses any interface in a package must include the -shared library of that package in <strong>one (1)</strong> of the following -locations:</p> - -<ul> -<li>In <strong>Android.mk</strong>: -<pre class="prettyprint"> -LOCAL_SHARED_LIBRARIES += android.hardware.samples@1.0 -</pre> -</li> - -<li>In <strong>Android.bp</strong>: -<pre class="prettyprint"> -shared_libs: [ - /* ... */ - "android.hardware.samples@1.0", -], -</pre> -</li> -</ul> - -<p>For specific libraries:</p> - -<table> - -<tr> -<th><code>libhidlbase</code></th> -<td>Includes standard HIDL data-types. Unless your interface consists only of -primitives that map directly to C++ primitives, you must also link this library: -<pre class="prettyprint"> -LOCAL_SHARED_LIBRARIES += libhidlbase -</pre> -</td> -</tr> - -<tr> -<th><code>libhidltransport</code></th> -<td>Handles the transport of HIDL calls over different RPC/IPC mechanisms. You -must always link this library: -<pre class="prettyprint"> -LOCAL_SHARED_LIBRARIES += libhidltransport -</pre> -</td> -</tr> - -<tr> -<th><code>libhwbinder</code></th> -<td>You must also link to this library: -<pre class="prettyprint"> -LOCAL_SHARED_LIBRARIES += libhwbinder -</pre> -</td> -</tr> - -<tr> -<th><code>libfmq</code></th> -<td>To use Fast Message Queue IPC, you must also link to this library. -<pre class="prettyprint"> -LOCAL_SHARED_LIBRARIES += libfmq -</pre> -</td> -</tr> - -</tbody> -</table> - -<h2 id=namespaces>Namespaces</h2> -<p>HIDL functions and types such as <code>Return<T></code> and -<code>Void()</code> are declared in namespace <code>::android::hardware</code>. -The C++ namespace of a package is determined by the package name and version. -For example, a package <strong>mypackage</strong> with version 1.2 under -<code>hardware/interfaces</code> has the following qualities:</p> - -<ul> -<li><strong>C++ namespace</strong> is -<code>::android::hardware::mypackage::V1_2</code></li> -<li><strong>Fully qualified name </strong>of <code>IMyInterface</code> in that -package is: <code>::android::hardware::mypackage::V1_2::IMyInterface</code>. -(<code>IMyInterface</code> is an identifier, not part of the namespace).</li> -<li><strong>Types</strong> defined in the package's <code>types.hal</code> file -are identified as: -<code>::android::hardware::mypackage::V1_2::MyPackageType</code></li> -</ul> - - </body> -</html> diff --git a/en/devices/architecture/hidl-cpp/types.html b/en/devices/architecture/hidl-cpp/types.html deleted file mode 100644 index 1d93df74..00000000 --- a/en/devices/architecture/hidl-cpp/types.html +++ /dev/null @@ -1,323 +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>HIDL data declarations generate C++ standard-layout data structures. These -structures can be placed anywhere that feels natural (on the stack, at file or -global scope, or on the heap) and can be composed in the same fashion. Client -code calls HIDL proxy code passing in const references and primitive types, -while the stub and proxy code hides the details of serialization.</p> - -<p class=note><strong>Note:</strong> At no point is developer-written code -required to explicitly serialize or deserialize data structures.</p> - -<p>The table below maps HIDL primitives to C++ data types:</p> - -<table> -<tbody> -<tr> -<th><strong>HIDL Type</strong></th> -<th><strong>C++ Type</strong></th> -<th><strong>Header/Library</strong></th> -</tr> - -<tr> -<td><pre>enum</pre></td> -<td><pre>enum class</pre></td> -<td></td> -</tr> - -<tr> -<td><pre>uint8_t..uint64_t</pre></td> -<td><pre>uint8_t..uint64_t</pre></td> -<td><pre><stdint.h></pre></td> -</tr> - -<tr> -<td><pre>int8_t..int64_t</pre></td> -<td><pre>int8_t..int64_t</pre></td> -<td><pre><stdint.h></pre></td> -</tr> - -<tr> -<td><pre>float</pre></td> -<td><pre>float</pre></td> -<td></td> -</tr> - -<tr> -<td><pre>double</pre></td> -<td><pre>double</pre></td> -<td></td> -</tr> - -<tr> -<td><pre>vec<T></pre></td> -<td><pre>hidl_vec<T></pre></td> -<td><pre>libhidlbase</pre></td> -</tr> - -<tr> -<td><pre>T[S1][S2]...[SN]</pre></td> -<td><pre>T[S1][S2]...[SN]</pre></td> -<td></td> -</tr> - -<tr> -<td><pre>string</pre></td> -<td><pre>hidl_string</pre></td> -<td><pre>libhidlbase</pre></td> -</tr> - -<tr> -<td><pre>handle</pre></td> -<td><pre>hidl_handle</pre></td> -<td><pre>libhidlbase</pre></td> -</tr> - -<tr> -<td><pre>opaque</pre></td> -<td><pre>uint64_t</pre></td> -<td><pre><stdint.h></pre> -</td> -</tr> - -<tr> -<td><pre>struct</pre></td> -<td><pre>struct</pre></td> -<td></td> -</tr> - -<tr> -<td><pre>union</pre></td> -<td><pre>union</pre></td> -<td></td> -</tr> - -<tr> -<td><pre>fmq_sync</pre></td> -<td><pre>MQDescriptorSync</pre></td> -<td><pre>libhidlbase</pre></td> -</tr> - -<tr> -<td><pre>fmq_unsync</pre></td> -<td><pre>MQDescriptorUnsync</pre></td> -<td><pre>libhidlbase</pre></td> -</tr> - -</tbody> -</table> - -<p>The sections below describe data types in more detail.</p> - -<h2 id=enum>enum</h2> -<p>An enum in HIDL becomes an enum in C++. For example:</p> -<pre class="prettyprint"> -enum Mode : uint8_t { WRITE = 1 << 0, READ = 1 << 1 }; -</pre> - -<p>… becomes:</p> -<pre class="prettyprint"> -enum class Mode : uint8_t { WRITE = 1, READ = 2 }; -</pre> - -<h2 id=bitfield>bitfield<T></h2> -<p><code>bitfield<T></code> (where <code>T</code> is a user-defined enum) -becomes the underlying type of that enum in C++. In the above example, -<code>bitfield<Mode></code> becomes <code>uint8_t</code>.</p> - -<h2 id=vect>vec<T></h2> -<p>The <code>hidl_vec<T></code> class template is part of -<code>libhidlbase</code> and can be used to pass a vector of any HIDL type with -an arbitrary size. The comparable fixed size container is -<code>hidl_array</code>. A <code>hidl_vec<T></code> can also be -initialized to point to an external data buffer of type <code>T</code>, using -the <code>hidl_vec::setToExternal()</code> function.</p> - -<p>In addition to emitting/inserting the struct appropriately in the generated -C++ header, the use of <code>vec<T></code> generates some convenience -functions to translate to/from <code>std::vector</code> and bare <code>T</code> -pointers. If the <code>vec<T></code> is used as a parameter, the function -using it will be overloaded (two prototypes will be generated) to accept and -pass both the HIDL struct and a <code>std::vector<T></code> type for that -parameter.</p> - -<h2 id=arrays>array</h2> -<p>Constant arrays in hidl are represented by the <code>hidl_array</code> class -in <code>libhidlbase</code>. A <code>hidl_array<T, S1, S2, …, -SN></code> represents an N dimensional fixed size array -<code>T[S1][S2]…[SN]</code>.</p> - -<h2 id=string>string</h2> -<p>The <code>hidl_string</code> class (part of <code>libhidlbase</code>) can be -used to pass strings over HIDL interfaces and is defined in -<code>/system/libhidl/base/include/hidl/HidlSupport.h</code>. The first storage -location in the class is a pointer to its character buffer.</p> - -<p><code>hidl_string</code> knows how to convert to and from -<code>std::string and char*</code> (C-style string) using -<code>operator=</code>, implicit casts, and <code>.c_str()</code> function. -HIDL string structs has the appropriate copy constructors and assignment -operators to:</p> - -<ul> -<li>Load the HIDL string from an <code>std::string</code> or a C string.</li> -<li>Create a new <code>std::string</code> from a HIDL string.</li> -</ul> - -<p>In addition, HIDL strings have conversion constructors so C strings -(<code>char *</code>) and C++ strings (<code>std::string</code>) can be used on -methods that take a HIDL string.</p> - -<h2 id=struct>struct</h2> -<p>A <code>struct</code> in HIDL can contain only fixed-size data types and no -functions. HIDL struct definitions map directly to standard-layout -<code>struct</code>s in C++, ensuring that <code>struct</code>s have a -consistent memory layout. A struct can include HIDL types, including -<code>handle</code>, <code>string</code>, and <code>vec<T></code>, that -point to separate variable-length buffers.</p> - -<h2 id=handle>handle</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 being used to look -up allocated memory within a process. Otherwise, bad handles may cause bad -memory access or memory corruption.</p> - -<p>The <code>handle</code> type is represented by the <code>hidl_handle</code> -structure in C++, which is a simple wrapper around a pointer to a -<code>const native_handle_t</code> object (this has been present in Android for -a long time).</p> - -<pre> -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>By default, <code>hidl_handle</code> does <strong>not</strong> take ownership -of the <code>native_handle_t</code> pointer it wraps. It merely exists to safely -store a pointer to a <code>native_handle_t</code> such that it can be used in -both 32- and 64-bit processes.</p> - -<p>Scenarios in which the <code>hidl_handle</code> does own its enclosed file -descriptors include:</p> -<ul> -<li>Following a call to the <code>setTo(native_handle_t* handle, bool -shouldOwn)</code> method with the <code>shouldOwn</code> parameter set to -<code>true</code></li> -<li>When the <code>hidl_handle</code> object is created by copy construction -from another <code>hidl_handle</code> object</li> -<li>When the <code>hidl_handle</code> object is copy-assigned from another -<code>hidl_handle</code> object</li> -</ul> - -<p><code>hidl_handle</code> provides both implicit and explicit conversions -to/from <code>native_handle_t* </code>objects. The main use for the -<code>handle</code> type in HIDL is to pass file descriptors over HIDL -interfaces. A single file descriptor is therefore represented by a -<code>native_handle_t</code> with no <code>int</code>s and a single -<code>fd</code>. If the client and server live in a different process, the RPC -implementation will automatically take care of the file descriptor to ensure -both processes can operate on the same file.</p> - -<p>Although a file descriptor received in a <code>hidl_handle</code> by a -process will be valid in that process, it will not persist beyond the receiving -function (it will be closed once the function returns). A process that wants to -retain persistent access to the file descriptor must <code>dup()</code> the -enclosed file descriptors, or copy the entire <code>hidl_handle</code> object. -</p> - -<h2 id=memory>memory</h2> -<p>The HIDL <code>memory</code> type maps to the <code>hidl_memory</code> class -in <code>libhidlbase</code>, which represents unmapped shared memory. This is -the object that must be passed between processes to share memory in HIDL. To -use shared memory:</p> - -<ol> -<li>Obtain an instance of <code>IAllocator</code> (currently only instance -"ashmem" is available) and use it to allocate shared memory.</li> -<li><code>IAllocator::allocate()</code> returns a <code>hidl_memory</code> -object that can be passed through HIDL RPC and be mapped into a process using -<code>libhidlmemory</code>'s <code>mapMemory</code> function.</li> -<li><code>mapMemory</code> returns a reference to an -<code>sp<IMemory></code> object that can be used to access the memory. -(<code>IMemory</code> and <code>IAllocator</code> are defined in -<code>android.hidl.memory@1.0</code>.)</li> -</ol> - -<p>An instance of <code>IAllocator</code> can be used to allocate memory:</p> -<pre class="prettyprint"> -#include <android/hidl/allocator/1.0/IAllocator.h> -#include <android/hidl/memory/1.0/IMemory.h> -#include <hidlmemory/mapping.h> -using ::android::hidl::allocator::V1_0::IAllocator; -using ::android::hidl::memory::V1_0::IMemory; -using ::android::hardware::hidl_memory; -.... - sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem"); - ashmemAllocator->allocate(2048, [&](bool success, const hidl_memory& mem) { - if (!success) { /* error */ } - // now you can use the hidl_memory object 'mem' or pass it around - })); -</pre> - -<p>Actual changes to the memory must be done through an <code>IMemory</code> -object, either on the side that created <code>mem</code> or on the side that -receives it over HIDL RPC.</p> - -<pre class="prettyprint"> -// Same includes as above - -sp<IMemory> memory = mapMemory(mem); -void* data = memory->getPointer(); -memory->update(); -// update memory however you wish after calling update and before calling commit -data[0] = 42; -memory->commit(); -// … -memory->update(); // the same memory can be updated multiple times -// … -memory->commit(); -</pre> - -<h2 id=interfaces>interface</h2> -<p>Interfaces can be passed as objects. The word <em>interface</em> can be used -as syntactic sugar for the type <code>android.hidl.base@1.0::IBase</code>; -in addition, the current interface and any imported interfaces will be defined -as a type.</p> - -<p>Variables that hold Interfaces should be strong pointers: -<code>sp<IName></code>. HIDL functions that take interface parameters -will convert raw pointers to strong pointers, causing non-intuitive behavior -(the pointer can be cleared unexpectedly). To avoid problems, always store HIDL -interfaces as a <code>sp<></code>.</p> - - </body> -</html> |