คุณต้องใช้ HIDL เพื่ออธิบาย Flag บิลด์ทั้งหมดที่ใช้สำหรับการคอมไพล์เฟรมเวิร์กอย่างมีเงื่อนไข คุณจะต้องจัดกลุ่มแฟล็กบิลด์ที่เกี่ยวข้องและรวมไว้ในไฟล์ .hal
ไฟล์เดียว การใช้ HIDL เพื่อระบุรายการการกำหนดค่า
มีประโยชน์ดังนี้
- เวอร์ชัน (เพื่อเพิ่มรายการการกำหนดค่าใหม่ ผู้ให้บริการ/OEM ต้องขยาย HAL อย่างชัดแจ้ง)
- มีเอกสารประกอบอย่างละเอียด
- การควบคุมการเข้าถึงโดยใช้ SELinux
- การตรวจสอบความเรียบร้อยของรายการการกำหนดค่าผ่านชุดทดสอบของผู้ให้บริการ (การตรวจสอบช่วง การตรวจสอบการขึ้นต่อกันระหว่างรายการต่างๆ ฯลฯ)
- API ที่สร้างขึ้นโดยอัตโนมัติทั้งใน C++ และ Java
ระบุแฟล็กบิลด์ที่เฟรมเวิร์กใช้
เริ่มต้นด้วยการระบุการกำหนดค่าบิลด์ที่ใช้ในการคอมไพล์เฟรมเวิร์กอย่างมีเงื่อนไข จากนั้นยกเลิกการกำหนดค่าที่ล้าสมัยเพื่อทำให้ชุดมีขนาดเล็กลง ตัวอย่างเช่น มีการระบุชุด Flag บิลด์ต่อไปนี้สำหรับ 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 และมีฟังก์ชันที่แสดงผลโครงสร้างนั้น (การทำเช่นนี้สามารถลดจำนวนการเรียกใช้ฟังก์ชันได้)
ตัวอย่างเช่น ตัวเลือกสำหรับการรวม 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 ยังมีฟังก์ชันง่ายๆ เช่น getBoolean(string
key)
และ getInteger(string key)
แทนการใช้ฟังก์ชัน HAL เดียวสำหรับแฟล็กบิลด์ทั้งหมด คู่ key=value
จริงจะจัดเก็บไว้ในไฟล์แยกต่างหาก และบริการ HAL จะระบุค่าโดยการอ่าน/แยกวิเคราะห์ไฟล์เหล่านั้น
แม้ว่าวิธีการนี้จะระบุง่าย แต่ไม่รวมถึงข้อดีของ HIDL (การกำหนดเวอร์ชันที่บังคับใช้ การจัดทำเอกสารได้ง่าย การควบคุมการเข้าถึง) ดังนั้นเราจึงไม่แนะนำ
อินเทอร์เฟซเดียวและหลายอินเทอร์เฟซ
การออกแบบอินเทอร์เฟซ HAL สำหรับรายการการกำหนดค่ามี 2 ตัวเลือก ดังนี้
- อินเทอร์เฟซเดียวที่ครอบคลุมรายการการกำหนดค่าทั้งหมด
- อินเทอร์เฟซหลายรายการ แต่ละอินเทอร์เฟซจะครอบคลุมชุดรายการการกำหนดค่าที่เกี่ยวข้อง
อินเทอร์เฟซเดียวนั้นทำได้ง่ายกว่าแต่อาจจัดการไม่ได้เมื่อมีการเพิ่มรายการการกำหนดค่าลงในไฟล์เดียว นอกจากนี้ การควบคุมการเข้าถึงไม่ได้มีความละเอียด ดังนั้นกระบวนการที่ให้สิทธิ์เข้าถึงอินเทอร์เฟซจะอ่านรายการการกำหนดค่าทั้งหมดได้ (ไม่อาจให้สิทธิ์เข้าถึงชุดรายการการกำหนดค่าเพียงบางส่วนได้) ไม่เช่นนั้นหากไม่ได้รับสิทธิ์เข้าถึง รายการการกำหนดค่าจะไม่สามารถอ่านได้
ด้วยเหตุนี้ Android จึงใช้อินเทอร์เฟซหลายรายการที่มีอินเทอร์เฟซ HAL เดียวสำหรับกลุ่มรายการการกำหนดค่าที่เกี่ยวข้อง ตัวอย่างเช่น ISurfaceflingerConfigs
สำหรับรายการการกำหนดค่าที่เกี่ยวข้องกับ surfaceflinger
และ IBluetoothConfigs
สำหรับรายการการกำหนดค่าที่เกี่ยวข้องกับบลูทูธ