การสร้างอินเทอร์เฟซ HAL

คุณต้องใช้ HIDL เพื่ออธิบายแฟล็กบิลด์ทั้งหมดที่ใช้สำหรับการรวบรวมเฟรมเวิร์กแบบมีเงื่อนไข แฟล็กบิลด์ที่เกี่ยวข้องต้องถูกจัดกลุ่มและรวมไว้ในไฟล์ .hal ไฟล์เดียว การใช้ HIDL เพื่อระบุรายการการกำหนดค่ามีข้อดีดังต่อไปนี้:

  • มีเวอร์ชันแล้ว (หากต้องการเพิ่มรายการกำหนดค่าใหม่ ผู้จำหน่าย/OEM จะต้องขยาย HAL อย่างชัดเจน)
  • มีเอกสารอย่างดี
  • การควบคุมการเข้าถึงโดยใช้ SELinux
  • การตรวจสอบสภาพสำหรับรายการการกำหนดค่าผ่าน ชุดทดสอบผู้ขาย (การตรวจสอบช่วง การตรวจสอบการพึ่งพาระหว่างรายการ ฯลฯ)
  • API ที่สร้างขึ้นอัตโนมัติทั้งใน C++ และ Java

การระบุแฟล็กบิลด์ที่ใช้โดยเฟรมเวิร์ก

เริ่มต้นด้วยการระบุการกำหนดค่าบิวด์ที่ใช้ในการคอมไพล์เฟรมเวิร์กตามเงื่อนไข จากนั้นละทิ้งการกำหนดค่าที่ล้าสมัยเพื่อทำให้ชุดมีขนาดเล็กลง ตัวอย่างเช่น ชุดของแฟล็ก build ต่อไปนี้จะถูกระบุสำหรับ 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

การสร้างอินเทอร์เฟซ HAL

การกำหนดค่าบิวด์สำหรับระบบย่อยสามารถเข้าถึงได้ผ่านอินเทอร์เฟซ HAL ในขณะที่อินเทอร์เฟซสำหรับการกำหนดค่าจะถูกจัดกลุ่มไว้ในแพ็คเกจ HAL android.hardware.configstore (ปัจจุบันเป็นเวอร์ชัน 1.0) ตัวอย่างเช่น หากต้องการสร้างไฟล์อินเทอร์เฟซ HAL สำหรับ surfaceflinger ใน hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal :

package android.hardware.configstore@1.0;

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

หลังจากสร้างไฟล์ .hal แล้ว ให้รัน hardware/interfaces/update-makefiles.sh เพื่อเพิ่มไฟล์ .hal ใหม่ลงในไฟล์ Android.bp และ Android.mk

การเพิ่มฟังก์ชันสำหรับการสร้างแฟล็ก

สำหรับแต่ละแฟล็ก build ให้เพิ่มฟังก์ชันใหม่ให้กับอินเทอร์เฟซ ตัวอย่างเช่น ใน 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);
};

เมื่อเพิ่มฟังก์ชัน:

  • กระชับกับชื่อ หลีกเลี่ยงการแปลงชื่อตัวแปร makefile เป็นชื่อฟังก์ชัน และโปรดจำไว้ว่าคำนำหน้า TARGET_ และ BOARD_ นั้นไม่จำเป็นอีกต่อไป
  • เพิ่มความคิดเห็น ช่วยให้นักพัฒนาเข้าใจวัตถุประสงค์ของรายการกำหนดค่า การเปลี่ยนแปลงพฤติกรรมของเฟรมเวิร์ก ค่าที่ถูกต้อง และข้อมูลอื่นๆ ที่เกี่ยวข้อง

ประเภทการส่งคืนฟังก์ชันสามารถเป็น Optional[Bool|String|Int32|UInt32|Int64|UInt64] ประเภทถูกกำหนดไว้ใน types.hal ในไดเร็กทอรีเดียวกันและรวมค่าดั้งเดิมด้วยฟิลด์ที่ระบุว่าค่านั้นถูกระบุโดย HAL หรือไม่ ถ้าไม่เช่นนั้น จะใช้ค่าเริ่มต้น

struct OptionalString {
    bool specified;
    string value;
};

เมื่อเหมาะสม ให้กำหนดแจงนับที่แสดงถึงประเภทของรายการการกำหนดค่าได้ดีที่สุด และใช้แจงนับนั้นเป็นประเภทการส่งคืน ในตัวอย่างข้างต้น NumBuffers enum ถูกกำหนดให้จำกัดจำนวนค่าที่ถูกต้อง เมื่อกำหนดประเภทข้อมูลที่กำหนดเอง ให้เพิ่มฟิลด์หรือค่าแจงนับ (เช่น USE_DEFAULT ) เพื่อแสดงว่าค่านั้น/ไม่ได้ระบุโดย HAL

ไม่จำเป็นสำหรับแฟล็ก build เดียวที่จะกลายเป็นฟังก์ชันเดียวใน HIDL เจ้าของโมดูลสามารถรวมแฟล็กบิลด์ที่เกี่ยวข้องอย่างใกล้ชิดลงในโครงสร้างและมีฟังก์ชันที่ส่งคืนโครงสร้างนั้น (การทำเช่นนี้สามารถลดจำนวนการเรียกใช้ฟังก์ชันได้)

ตัวอย่างเช่น ตัวเลือกสำหรับการรวมแฟล็กบิลด์สองรายการให้เป็นโครงสร้างเดียวใน hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal คือ:

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

ทางเลือกแทนฟังก์ชัน HAL เดียว

เป็นทางเลือกแทนการใช้ฟังก์ชัน HAL เดียวสำหรับแฟล็กบิวด์ทั้งหมด อินเทอร์เฟซ HAL ยังมีฟังก์ชันง่ายๆ เช่น getBoolean(string key) และ getInteger(string key) คู่ key=value จริงจะถูกจัดเก็บไว้ในไฟล์แยกกัน และบริการ HAL จะให้ค่าโดยการอ่าน/แยกวิเคราะห์ไฟล์เหล่านั้น

แม้ว่าวิธีนี้จะกำหนดได้ง่าย แต่ก็ไม่ได้รวมข้อดีที่ได้รับจาก HIDL (การกำหนดเวอร์ชันที่บังคับใช้ ความง่ายในการจัดทำเอกสาร การควบคุมการเข้าถึง) ดังนั้นจึงไม่แนะนำ

อินเทอร์เฟซเดียวและหลายอินเทอร์เฟซ

การออกแบบอินเทอร์เฟซ HAL สำหรับรายการการกำหนดค่ามีสองทางเลือก:

  • อินเทอร์เฟซเดียวที่ครอบคลุมรายการการกำหนดค่าทั้งหมด
  • อินเทอร์เฟซหลายรายการ ซึ่งแต่ละอินเทอร์เฟซครอบคลุมชุดของรายการการกำหนดค่าที่เกี่ยวข้อง

อินเทอร์เฟซเดียวนั้นง่ายกว่า แต่อาจไม่สามารถบำรุงรักษาได้เนื่องจากมีการเพิ่มรายการการกำหนดค่าเพิ่มเติมลงในไฟล์เดียว นอกจากนี้ การควบคุมการเข้าถึงยังไม่ละเอียด ดังนั้นกระบวนการที่ได้รับสิทธิ์ในการเข้าถึงอินเทอร์เฟซจึงสามารถอ่านรายการการกำหนดค่าทั้งหมดได้ (ไม่สามารถให้สิทธิ์การเข้าถึงชุดรายการการกำหนดค่าบางส่วนได้) หรือหากไม่ได้รับอนุญาตให้เข้าถึง รายการการกำหนดค่าจะไม่สามารถอ่านได้

เนื่องจากปัญหาเหล่านี้ Android จึงใช้อินเทอร์เฟซหลายอินเทอร์เฟซที่มีอินเทอร์เฟซ HAL เดียวสำหรับกลุ่มรายการการกำหนดค่าที่เกี่ยวข้อง ตัวอย่างเช่น ISurfaceflingerConfigs สำหรับรายการการกำหนดค่าที่เกี่ยวข้องกับ surfaceflinger และ IBluetoothConfigs สำหรับรายการการกำหนดค่าที่เกี่ยวข้องกับ Bluetooth