HIDL is built around interfaces, an abstract type used in object-oriented languages to define behaviors. Each interface is part of a package.

Packages

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.

Interface definition

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:

Importing

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:

The importing entity gets access to a combination of:

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

Interface inheritance

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.

Vendor extensions

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.

Versioning

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.