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 hardware/libhardware
. 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
C++.
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.
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.
To access an interface IFoo in package android.hardware.foo
version 1.0 that is registered as service name foo-bar
:
LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-javaOR
static_libs: [ /* … */ "android.hardware.foo-V1.0-java", ],
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(…);
Warning: Java getService
with no arguments will not
wait for the service to start.
Framework code in Java may need to serve interfaces to receive asynchronous callbacks from HALs.
Warning: Do not implement a driver (HAL) in Java. We strongly recommend you implement drivers in C++.
Warning: Java drivers must be in a separate process from their clients (same process communication is not supported).
For interface IFooCallback
in version 1.0 of package
android.hardware.foo
, you can implement your interface in Java
using the following steps:
/tmp/android/hardware/foo/IFooCallback.java
as a
reference.android.hardware.foo.V1_0.IFooCallback.Stub
, then write a new class
to extend it and implement the abstract methods.To view the automatically-generated files, run:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
These commands generate the directory
/tmp/android/hardware/foo/1.0
. For the file
hardware/interfaces/foo/1.0/IFooCallback.hal
, this generates the
file /tmp/android/hardware/foo/1.0/IFooCallback.java
, which
encapsulates the Java interface, the proxy code, and the stubs (both proxy and
stubs conform to the interface).
-Lmakefile
generates the rules that run this command at build
time and allow you to include
android.hardware.foo-V1.0-java
and link against the
appropriate files. A script that automatically does this for a project full of
interfaces can be found at hardware/interfaces/update-makefiles.sh
.
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.
The HAL provides an interface IFoo
, which must make asynchronous
callbacks to the framework over interface IFooCallback
. The
IFooCallback
interface is not registered by name as a discoverable
service; instead, IFoo
must contain a method such as
setFooCallback(IFooCallback x)
.
To set up IFooCallback
from version 1.0 of package
android.hardware.foo
, add
android.hardware.foo-V1.0-java
to Android.mk
. The code
to run the service is:
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);
Assuming a given service implements an interface IFoo
across all
devices, it's possible that on a particular device the service may provide
additional capabilities implemented in an interface extension
IBetterFoo
, i.e.:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Calling code aware of the extended interface can use the
castFrom()
Java method to safely cast the base interface to the
extended interface:
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. }