Android 8 ได้ปรับโครงสร้างระบบปฏิบัติการ Android เพื่อกำหนดอินเทอร์เฟซที่ชัดเจนระหว่าง
แพลตฟอร์ม Android ที่ไม่ขึ้นอยู่กับอุปกรณ์ และโค้ดเฉพาะอุปกรณ์และผู้ให้บริการ
Android กำหนดอินเทอร์เฟซดังกล่าวไว้
ในรูปแบบของอินเทอร์เฟซ HAL
กำหนดเป็นส่วนหัว C ใน hardware/libhardware
HIDL มาแทนที่
อินเทอร์เฟซ HAL ที่มีอินเทอร์เฟซที่เสถียรและมีเวอร์ชัน ซึ่งสามารถเป็น
อินเทอร์เฟซ HIDL ฝั่งเซิร์ฟเวอร์ใน C++ (ตามที่อธิบายไว้ด้านล่าง) หรือ
Java
หน้าในส่วนนี้อธิบายการใช้อินเทอร์เฟซ HIDL ของ C++
รวมถึงรายละเอียดเกี่ยวกับไฟล์ที่สร้างขึ้นโดยอัตโนมัติจาก HIDL .hal
ของคอมไพเลอร์ hidl-gen
วิธีจัดแพ็กเกจไฟล์เหล่านี้ และ
วิธีผสานรวมไฟล์เหล่านี้กับโค้ด C++ ที่ใช้ไฟล์
การติดตั้งใช้งานไคลเอ็นต์และเซิร์ฟเวอร์
อินเทอร์เฟซ HIDL มีการใช้งานไคลเอ็นต์และเซิร์ฟเวอร์ ดังนี้
- ไคลเอ็นต์ของอินเทอร์เฟซ HIDL คือโค้ดที่ใช้เมธอด โดยเรียกใช้เมธอดได้
- เซิร์ฟเวอร์คือการใช้งานอินเทอร์เฟซ HIDL ที่ รับสายจากลูกค้าและแสดงผลลัพธ์ (หากจำเป็น)
การเปลี่ยนจาก HAL libhardware
เป็น HIDL HAL, HAL
กลายเป็นเซิร์ฟเวอร์ และกระบวนการที่เข้าสู่ HAL
ไคลเอ็นต์ การใช้งานเริ่มต้นสามารถแสดงได้ทั้ง Passthrough และ Binderized
HAL และอาจเปลี่ยนแปลงเมื่อเวลาผ่านไป
รูปที่ 1 ความคืบหน้าในการพัฒนาสำหรับ HAL เดิม
สร้างไคลเอ็นต์ HAL
เริ่มต้นด้วยการรวมไลบรารี HAL ไว้ในไฟล์ Makefile ดังนี้
- ยี่ห้อ:
LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
- เพลง:
shared_libs: [ …, android.hardware.nfc@1.0 ]
จากนั้น รวมไฟล์ส่วนหัว HAL ดังนี้
#include <android/hardware/nfc/1.0/IFoo.h> … // in code: sp<IFoo> client = IFoo::getService(); client->doThing();
สร้างเซิร์ฟเวอร์ HAL
หากต้องการสร้างการใช้งาน HAL คุณต้องมีไฟล์ .hal
ที่แสดงถึง HAL ของคุณและได้สร้างไฟล์ไฟล์สำหรับ HAL ของคุณ โดยใช้
-Lmakefile
หรือ -Landroidbp
ใน hidl-gen
(./hardware/interfaces/update-makefiles.sh
ดำเนินการนี้สำหรับภายใน
ไฟล์ HAL และเป็นข้อมูลอ้างอิงที่ดี) เมื่อโอน HAL จาก
libhardware
คุณทำงานหลายๆ อย่างนี้ได้ง่ายๆ โดยใช้ c2hal
วิธีสร้างไฟล์ที่จำเป็นสำหรับการใช้งาน HAL
PACKAGE=android.hardware.nfc@1.0 LOC=hardware/interfaces/nfc/1.0/default/ m -j hidl-gen hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE
คุณต้องมีสิ่งต่อไปนี้เพื่อให้ HAL ทำงานในโหมดส่งผ่าน
ฟังก์ชัน HIDL_FETCH_IModuleName
อยู่ใน
วันที่ /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl(OPTIONAL_IDENTIFIER).so
โดยที่ OPTIONAL_IDENTIFIER คือสตริงที่ระบุการส่งผ่าน
การใช้งานของคุณ แอตทริบิวต์ของโหมดส่งผ่าน (Pass Through) จะมีการปฏิบัติตามโดยอัตโนมัติ
เหนือคำสั่งอื่นๆ ซึ่งจะสร้าง android.hardware.nfc@1.0-impl
ด้วย
แต่สามารถใช้ส่วนขยายใดก็ได้ ตัวอย่างเช่น
android.hardware.nfc@1.0-impl-foo
ใช้ -foo
เพื่อ
แยกความแตกต่างได้
หาก HAL เป็นเวอร์ชันย่อยหรือเป็นส่วนขยายของเวอร์ชันอื่น
HAL ควรใช้ HAL พื้นฐานเพื่อตั้งชื่อไบนารีนี้ ตัวอย่างเช่น
การติดตั้งใช้งาน android.hardware.graphics.mapper@2.1
รายการควร
ยังคงอยู่ในไบนารีที่ชื่อว่า
android.hardware.graphics.mapper@2.0-impl(OPTIONAL_IDENTIFIER)
ปกติแล้ว OPTIONAL_IDENTIFIER ที่นี่จะมี HAL จริง
เวอร์ชัน ด้วยการตั้งชื่อไบนารีแบบนี้ ไคลเอ็นต์ 2.0 สามารถเรียกการเรียกดังกล่าวได้โดยตรง
และลูกค้า 2.1 สามารถ
ปรับปรุงการใช้งานได้
ถัดไป ให้ป้อนฟังก์ชันต่างๆ ของสตั๊ดแล้วตั้งค่า Daemon ตัวอย่าง รหัส Daemon (ที่รองรับ Passthrough):
#include <hidl/LegacySupport.h> int main(int /* argc */, char* /* argv */ []) { return defaultPassthroughServiceImplementation<INfc>("nfc"); }
โทร defaultPassthroughServiceImplementation
ครั้ง
dlopen()
สำหรับไลบรารี -impl
ที่ให้ไว้ และกำหนดให้เป็น
บริการที่เชื่อมโยงไว้ ตัวอย่างโค้ด Daemon (สำหรับบริการที่เชื่อมโยงทั้งหมด)
int main(int /* argc */, char* /* argv */ []) { // This function must be called before you join to ensure the proper // number of threads are created. The threadpool never exceeds // size one because of this call. ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/); sp<INfc> nfc = new Nfc(); const status_t status = nfc->registerAsService(); if (status != ::android::OK) { return 1; // or handle error } // Adds this thread to the threadpool, resulting in one total // thread in the threadpool. We could also do other things, but // would have to specify 'false' to willJoin in configureRpcThreadpool. ::android::hardware::joinRpcThreadpool(); return 1; // joinRpcThreadpool should never return }
Daemon นี้มักจะอาศัยอยู่ใน $PACKAGE + "-service-suffix"
(สำหรับ
เช่น android.hardware.nfc@1.0-service
) แต่อาจเป็นที่ใดก็ได้
sepolicy สําหรับ
คลาสของ HAL คือแอตทริบิวต์ hal_<module>
(เช่น
hal_nfc)
แอตทริบิวต์นี้ต้องนำไปใช้กับ Daemon ที่เรียกใช้
HAL ที่เฉพาะเจาะจง (หากกระบวนการเดียวกันแสดง HAL หลายรายการ จะมีแอตทริบิวต์หลายรายการ
ด้วย)