HAL arayüzünü oluşturma

Çerçeveyi koşullu olarak derlemek için kullanılan tüm derleme işaretlerini açıklamak üzere HIDL'yi kullanmanız gerekir. İlgili derleme işaretleri gruplandırılmalı ve tek bir .hal dosyasına eklenmelidir. Yapılandırma öğelerini belirtmek için HIDL kullanmanın aşağıdaki avantajları vardır:

  • Sürümlendirilmiş (yeni yapılandırma öğeleri eklemek için satıcılar/OEM'ler HAL'yi açıkça genişletmelidir)
  • İyi belgelenmiş
  • SELinux kullanarak erişim denetimi
  • Tedarikçi Test Paketi aracılığıyla yapılandırma öğeleri için uygunluk kontrolü (aralık kontrolü, öğeler arasında karşılıklı bağımlılık kontrolü vb.)
  • Hem C++ hem de Java'da otomatik olarak oluşturulan API'ler

Çerçeve tarafından kullanılan derleme işaretlerini belirleme

Öncelikle çerçeveyi koşullu olarak derlemek için kullanılan derleme yapılandırmalarını belirleyin, ardından grubu küçültmek için eski yapılandırmaları kaldırın. Örneğin, surfaceflinger için aşağıdaki derleme işaretleri grubu tanımlanır:

  • 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

HAL arayüzü oluşturma

Bir alt sistemin derleme yapılandırmalarına HAL arayüzü üzerinden erişilirken yapılandırma değerleri sağlayan arayüzler HAL paketinde android.hardware.configstore (şu anda 1.0 sürümünde) gruplandırılır. Örneğin, surfaceflinger için bir HAL arayüzü dosyası oluşturmak üzere hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal içinde:

package android.hardware.configstore@1.0;

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

.hal dosyasını oluşturduktan sonra, yeni .hal dosyasını Android.bp ve Android.mk dosyalarına eklemek için hardware/interfaces/update-makefiles.sh komutunu çalıştırın.

Derleme işaretleri için işlevler ekleme

Her derleme işareti için arayüze yeni bir işlev ekleyin. Örneğin, 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);
};

İşlev eklerken:

  • Adları kısa tutun. Makefile değişken adlarını işlev adlarına dönüştürmekten kaçının ve TARGET_ ile BOARD_ ön eklerinin artık gerekli olmadığını unutmayın.
  • Yorum ekleyin. Geliştiricilerin yapılandırma öğesinin amacını, çerçeve davranışını nasıl değiştirdiğini, geçerli değerleri ve diğer ilgili bilgileri anlamasına yardımcı olun.

İşlev dönüş türleri şunlar olabilir: Optional[Bool|String|Int32|UInt32|Int64|UInt64]. Türler, aynı dizindeki types.hal içinde tanımlanır ve temel değerleri, değerin HAL tarafından belirtilip belirtilmediğini gösteren bir alanla sarmalar. Belirtilmemişse varsayılan değer kullanılır.

struct OptionalString {
    bool specified;
    string value;
};

Uygun olduğunda, yapılandırma öğesinin türünü en iyi şekilde temsil eden enum'ı tanımlayın ve dönüş türü olarak bu enum'ı kullanın. Yukarıdaki örnekte, geçerli değerlerin sayısını sınırlamak için NumBuffers enum'u tanımlanmıştır. Bu tür özel veri türlerini tanımlarken değerin HAL tarafından belirtilip belirtilmediğini belirtmek için bir alan veya enum değeri (örneğin, USE_DEFAULT) ekleyin.

Tek bir derleme işaretinin HIDL'de tek bir işlev haline gelmesi zorunlu değildir. Alternatif olarak, modül sahipleri yakından ilişkili derleme işaretlerini bir yapıda toplayabilir ve bu yapıyı döndüren bir işlev oluşturabilir (bunu yapmak işlev çağrılarının sayısını azaltabilir).

Örneğin, iki derleme işaretini tek bir yapıda toplama seçeneği hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal şöyledir:

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

Tek bir HAL işlevinin alternatifleri

Tüm derleme işaretleri için tek bir HAL işlevi kullanmak yerine, HAL arayüzü getBoolean(string key) ve getInteger(string key) gibi basit işlevler de sağlar. Gerçek key=value çiftleri ayrı dosyalarda saklanır ve HAL hizmeti, bu dosyaları okuyarak/ayrıştırarak değerler sağlar.

Bu yaklaşımı tanımlamak kolay olsa da HIDL'nin sağladığı avantajları (sürüm oluşturmanın zorunlu kılınması, dokümantasyon kolaylığı, erişim kontrolü) içermediğinden önerilmez.

Tek ve çoklu arayüzler

Yapılandırma öğeleri için HAL arayüzünün tasarımında iki seçenek sunulur:

  • Tüm yapılandırma öğelerini kapsayan tek bir arayüz
  • Her biri bir dizi ilgili yapılandırma öğesini kapsayan birden fazla arayüz

Tek bir arayüz daha kolaydır ancak tek dosyaya daha fazla yapılandırma öğesi eklendikçe bakımı zorlaşabilir. Ayrıca, erişim denetimi ayrıntılı olmadığından arayüze erişim izni verilen bir işlem tüm yapılandırma öğelerini okuyabilir (yapılandırma öğelerinin bir kısmına erişim izni verilemez). Alternatif olarak, erişim verilmezse yapılandırma öğeleri okunamayabilir.

Bu sorunlar nedeniyle Android, bir grup ilgili yapılandırma öğesi için tek bir HAL arayüzüyle birden fazla arayüz kullanır. Örneğin, ISurfaceflingerConfigs surfaceflinger ile ilgili yapılandırma öğeleri ve IBluetoothConfigs Bluetooth ile ilgili yapılandırma öğeleri için kullanılır.