レガシーHAL

HAL は、ハードウェア ベンダーが実装する標準インターフェースを定義します。これにより、Android は下位レベルのドライバーの実装にとらわれなくなります。 HAL を使用すると、上位レベルのシステムに影響を与えたり変更したりせずに機能を実装できます。このページでは、Android 8.0 でサポートされなくなった古いアーキテクチャについて説明します。 Android 8.0 以降については、 HAL タイプを参照してください。

HAL コンポーネント

図 1. HAL コンポーネント

製品が提供する特定のハードウェアに対応する HAL (およびドライバー) を実装する必要があります。通常、HAL 実装は共有ライブラリ モジュール ( .soファイル) に組み込まれますが、Android では HAL 実装とデバイス ドライバーとの間の標準的な対話が義務付けられていないため、状況に最適な方法を実行できます。ただし、Android システムがハードウェアと正しくやり取りできるようにするには、各ハードウェア固有の HAL インターフェースで定義されている契約に従う必要があります。

HAL が予測可能な構造を持つことを保証するために、各ハードウェア固有の HAL インターフェイスには、 hardware/libhardware/include/hardware/hardware.hで定義されたプロパティがあります。このインターフェースにより、Android システムは正しいバージョンの HAL モジュールを一貫した方法でロードできます。 HAL インターフェイスは、モジュールとデバイスの 2 つのコンポーネントで構成されます。

HAL モジュール

モジュールは、パッケージ化された HAL 実装を表し、共有ライブラリ ( .so file ) として保存されます。 hardware/libhardware/include/hardware/hardware.hヘッダー ファイルは、モジュールを表し、モジュールのバージョン、名前、作成者などのメタデータを含む構造体 ( hw_module_t ) を定義します。 Android はこのメタデータを使用して、HAL モジュールを正しく見つけてロードします。

さらに、 hw_module_t構造体には、モジュールのオープン関数へのポインターを含む別の構造体hw_module_methods_tへのポインターが含まれています。このオープン関数は、HAL が抽象化として機能しているハードウェアとの通信を開始するために使用されます。各ハードウェア固有の HAL は通常、汎用のhw_module_t構造体を、その特定のハードウェアの追加情報で拡張します。たとえば、カメラ HAL では、 camera_module_t構造体には、他のカメラ固有の関数ポインターと共にhw_module_t構造体が含まれています。

typedef struct camera_module {
    hw_module_t common;
    int (*get_number_of_cameras)(void);
    int (*get_camera_info)(int camera_id, struct camera_info *info);
} camera_module_t;

HAL を実装してモジュール構造体を作成するときは、 HAL_MODULE_INFO_SYMという名前を付ける必要があります。 Nexus 9 オーディオ HAL の例:

struct audio_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = AUDIO_HARDWARE_MODULE_ID,
        .name = "NVIDIA Tegra Audio HAL",
        .author = "The Android Open Source Project",
        .methods = &hal_module_methods,
    },
};

HAL デバイス

デバイスは、製品のハードウェアを抽象化します。たとえば、オーディオ モジュールには、プライマリ オーディオ デバイス、USB オーディオ デバイス、または Bluetooth A2DP オーディオ デバイスを含めることができます。

デバイスはhw_device_t構造体で表されます。モジュールと同様に、各タイプのデバイスは、ハードウェアの特定の機能に対する関数ポインターを含む汎用hw_device_tの詳細バージョンを定義します。たとえば、 audio_hw_device_t構造体型には、オーディオ デバイス操作への関数ポインターが含まれています。

struct audio_hw_device {
    struct hw_device_t common;

    /**
     * used by audio flinger to enumerate what devices are supported by
     * each audio_hw_device implementation.
     *
     * Return value is a bitmask of 1 or more values of audio_devices_t
     */
    uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
  ...
};
typedef struct audio_hw_device audio_hw_device_t;

これらの標準プロパティに加えて、各ハードウェア固有の HAL インターフェイスは、独自の機能と要件をさらに定義できます。詳細については、 HAL リファレンス ドキュメントと、各 HAL の個別の手順を参照してください。

HAL モジュールの構築

HAL 実装はモジュール ( .so ) ファイルに組み込まれ、必要に応じて Android によって動的にリンクされます。 HAL 実装ごとにAndroid.mkファイルを作成し、ソース ファイルを指定することで、モジュールを構築できます。一般に、共有ライブラリは特定の形式で名前を付けて、適切に見つけてロードできるようにする必要があります。命名スキームはモジュールごとにわずかに異なりますが、 <module_type>.<device_name>の一般的なパターンに従います。

従来の HAL

レガシー HAL という用語は、Android 8.0 より前のすべての HAL (Android 8 で非推奨) を広く指します。大部分の Android システム インターフェース (カメラ、オーディオ、センサーなど) は、`hardware/libhardware/include/hardware` で定義されており、大まかなバージョン管理とほぼ安定した ABI を備えています。一部のサブシステム (Wi-Fi、無線インターフェイス層、Bluetooth など) には、「libhardware_legacy」に標準化されていない他のインターフェイスがあるか、コードベース全体に散在しています。従来の HAL では、ハードな安定性が保証されることはありませんでした。