HAL arayüzünü oluşturma

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

  • Sürümlü (yeni yapılandırma öğeleri eklemek için tedarikçiler/OEM'ler HAL'i açıkça genişletmelidir)
  • İyi belgelenmiş
  • SELinux'u kullanarak erişim denetimi
  • Tedarikçi Test Paketi aracılığıyla yapılandırma öğeleri için doğruluk kontrolü (aralık kontrolü, öğeler arasındaki 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 tanımlama

Çerçeveyi koşullu olarak derlemek için kullanılan derleme yapılandırmalarını tanımlayarak başlayın, ardından grubu daha küçük hale getirmek için eski yapılandırmaları kaldırın. Örneğin, surfaceflinger için aşağıdaki derleme işaretleri belirlenir:

  • 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

Alt sistem için derleme yapılandırmalarına HAL arayüzünden erişilir. Yapılandırma değerlerini vermek için kullanılan arayüzler ise android.hardware.configstore (şu anda sürüm 1.0'da) içinde gruplandırılır. Örneğin, hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal konumunda surfaceflinger için bir HAL arayüz dosyası oluşturmak amacıyla:

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'yi çalıştırın.

Derleme işaretleri için işlev 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 ve öz 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 alakalı bilgileri anlamalarına yardımcı olun.

İşlevlerin döndürdüğü türler Optional[Bool|String|Int32|UInt32|Int64|UInt64] olabilir. Türler aynı dizinde types.hal içinde tanımlanır ve ilkel değerleri, değerin HAL tarafından belirtilip belirtilmediğini belirten bir alanla sarmalanır. Aksi takdirde 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'u tanımlayın ve bu enum'u döndürülen tür olarak kullanın. Yukarıdaki örnekte, geçerli değer sayısını sınırlamak için NumBuffers enum 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 sıralama değeri (örneğin, USE_DEFAULT) ekleyin.

Tek bir derleme işaretinin HIDL'de tek bir işlev haline gelmesi zorunlu değildir. Modül sahipleri, yakın ilişkili derleme işaretlerini bir yapı içinde toplayabilir ve bu yapıyı döndüren bir işleve sahip olabilir (Böylece işlev çağrılarının sayısını azaltabilir).

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

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

Tek bir HAL işlevinin alternatifleri

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

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

Tek ve çoklu arayüzler

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

  • 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 bir dosyaya daha fazla yapılandırma öğesi eklendikçe bakımı zor hale gelebilir. 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 izni verilmezse yapılandırma öğeleri okunamaz.

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