blob: f98d1b64a41cd8f7024db4b39c53dcc8ad692fc2 [file] [log] [blame]
<html devsite>
<head>
<title>HIDL Java</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 in Java
(described below) or as client- and server-side HIDL interfaces in
<a href="/devices/architecture/hidl-cpp/index.html">C++</a>.</p>
<p>HIDL interfaces are intended to be used primarily from native code, and as a
result HIDL is focused on the auto-generation of efficient code in C++. However,
HIDL interfaces must also be able to be used directly from Java as some Android
subsystems (such as Telephony) will most likely have Java HIDL interfaces.</p>
<p>The pages in this section describe the Java frontend for HIDL interfaces,
detail how to create, register, and use services, and explain how HALs and HAL
clients written in Java interact with the HIDL RPC system.</p>
<h2 id=client>Being a client</h2>
<p>To access an interface IFoo in package <code>android.hardware.foo</code>
version 1.0 that is registered as service name <code>foo-bar</code>:</p>
<ol>
<li>Add libraries:
<ul>
<li>Add the following to Android.mk:
<pre class="prettyprint">LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java</pre>
<strong>OR</strong><br>
</li>
<li>Add the following to Android.bp:
<pre class="prettyprint">
static_libs: [
/* &hellip; */
"android.hardware.foo-V1.0-java",
],
</pre>
</li>
</ul>
</li>
<li>Add the following to your Java file:
<pre class="prettyprint">
import android.hardware.foo.V1_0.IFoo;
...
// retry to wait until the service starts up if it is in the manifest
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IFoo anotherServer = IFoo.getService("second_impl", true /* retry */);
server.doSomething(&hellip;);
</pre>
<p class=caution><strong>Warning</strong>: Java <code>getService</code> with no arguments will not
wait for the service to start.</p>
</li>
</ol>
<h2 id=service>Providing a service</h2>
<p>Framework code in Java may need to serve interfaces to receive asynchronous
callbacks from HALs.</p>
<p class=warning><strong>Warning</strong>: Do not implement a driver (HAL) in
Java. We strongly recommend you implement drivers in C++.</p>
<p class=warning><strong>Warning</strong>: Java drivers must be in a separate
process from their clients (same process communication is not supported).</p>
<p>For interface <code>IFooCallback</code> in version 1.0 of package
<code>android.hardware.foo</code>, you can implement your interface in Java
using the following steps:</p>
<ol>
<li>Define your interface in HIDL.</li>
<li>Open <code>/tmp/android/hardware/foo/IFooCallback.java</code> as a
reference.</li>
<li>Create a new module for your Java implementation.</li>
<li>Examine the abstract class
<code>android.hardware.foo.V1_0.IFooCallback.Stub</code>, then write a new class
to extend it and implement the abstract methods.</li>
</ol>
<h3 id=autogen>Viewing auto-generated files</h3>
<p>To view the automatically-generated files, run:</p>
<pre class="prettyprint">
hidl-gen -o /tmp -Ljava \
-randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
</pre>
<p>These commands generate the directory
<code>/tmp/android/hardware/foo/1.0</code>. For the file
<code>hardware/interfaces/foo/1.0/IFooCallback.hal</code>, this generates the
file <code>/tmp/android/hardware/foo/1.0/IFooCallback.java</code>, which
encapsulates the Java interface, the proxy code, and the stubs (both proxy and
stubs conform to the interface).</p>
<p><code>-Lmakefile</code> generates the rules that run this command at build
time and allow you to include
<code>android.hardware.foo-V1.0-java</code> and link against the
appropriate files. A script that automatically does this for a project full of
interfaces can be found at <code>hardware/interfaces/update-makefiles.sh</code>.
The paths in this example are relative; hardware/interfaces can be a temporary
directory under your code tree to enable you to develop a HAL prior to
publishing it.</p>
<h2 id=service>Running a service</h2>
<p>The HAL provides an interface <code>IFoo</code>, which must make asynchronous
callbacks to the framework over interface <code>IFooCallback</code>. The
<code>IFooCallback</code> interface is not registered by name as a discoverable
service; instead, <code>IFoo</code> must contain a method such as
<code>setFooCallback(IFooCallback x)</code>.</p>
<p>To set up <code>IFooCallback</code> from version 1.0 of package
<code>android.hardware.foo</code>, add
<code>android.hardware.foo-V1.0-java</code> to <code>Android.mk</code>. The code
to run the service is:</p>
<pre class="prettyprint">
import android.hardware.foo.V1_0.IFoo;
import android.hardware.foo.V1_0.IFooCallback.Stub;
....
class FooCallback extends IFooCallback.Stub {
// implement methods
}
....
// Get the service you will be receiving callbacks from.
// This also starts the threadpool for your callback service.
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
....
// This must be a persistent instance variable, not local,
// to avoid premature garbage collection.
FooCallback mFooCallback = new FooCallback();
....
// Do this once to create the callback service and tell the "foo-bar" service
server.setFooCallback(mFooCallback);
</pre>
<h2 id=extensions>Interface extensions</h2>
<p>Assuming a given service implements an interface <code>IFoo</code> across all
devices, it's possible that on a particular device the service may provide
additional capabilities implemented in an interface extension
<code>IBetterFoo</code>, i.e.:</p>
<pre class="prettyprint">
interface IFoo {
...
};
interface IBetterFoo extends IFoo {
...
};
</pre>
<p>Calling code aware of the extended interface can use the
<code>castFrom()</code> Java method to safely cast the base interface to the
extended interface:</p>
<pre class="prettyprint">
IFoo baseService = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IBetterFoo extendedService = IBetterFoo.castFrom(baseService);
if (extendedService != null) {
// The service implements the extended interface.
} else {
// The service only implements the base interface.
}
</pre>
</body>
</html>