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

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

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

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

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

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

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

เมื่อเพิ่มฟังก์ชัน ให้ทำดังนี้

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

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

struct OptionalString {
    bool specified;
    string value;
};

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

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

เช่น ตัวเลือกสำหรับการรวม 2 Flag บิลด์เป็นโครงสร้างเดียว ใน 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 เดียวสำหรับ Flag บิลด์ทั้งหมดคือ HAL ยังมีฟังก์ชันอย่างง่าย เช่น getBoolean(string key) และ getInteger(string key) ฟิลด์ ระบบจะจัดเก็บ key=value คู่ไว้ในไฟล์แยกต่างหากและบริการ HAL ระบุค่าโดยการอ่าน/แยกวิเคราะห์ไฟล์เหล่านั้น

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

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

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

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

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

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