HIDL is built around interfaces, an abstract type used in object-oriented languages to define behaviors. Each interface is part of a package.
Package names can have sublevels such as package.subpackage
. The
root directory for published HIDL packages is hardware/interfaces
or vendor/vendorName
(e.g. vendor/google
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,
package android.hardware.example.extension.light@2.0
could be found
under hardware/interfaces/example/extension/light/2.0
.
The following table lists package prefixes and locations:
Package Prefix | Location |
---|---|
android.hardware.* |
hardware/interfaces/* |
android.frameworks.* |
frameworks/hardware/interfaces/* |
android.system.* |
system/hardware/interfaces/* |
android.hidl.* |
system/libhidl/transport/* |
The package directory contains files with extension .hal
. Every
file must contain a package
statement naming the package and
version the file is part of. The file types.hal
, if present, does
not define an interface but instead defines data types accessible to every
interface in the package.
Aside from types.hal
, every other .hal
file defines
an interface. For example, an interface is typically defined as follows:
interface IBar extends IFoo { // IFoo is another interface // embedded types struct MyStruct {/*...*/}; // interface methods create(int32_t id) generates (MyStruct s); close(); };
An interface without an explicit extends
declaration implicitly
extends from android.hidl.base@1.0::IBase
(similar to
java.lang.Object
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:
ping
interfaceChain
interfaceDescriptor
notifySyspropsChanged
linkToDeath
unlinkToDeath
setHALInstrumentation
getDebugInfo
debug
getHashChain
The import
statement is HIDL mechanism to access package
interfaces and types in another package. An import
statement
concerns itself with two entities:
The importing entity is determined by the location of the
import
statement. When the statement is inside a package's
types.hal
, what is being imported is visible by the entire package;
this is a package-level import. When the statement is inside an
interface file, the importing entity is the interface itself; this is an
interface-level import.
The imported entity is determined by the value after the import
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:
types.hal
and that
interface are imported into the importing entity.types.hal
, then only that UDT
is imported into the importing entity (other types in types.hal
are
not imported).types
instead
of an Interface name, only the UDTs in types.hal
of the designated
package are imported.The importing entity gets access to a combination of:
types.hal
;The import statement uses the fully-qualified-type-name syntax to provide the name and version of the package or interface being imported:
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
An interface can be an extension of a previously-defined interface. Extensions can be one of the following three types:
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
IBar
in version 4.0 of package derivative
is based on
(extends) an interface IFoo
in version 1.2 of package
original
, and a version 1.3 of package original
is
created, IBar
version 4.1 cannot extend version 1.3 of
IFoo
. Instead, IBar
version 4.1 must extend
IBar
version 4.0, which is tied to IFoo
version 1.2.
IBar
version 5.0 could extend IFoo
version 1.3, if
desired.
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.
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.
Packages are versioned, and interfaces have the version of their package. Versions are expressed in two integers, major.minor.
For broader compatibility with frameworks, multiple major versions of a HAL can be present on a device simultaneously. While multiple minor versions can also be present on a device, as minor versions are backwards compatible no reason exists to support more than the latest minor version for each major version.
For more details on versioning and vendor extensions, see HIDL Versioning.