คุณต้องใช้ HIDL เพื่ออธิบาย Flag การสร้างทั้งหมดที่ใช้สำหรับการคอมไพล์เฟรมเวิร์กแบบมีเงื่อนไข ต้องจัดกลุ่มและรวม Flag การสร้างที่เกี่ยวข้องไว้ในไฟล์ .hal
ไฟล์เดียว การใช้ HIDL เพื่อระบุรายการการกําหนดค่ามีข้อดีดังนี้
- มีเวอร์ชัน (หากต้องการเพิ่มรายการการกําหนดค่าใหม่ ผู้ขาย/OEM ต้องขยาย HAL อย่างชัดเจน)
- มีเอกสารประกอบอย่างดี
- การควบคุมการเข้าถึงโดยใช้ SELinux
- การตรวจสอบความถูกต้องของรายการการกําหนดค่าผ่านชุดทดสอบผู้ให้บริการ (การตรวจสอบช่วง การตรวจสอบความเกี่ยวข้องระหว่างรายการต่างๆ เป็นต้น)
- API ที่สร้างขึ้นโดยอัตโนมัติทั้งใน C++ และ Java
ระบุ Flag การสร้างที่เฟรมเวิร์กใช้
เริ่มต้นด้วยการระบุการกำหนดค่าบิลด์ที่ใช้คอมไพล์เฟรมเวิร์กแบบมีเงื่อนไข จากนั้นทิ้งการกำหนดค่าที่ล้าสมัยเพื่อให้ชุดมีขนาดเล็กลง ตัวอย่างเช่น ระบบจะระบุชุด 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 ส่วนอินเทอร์เฟซสําหรับระบุค่าการกําหนดค่าจะจัดกลุ่มไว้ในแพ็กเกจ HALandroid.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
เพิ่มฟังก์ชันสําหรับ Flag การสร้าง
เพิ่มฟังก์ชันใหม่ลงในอินเทอร์เฟซสำหรับ Flag การสร้างแต่ละรายการ ตัวอย่างเช่น ใน 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); };
เมื่อเพิ่มฟังก์ชัน
- ใช้ชื่อที่กระชับ หลีกเลี่ยงการแปลงชื่อตัวแปรของไฟล์ make เป็นชื่อฟังก์ชัน และอย่าลืมว่าไม่จำเป็นต้องใช้คำนำหน้า
TARGET_
และBOARD_
อีกต่อไป - เพิ่มความคิดเห็น ช่วยให้นักพัฒนาซอฟต์แวร์เข้าใจวัตถุประสงค์ของรายการการกําหนดค่า วิธีเปลี่ยนลักษณะการทํางานของเฟรมเวิร์ก ค่าที่ถูกต้อง และข้อมูลอื่นๆ ที่เกี่ยวข้อง
ประเภทผลลัพธ์ของฟังก์ชันอาจเป็น Optional[Bool|String|Int32|UInt32|Int64|UInt64]
ระบบจะกำหนดประเภทใน types.hal
ในไดเรกทอรีเดียวกันและรวมค่าพื้นฐานไว้กับช่องที่ระบุว่า HAL ระบุค่าหรือไม่ หากไม่ได้ระบุ ระบบจะใช้ค่าเริ่มต้น
struct OptionalString { bool specified; string value; };
เมื่อเหมาะสม ให้กําหนด enum ที่แสดงถึงประเภทของรายการการกําหนดค่าได้ดีที่สุด และใช้ enum นั้นเป็นประเภทผลลัพธ์ ในตัวอย่างข้างต้น ระบบจะกำหนด NumBuffers
enum เพื่อจำกัดจำนวนค่าที่ถูกต้อง เมื่อกำหนดประเภทข้อมูลที่กำหนดเองดังกล่าว ให้เพิ่มฟิลด์หรือค่า Enum (เช่น USE_DEFAULT
) เพื่อระบุว่า HAL ระบุค่าหรือไม่
คุณไม่จำเป็นต้องกำหนดให้ Flag การสร้างรายการเดียวกลายเป็นฟังก์ชันเดียวใน HIDL เจ้าของโมดูลสามารถรวบรวม Flag การสร้างที่เกี่ยวข้องอย่างใกล้ชิดไว้ในสตรูคเจอร์และมีฟังก์ชันที่แสดงผลสตรูคเจอร์นั้น (การดำเนินการดังกล่าวจะช่วยลดจํานวนการเรียกใช้ฟังก์ชัน)
ตัวอย่างเช่น ตัวเลือกในการรวบรวม Flag การสร้าง 2 รายการไว้ใน Struct เดียวใน 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 เดียวสำหรับ Flag การสร้างทั้งหมด ระบบจะจัดเก็บคู่จริงของ key=value
ไว้ในไฟล์แยกต่างหาก และบริการ HAL จะระบุค่าโดยการอ่าน/แยกวิเคราะห์ไฟล์เหล่านั้น
แม้ว่าวิธีนี้จะกำหนดได้ง่าย แต่ก็ไม่ได้ให้ประโยชน์ที่ HIDL มีให้ (การกำหนดเวอร์ชันที่บังคับใช้ ความสะดวกในการจัดทำเอกสาร การควบคุมการเข้าถึง) เราจึงไม่แนะนำให้ใช้
อินเทอร์เฟซเดียวและหลายอินเทอร์เฟซ
การออกแบบอินเทอร์เฟซ HAL สําหรับรายการการกําหนดค่ามี 2 ตัวเลือก ดังนี้
- อินเทอร์เฟซเดียวที่ครอบคลุมรายการการกําหนดค่าทั้งหมด
- อินเทอร์เฟซหลายรายการ ซึ่งแต่ละรายการครอบคลุมชุดรายการการกําหนดค่าที่เกี่ยวข้อง
อินเทอร์เฟซเดียวจะใช้งานได้ง่ายกว่า แต่อาจทำให้ดูแลรักษาไม่ได้เมื่อเพิ่มรายการการกําหนดค่าลงในไฟล์เดียว นอกจากนี้ การควบคุมการเข้าถึงไม่ได้เป็นแบบละเอียด ดังนั้นกระบวนการที่ได้รับสิทธิ์เข้าถึงอินเทอร์เฟซจะอ่านรายการการกําหนดค่าทั้งหมดได้ (ไม่สามารถให้สิทธิ์เข้าถึงรายการการกําหนดค่าบางส่วนได้) หรือหากไม่ได้รับสิทธิ์เข้าถึง คุณจะอ่านรายการการกําหนดค่าไม่ได้
ปัญหาเหล่านี้ทำให้ Android ใช้อินเทอร์เฟซหลายรายการกับอินเทอร์เฟซ HAL เดียวสําหรับกลุ่มรายการการกําหนดค่าที่เกี่ยวข้อง เช่น ISurfaceflingerConfigs
สำหรับรายการการกําหนดค่าที่เกี่ยวข้องกับ surfaceflinger
และ IBluetoothConfigs
สำหรับรายการการกําหนดค่าที่เกี่ยวข้องกับบลูทูธ