Membuat antarmuka HAL

Anda harus menggunakan HIDL untuk menjelaskan semua flag build yang digunakan untuk mengompilasi framework secara bersyarat. Tanda build yang relevan harus dikelompokkan dan disertakan dalam satu file .hal. Penggunaan HIDL untuk menentukan item konfigurasi mencakup manfaat berikut:

  • Berversi (untuk menambahkan item konfigurasi baru, vendor/OEM harus secara eksplisit memperluas HAL)
  • Terdokumentasi dengan baik
  • Kontrol akses menggunakan SELinux
  • Pemeriksaan kesehatan untuk item konfigurasi melalui Vendor Test Suite (pemeriksaan rentang, pemeriksaan inter-dependensi antara item, dll.)
  • API yang dibuat secara otomatis di C++ dan Java

Mengidentifikasi flag build yang digunakan oleh framework

Mulai dengan mengidentifikasi konfigurasi build yang digunakan untuk mengompilasi framework secara bersyarat, lalu tinggalkan konfigurasi yang tidak digunakan lagi untuk memperkecil kumpulan. Misalnya, kumpulan tanda build berikut diidentifikasi untuk surfaceflinger:

  • TARGET_USES_HWC2
  • TARGET_BOARD_PLATFORM
  • TARGET_DISABLE_TRIPLE_BUFFERING
  • TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
  • NUM_FRAMEBUFFER_SURFACE_BUFFERS
  • TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK
  • VSYNC_EVENT_PHASE_OFFSET_NS
  • SF_VSYNC_EVENT_PHASE_OFFSET_NS
  • PRESENT_TIME_OFFSET_FROM_VSYNC_NS
  • MAX_VIRTUAL_DISPLAY_DIMENSION

Membuat antarmuka HAL

Konfigurasi build untuk subsistem diakses melalui antarmuka HAL, sedangkan antarmuka untuk memberikan nilai konfigurasi dikelompokkan dalam paket HAL android.hardware.configstore (saat ini versi 1.0). Misalnya, untuk membuat file antarmuka HAL untuk surfaceflinger, di hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal:

package android.hardware.configstore@1.0;

interface ISurfaceFlingerConfigs {
    // TO-BE-FILLED-BELOW
};

Setelah membuat file .hal, jalankan hardware/interfaces/update-makefiles.sh untuk menambahkan file .hal baru ke file Android.bp dan Android.mk.

Menambahkan fungsi untuk tanda build

Untuk setiap flag build, tambahkan fungsi baru ke antarmuka. Misalnya, dalam hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal:

interface ISurfaceFlingerConfigs {
    disableTripleBuffering() generates(OptionalBool ret);
    forceHwcForVirtualDisplays() generates(OptionalBool ret);
    enum NumBuffers: uint8_t {
        USE_DEFAULT = 0,
        TWO = 2,
        THREE = 3,
    };
    numFramebufferSurfaceBuffers() generates(NumBuffers ret);
    runWithoutSyncFramework() generates(OptionalBool ret);
    vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret);
    presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret);
    maxVirtualDisplayDimension() generates(OptionalInt32 ret);
};

Saat menambahkan fungsi:

  • Sampaikan nama dengan ringkas. Hindari mengonversi nama variabel makefile menjadi nama fungsi dan perlu diingat bahwa awalan TARGET_ dan BOARD_ tidak lagi diperlukan.
  • Menambahkan komentar. Membantu developer memahami tujuan item konfigurasi, caranya mengubah perilaku framework, nilai yang valid, dan informasi relevan lainnya.

Jenis nilai yang ditampilkan fungsi dapat berupa Optional[Bool|String|Int32|UInt32|Int64|UInt64]. Jenis ditentukan dalam types.hal pada direktori yang sama dan menggabungkan nilai primitif dengan kolom yang menunjukkan apakah nilai ditentukan oleh HAL; jika tidak, nilai default akan digunakan.

struct OptionalString {
    bool specified;
    string value;
};

Jika sesuai, tentukan enum yang paling mewakili jenis item konfigurasi dan gunakan enum tersebut sebagai jenis nilai yang ditampilkan. Pada contoh di atas, enum NumBuffers ditentukan untuk membatasi jumlah nilai yang valid. Saat menentukan jenis data kustom tersebut, tambahkan kolom atau nilai enum (misalnya, USE_DEFAULT) untuk menunjukkan apakah nilai tersebut ditentukan oleh HAL atau tidak.

Satu flag build tidak harus menjadi fungsi tunggal di HIDL. Pemilik modul juga dapat menggabungkan flag build yang terkait erat ke dalam struct dan memiliki fungsi yang menampilkan struct tersebut (tindakan ini dapat mengurangi jumlah panggilan fungsi).

Misalnya, opsi untuk menggabungkan dua flag build menjadi satu struct di hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal adalah:

 interface ISurfaceFlingerConfigs {
    // other functions here
    struct SyncConfigs {
        OptionalInt64 vsyncEventPhaseoffsetNs;
        OptionalInt64 presentTimeoffsetFromSyncNs;
    };
    getSyncConfigs() generates (SyncConfigs ret);
    // other functions here
};

Alternatif untuk fungsi HAL tunggal

Sebagai alternatif penggunaan fungsi HAL tunggal untuk semua tanda build, antarmuka HAL juga menyediakan fungsi sederhana seperti getBoolean(string key) dan getInteger(string key). Pasangan key=value aktual disimpan dalam file terpisah dan layanan HAL memberikan nilai dengan membaca/mengurai file tersebut.

Meskipun mudah ditentukan, pendekatan ini tidak menyertakan manfaat yang diberikan oleh HIDL (pembuatan versi diterapkan, kemudahan dokumentasi, kontrol akses) sehingga tidak direkomendasikan.

Satu dan beberapa antarmuka

Desain antarmuka HAL untuk item konfigurasi menghadirkan dua pilihan:

  • Satu antarmuka yang mencakup semua item konfigurasi
  • Beberapa antarmuka, yang masing-masing mencakup sekumpulan item konfigurasi terkait

Satu antarmuka lebih mudah, tetapi dapat menjadi tidak dapat dikelola karena lebih banyak item konfigurasi ditambahkan ke satu file. Selain itu, kontrol akses tidak terperinci, sehingga proses yang diberi akses ke antarmuka dapat membaca semua item konfigurasi (akses ke sebagian kumpulan item konfigurasi tidak dapat diberikan). Atau, jika akses tidak diberikan, item konfigurasi tidak dapat dibaca.

Karena masalah ini, Android menggunakan beberapa antarmuka dengan satu antarmuka HAL untuk grup item konfigurasi terkait. Misalnya, ISurfaceflingerConfigs untuk item konfigurasi terkait surfaceflinger, dan IBluetoothConfigs untuk item konfigurasi terkait Bluetooth.