ภาษานิยามอินเทอร์เฟซ HAL หรือ HIDL เป็นภาษาคำอธิบายอินเทอร์เฟซ (IDL) สำหรับระบุ อินเทอร์เฟซระหว่าง HAL กับ ผู้ใช้ของเขา HIDL อนุญาตให้ระบุประเภทและการเรียกใช้เมธอด ซึ่งรวบรวมไว้ใน อินเทอร์เฟซและแพ็กเกจได้ โดยทั่วไป HIDL เป็นระบบสำหรับการสื่อสาร ระหว่างโค้ดเบสที่อาจคอมไพล์แยกกันได้
HIDL มีไว้เพื่อการสื่อสารระหว่างกระบวนการ (IPC) HAL ที่สร้างด้วย HDL ที่เรียกว่า Binderized HALs ที่สื่อสารกับเลเยอร์สถาปัตยกรรมอื่นๆ โดยใช้ไฟล์ Binder การสื่อสารระหว่างกระบวนการ (IPC) HAL ที่มีการเชื่อมโยงจะทำงานในกระบวนการที่แยกจากไคลเอ็นต์ ที่ใช้โค้ดเหล่านั้น สำหรับ ไลบรารีที่ต้องลิงก์กับกระบวนการ การส่งผ่าน มีโหมด ให้ใช้งานด้วย (ไม่ได้รับการสนับสนุนใน Java)
HIDL ระบุโครงสร้างข้อมูลและลายเซ็นเมธอด ซึ่งจัดระเบียบในอินเทอร์เฟซ (คล้ายกับคลาส) ซึ่งรวบรวมไว้ในแพ็กเกจ ไวยากรณ์ของ HIDL มีความคุ้นเคยสำหรับ C++ และ โปรแกรมเมอร์ Java แต่มีชุดของ คีย์เวิร์ด HIDL ยังใช้คำอธิบายประกอบแบบ Java ด้วย
คำศัพท์
ส่วนนี้ใช้คำที่เกี่ยวข้องกับ HIDL ต่อไปนี้
ถูกยึด | บ่งบอกว่ามีการใช้ HIDL สำหรับการเรียกใช้โพรซีเยอร์ระยะไกลระหว่างกระบวนการ ติดตั้งบนกลไกที่คล้ายกับ Binder ดูส่งผ่านด้วย |
---|---|
Callback, ไม่พร้อมกัน | อินเทอร์เฟซที่แสดงผลโดยผู้ใช้ HAL และส่งไปยัง HAL (โดยใช้วิธีการ HIDL) และ ซึ่ง HAL เรียกใช้เพื่อแสดงข้อมูลได้ทุกเมื่อ |
Callback, พร้อมกัน | ส่งคืนข้อมูลจากการใช้เมธอด HIDL ของเซิร์ฟเวอร์ไปยังไคลเอ็นต์ ไม่ใช้สำหรับวิธีการที่ส่งคืนค่าเป็นโมฆะหรือค่าพื้นฐานค่าเดียว |
ไคลเอ็นต์ | กระบวนการที่เรียกใช้เมธอดของอินเทอร์เฟซหนึ่งๆ เฟรมเวิร์ก HAL หรือ Android กระบวนการอาจเป็นไคลเอ็นต์ของอินเทอร์เฟซหนึ่งและเซิร์ฟเวอร์ของอีกอินเทอร์เฟซหนึ่ง ดูเพิ่มเติม Passthrough |
ขยาย | บอกถึงอินเทอร์เฟซที่เพิ่มเมธอดและ/หรือประเภทให้กับอินเทอร์เฟซอื่น อินเทอร์เฟซหนึ่งสามารถขยายอินเทอร์เฟซอื่นได้เพียงรายการเดียวเท่านั้น ใช้ได้สำหรับผู้เยาว์ เวอร์ชันที่เพิ่มขึ้นในชื่อแพ็กเกจเดียวกันหรือสำหรับแพ็กเกจใหม่ (เช่น ผู้ให้บริการ ส่วนขยาย) เพื่อสร้างจากแพ็กเกจที่เก่ากว่า |
สร้าง | ระบุเมธอดอินเทอร์เฟซที่ส่งค่ากลับมาให้กับไคลเอ็นต์ เพื่อกลับ ค่าที่ไม่ใช่ค่าพื้นฐาน 1 ค่า หรือมีมากกว่าหนึ่งค่า ซึ่งเป็นฟังก์ชัน Callback แบบซิงโครนัส ขึ้น |
อินเทอร์เฟซ | การรวบรวมวิธีการและประเภท ได้รับการแปลเป็นคลาสใน C++ หรือ Java ทั้งหมด ในอินเทอร์เฟซจะเรียกในทิศทางเดียวกัน นั่นคือกระบวนการของไคลเอ็นต์ เรียกใช้เมธอดที่ใช้โดยกระบวนการของเซิร์ฟเวอร์ |
เที่ยวเดียว | เมื่อใช้กับเมธอด HIDL จะบ่งบอกว่าเมธอดนั้นไม่แสดงผลค่าใดๆ และ จะไม่บล็อก |
พัสดุ | คอลเล็กชันอินเทอร์เฟซและประเภทข้อมูลที่แชร์เวอร์ชัน |
การปล่อยผ่านสัญญาณ | โหมด HIDL ซึ่งเซิร์ฟเวอร์เป็นไลบรารีที่ใช้ร่วมกัน dlopen
จากลูกค้า ในโหมดส่งผ่าน ไคลเอ็นต์และเซิร์ฟเวอร์เป็นกระบวนการเดียวกัน แต่
และฐานของโค้ดแยกกัน ใช้เพื่อนำฐานของโค้ดเดิมไปไว้ในโมเดล HIDL เท่านั้น
ดูการเชื่อมโยงเพิ่มเติม |
เซิร์ฟเวอร์ | กระบวนการที่ใช้วิธีการของอินเทอร์เฟซ ดูเพิ่มเติม Passthrough |
การขนส่ง | โครงสร้างพื้นฐาน HIDL ที่ย้ายข้อมูลระหว่างเซิร์ฟเวอร์และไคลเอ็นต์ |
เวอร์ชัน | เวอร์ชันของแพ็กเกจ ประกอบด้วยจำนวนเต็ม 2 ตัว ได้แก่ หลักและรอง การแก้ไขเล็กน้อย การเพิ่มเวอร์ชันอาจเพิ่มประเภทและวิธีการ (แต่ไม่เปลี่ยนแปลง) |
รูปแบบ HIDL
เป้าหมายของ HIDL คือเราสามารถแทนที่เฟรมเวิร์ก Android ได้โดยไม่ต้องมี
สร้าง HAL ขึ้นมาใหม่ HAL สร้างขึ้นโดยผู้ให้บริการหรือผู้ผลิต SOC แล้วนำ
/vendor
พาร์ติชันในอุปกรณ์ ซึ่งเป็นการเปิดใช้เฟรมเวิร์ก Android เอง
แทน OTA โดยไม่ต้องคอมไพล์ HAL ใหม่
การออกแบบ HIDL ช่วยสร้างสมดุลให้กับข้อกังวลต่อไปนี้
- ความสามารถในการทำงานร่วมกัน สร้างอินเทอร์เฟซที่ทำงานร่วมกันได้อย่างเสถียร ระหว่างกระบวนการที่อาจคอมไพล์ด้วยสถาปัตยกรรม เครื่องมือเชนต่างๆ และการกำหนดค่าบิลด์ อินเทอร์เฟซ HIDL มีการกำหนดเวอร์ชันและเปลี่ยนแปลงไม่ได้ หลังจากเผยแพร่แล้ว
- ประสิทธิภาพ HIDL พยายามลดจำนวนสำเนา การดำเนินงาน ระบบจะส่งข้อมูลที่ HIDL กำหนดไปยังโค้ด C++ ในเลย์เอาต์มาตรฐาน C++ โครงสร้างข้อมูลที่ใช้ได้ โดยไม่ต้องคลายการแพคข้อมูล HIDL ยังมอบการแชร์ อินเทอร์เฟซหน่วยความจํา และเนื่องจาก RPC ค่อนข้างช้าอยู่ตัวหนึ่ง HIDL จึงรองรับ วิธีโอนข้อมูลโดยไม่ต้องใช้การเรียก RPC: หน่วยความจำที่ใช้ร่วมกันและ Fast คิวข้อความ (FMQ)
- ใช้งานง่าย HIDL หลีกเลี่ยงปัญหาที่ยากลำบากในการเป็นเจ้าของหน่วยความจำโดย
โดยใช้พารามิเตอร์
in
สำหรับ RPC เท่านั้น (โปรดดู แอนดรอยด์ ภาษานิยามอินเทอร์เฟซ (AIDL)); ที่ไม่มีประสิทธิภาพ ที่แสดงผลจาก Method จะได้รับการแสดงผลผ่านฟังก์ชัน Callback ไม่มีข้อมูล ลงใน HIDL เพื่อโอนและรับข้อมูลจาก HIDL เปลี่ยนการเป็นเจ้าของ ข้อมูล การเป็นเจ้าของจะยังคงอยู่กับฟังก์ชันการเรียกใช้เสมอ ข้อมูลจำเป็นต้อง คงอยู่เป็นระยะเวลาของฟังก์ชันที่เรียกใช้เท่านั้น และอาจถูกทำลายได้ ทันทีหลังจากฟังก์ชันที่เรียกทำงาน
ใช้โหมดส่งผ่าน
หากต้องการอัปเดตอุปกรณ์ที่ใช้ Android เวอร์ชันก่อนหน้าเป็น Android O ให้ทำดังนี้ รวม HAL ทั้งแบบทั่วไป (และแบบเดิม) ในอินเทอร์เฟซ HIDL ใหม่ที่แสดง HAL ในโหมดรวมตัวและกระบวนการเดียวกัน (ส่งผ่าน) การตัดข้อความเป็น มีความโปร่งใสสำหรับทั้ง HAL และเฟรมเวิร์ก Android
โหมดส่งผ่านใช้ได้เฉพาะกับไคลเอ็นต์และการใช้งาน C++ เท่านั้น อุปกรณ์ที่ใช้ Android เวอร์ชันก่อนหน้าจะไม่มี HAL ที่เขียนด้วย Java ดังนั้น Java HAL จะได้รับการผูกมัดโดยธรรมชาติ
ไฟล์ส่วนหัวแบบ Passthrough
เมื่อคอมไพล์ไฟล์ .hal
แล้ว hidl-gen
จะสร้างเอลิเมนต์
ไฟล์ส่วนหัวส่งผ่าน (Pass Through) เพิ่มเติม BsFoo.h
นอกเหนือจากส่วนหัว
ใช้สำหรับการสื่อสารแฟ้ม ส่วนหัวนี้จะกำหนดฟังก์ชัน
dlopen
แล้ว เมื่อ HAL Passthrough จะทํางานในกระบวนการเดียวกับที่
โดยปกติจะเรียกเมธอด Passthrough จะเรียกใช้โดย
การเรียกใช้ฟังก์ชัน (ชุดข้อความเดียวกัน) มีเมธอด oneway
รายการทำงานอยู่ในชุดข้อความของตัวเอง
เนื่องจากไม่ได้ใช้เพื่อรอให้ HAL ประมวลผล (ซึ่งหมายถึง HAL
ที่ใช้เมธอด oneway
ในโหมดส่งผ่านต้องเป็นแบบปลอดภัยของชุดข้อความ)
โดยใช้ IFoo.hal
โดย BsFoo.h
จะรวม HIDL ที่สร้างขึ้น
ในการนำเสนอฟีเจอร์เพิ่มเติม (เช่น การใช้ oneway
ธุรกรรมทำงานในชุดข้อความอื่น) ไฟล์นี้คล้ายกับ
อย่างไรก็ตาม BpFoo.h
แทนที่จะส่งต่อการโทร IPC โดยใช้ Binder ค่า
ระบบจะเรียกใช้ฟังก์ชันที่ต้องการโดยตรง การติดตั้งใช้งาน HAL ในอนาคต
อาจให้การใช้งานหลายอย่าง เช่น FooFast HAL และ
FooAccurate HAL ในกรณีดังกล่าว ไฟล์สำหรับการใช้งานเพิ่มเติมแต่ละรายการ
ให้สร้างขึ้น (เช่น PTFooFast.cpp
และ
PTFooAccurate.cpp
)
การเชื่อมโยง HAL ของ Passthrough
คุณสามารถรวมการติดตั้งใช้งาน HAL ที่รองรับโหมดส่งผ่าน ระบุ
สร้างอินเทอร์เฟซ HAL a.b.c.d@M.N::IFoo
แล้ว 2 แพ็กเกจ ดังนี้
a.b.c.d@M.N::IFoo-impl
มีการใช้ HAL และแสดงฟังก์ชันIFoo* HIDL_FETCH_IFoo(const char* name)
เปิด อุปกรณ์เดิม แพ็กเกจนี้dlopen
และการติดตั้งใช้งาน สร้างอินสแตนซ์โดยใช้HIDL_FETCH_IFoo
คุณสามารถสร้างโค้ดพื้นฐาน โดยใช้hidl-gen
และ-Lc++-impl
และ-Landroidbp-impl
a.b.c.d@M.N::IFoo-service
เปิด HAL Passthrough และ จดทะเบียนตนเองเป็นบริการที่มีการเชื่อมโยง จึงทำให้ใช้งาน HAL ได้เหมือนกัน เพื่อใช้เป็นทั้ง Passthrough และ Binderized
เนื่องจากเป็นประเภท IFoo
คุณสามารถเรียกใช้ sp<IFoo>
IFoo::getService(string name, bool getStub)
เพื่อรับสิทธิ์เข้าถึงอินสแตนซ์ได้
จาก IFoo
หาก getStub
เป็นจริง getService
จะพยายามเปิด HAL ในโหมดส่งผ่านเท่านั้น หาก getStub
คือ
เท็จ getService
พยายามค้นหาบริการที่มีการเชื่อมโยง ถ้าเป็นเช่นนั้น
ไม่สำเร็จ ระบบจะพยายามค้นหาบริการ Passthrough getStub
ไม่ควรใช้พารามิเตอร์ ยกเว้นใน
defaultPassthroughServiceImplementation
(อุปกรณ์ที่เปิดตัวด้วย
Android O เป็นอุปกรณ์ที่เชื่อมโยงอย่างสมบูรณ์ ดังนั้นการเปิดบริการในโหมดส่งผ่าน
ไม่ได้รับอนุญาต)
ไวยากรณ์ HIDL
ภาษา HIDL ออกแบบมาให้คล้ายกับภาษา C (แต่ไม่ได้ใช้ภาษา C
การประมวลผลล่วงหน้า) เครื่องหมายวรรคตอนทั้งหมดที่ไม่ได้อธิบายไว้ด้านล่าง (นอกเหนือจากการใช้งานที่ชัดเจน
ของ =
และ |
) เป็นส่วนหนึ่งของไวยากรณ์
หมายเหตุ: ดูรายละเอียดเกี่ยวกับรูปแบบรหัส HIDL ได้ที่ Code Style Guide
/** */
ระบุความคิดเห็นในเอกสาร คุณใช้วิธีเหล่านี้ได้ เพื่อประกาศค่า Method ฟิลด์ และ enum เท่านั้น/* */
หมายถึงความคิดเห็นหลายบรรทัด//
หมายถึงความคิดเห็นที่ท้ายบรรทัด นอกจาก//
บรรทัดใหม่จะเหมือนกับช่องว่างอื่นๆ- ในไวยากรณ์ตัวอย่างด้านล่าง ข้อความจาก
//
ถึงส่วนท้าย ไม่ได้เป็นส่วนหนึ่งของไวยากรณ์ แต่เป็นความคิดเห็นเกี่ยวกับไวยากรณ์ [empty]
หมายความว่าคํานั้นอาจว่างเปล่า?
ที่ตามหลังตัวลิเทอรัลหรือคำศัพท์หมายความว่าไม่บังคับให้...
หมายถึงลำดับที่มีรายการตั้งแต่ 0 รายการขึ้นไป การแยกเครื่องหมายวรรคตอนตามที่ระบุ ไม่มีอาร์กิวเมนต์แปรผันใน HIDL- องค์ประกอบของลำดับที่คั่นด้วยคอมมา
- เครื่องหมายอัฒภาคจะสิ้นสุดแต่ละองค์ประกอบ รวมถึงองค์ประกอบสุดท้าย
- ตัวพิมพ์ใหญ่ไม่ใช่เทอร์มินัล
italics
เป็นกลุ่มโทเค็น เช่นinteger
หรือidentifier
(C มาตรฐาน กฎการแยกวิเคราะห์)constexpr
เป็นนิพจน์คงที่รูปแบบ C (เช่น1 + 1
และ1L << 3
)import_name
คือชื่อแพ็กเกจหรือชื่ออินเทอร์เฟซ มีสิทธิ์ ตามที่อธิบายไว้ใน HIDL การกำหนดเวอร์ชันwords
ตัวพิมพ์เล็กเป็นโทเค็นแบบลิเทอรัล
ตัวอย่าง
ROOT = PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... } // not for types.hal | PACKAGE IMPORTS ITEM ITEM... // only for types.hal; no method definitions ITEM = ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?; | safe_union identifier { UFIELD; UFIELD; ...}; | struct identifier { SFIELD; SFIELD; ...}; // Note - no forward declarations | union identifier { UFIELD; UFIELD; ...}; | enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar | typedef TYPE identifier; VERSION = integer.integer; PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION; PREAMBLE = interface identifier EXTENDS EXTENDS = <empty> | extends import_name // must be interface, not package GENERATES = generates (FIELD, FIELD ...) // allows the Binder interface to be used as a type // (similar to typedef'ing the final identifier) IMPORTS = [empty] | IMPORTS import import_name; TYPE = uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t | float | double | bool | string | identifier // must be defined as a typedef, struct, union, enum or import // including those defined later in the file | memory | pointer | vec<TYPE> | bitfield<TYPE> // TYPE is user-defined enum | fmq_sync<TYPE> | fmq_unsync<TYPE> | TYPE[SIZE] FIELD = TYPE identifier UFIELD = TYPE identifier | safe_union identifier { FIELD; FIELD; ...} identifier; | struct identifier { FIELD; FIELD; ...} identifier; | union identifier { FIELD; FIELD; ...} identifier; SFIELD = TYPE identifier | safe_union identifier { FIELD; FIELD; ...}; | struct identifier { FIELD; FIELD; ...}; | union identifier { FIELD; FIELD; ...}; | safe_union identifier { FIELD; FIELD; ...} identifier; | struct identifier { FIELD; FIELD; ...} identifier; | union identifier { FIELD; FIELD; ...} identifier; SIZE = // Must be greater than zero constexpr ANNOTATIONS = [empty] | ANNOTATIONS ANNOTATION ANNOTATION = | @identifier | @identifier(VALUE) | @identifier(ANNO_ENTRY, ANNO_ENTRY ...) ANNO_ENTRY = identifier=VALUE VALUE = "any text including \" and other escapes" | constexpr | {VALUE, VALUE ...} // only in annotations ENUM_ENTRY = identifier | identifier = constexpr