APEX ของผู้ให้บริการ

คุณสามารถใช้รูปแบบไฟล์ APEX ในการทำแพ็กเกจและ ติดตั้งโมดูลระบบปฏิบัติการ Android ระดับล่าง ช่วยให้สามารถสร้างอิสระ การติดตั้งคอมโพเนนต์ เช่น บริการและไลบรารีแบบเนทีฟ, HAL การใช้งาน เฟิร์มแวร์ ไฟล์การกำหนดค่า ฯลฯ

ระบบบิลด์จะติดตั้ง APEX ของผู้ให้บริการโดยอัตโนมัติใน /vendor และเปิดใช้งานขณะรันไทม์โดย apexd เช่นเดียวกับ APEX ใน พาร์ติชัน

กรณีการใช้งาน

การแยกเป็นโมดูลสำหรับอิมเมจผู้ให้บริการ

APEX อำนวยความสะดวกในการสร้างการรวมกลุ่มและการแยกส่วนองค์ประกอบอย่างเป็นธรรมชาติ กับรูปภาพของผู้ให้บริการ

เมื่อมีการสร้างอิมเมจผู้ให้บริการเป็นชุดค่าผสมของผู้ให้บริการที่สร้างแยกต่างหาก APEX ทำให้ผู้ผลิตอุปกรณ์สามารถเลือก ที่ผู้ให้บริการต้องการบนอุปกรณ์ของตน และผู้ผลิตยังสร้าง APEX ของผู้ให้บริการใหม่หากไม่มี APEX ที่ให้มาที่เข้ากับความต้องการ หรือ ฮาร์ดแวร์ที่ออกแบบเองใหม่ล่าสุด

ตัวอย่างเช่น OEM อาจเลือกเขียนอุปกรณ์ด้วย Wi-Fi AOSP การใช้งาน APEX, การใช้บลูทูธ SoC, APEX และ OEM ที่กำหนดเอง การติดตั้งใช้งานโทรศัพท์อย่าง APEX

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

การทำซ้ำสำหรับนักพัฒนาซอฟต์แวร์

APEX ผู้ให้บริการช่วยให้นักพัฒนาซอฟต์แวร์ปรับปรุงผลิตภัณฑ์ได้เร็วขึ้น ขณะเดียวกันก็พัฒนาโมดูลผู้ให้บริการด้วยวิธีการดังนี้ รวมการใช้งานฟีเจอร์ทั้งหมด เช่น HAL ของ Wi-Fi ไว้ในผู้ให้บริการ APEX จากนั้นนักพัฒนาซอฟต์แวร์จะสร้างและพุช APEX ของผู้ให้บริการแต่ละรายเพื่อทดสอบได้ เปลี่ยนแปลง แทนที่จะสร้างอิมเมจผู้ให้บริการทั้งหมดขึ้นมาใหม่

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

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

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

ตัวอย่างเวิร์กโฟลว์

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

ตัวอย่าง

ข้อมูลเบื้องต้น

ดูหน้าหลักของรูปแบบไฟล์ APEX สำหรับ APEX ทั่วไป ซึ่งรวมถึงข้อกำหนดของอุปกรณ์ รายละเอียดรูปแบบไฟล์ และ ขั้นตอนการติดตั้ง

ใน Android.bp การตั้งค่าพร็อพเพอร์ตี้ vendor: true จะทำให้โมดูล APEX APEX ของผู้ให้บริการ

apex {
  ..
  vendor: true,
  ..
}

ไบนารีและไลบรารีที่ใช้ร่วมกัน

APEX จะรวมทรัพยากร Dependency แบบทรานซิทีฟภายในเพย์โหลด APEX ไว้ด้วย เว้นแต่จะมีการอ้างอิง มีอินเทอร์เฟซที่เสถียร

อินเทอร์เฟซเนทีฟแบบเสถียรสำหรับทรัพยากร Dependency ของ APEX ของผู้ให้บริการรวมถึง cc_library ด้วย stubs, ndk_library หรือ llndk_library ทรัพยากร Dependency เหล่านี้ไม่รวมอยู่ใน แพ็กเกจ และทรัพยากร Dependency จะได้รับการบันทึกไว้ในไฟล์ Manifest APEX ไฟล์ Manifest คือ ประมวลผลโดย linkerconfig เพื่อให้ทรัพยากร Dependency แบบเนทีฟภายนอก พร้อมใช้งานขณะรันไทม์

APEX ของผู้ให้บริการมักจะเชื่อมโยงกับ APEX ในพาร์ติชัน /system VNDK ที่ต้องการ ไลบรารี VNDK รับประกันความเสถียรของ ABI ภายใน เผยแพร่ เพื่อให้เราถือว่าไลบรารี VNDK มีความเสถียรและลดขนาดของผู้ให้บริการ APEX โดยยกเว้นจาก APEX โดยใช้ use_vndk_as_stable

ในข้อมูลโค้ดด้านล่าง APEX จะมีทั้งไบนารี (my_service) และ ทรัพยากร Dependency ที่ไม่เสถียร (*.so ไฟล์) เนื่องจากไม่มีไลบรารี VNDK แม้ว่า my_service จะสร้างด้วยไลบรารี VNDK เช่น libbase ก็ตาม แต่ที่ รันไทม์ my_service จะใช้ libbase จากไลบรารี VNDK ที่ให้บริการโดย ระบบ

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

ในข้อมูลโค้ดด้านล่าง APEX จะมีไลบรารีที่ใช้ร่วมกัน my_standalone_libและทรัพยากร Dependency ที่ไม่เสถียร (ตามที่อธิบายไว้ข้างต้น)

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

การติดตั้งใช้งาน HAL

หากต้องการกำหนดการปรับใช้ HAL ให้ระบุไบนารีและไลบรารีที่เกี่ยวข้อง ภายใน APEX ของผู้ให้บริการที่คล้ายกับตัวอย่างต่อไปนี้

เพื่อสรุปการติดตั้งใช้งาน HAL โดยสมบูรณ์ APEX ควรระบุ Fragment ของ VINTF และสคริปต์ Init ที่เกี่ยวข้อง

ส่วนย่อย VINTF

Fragment ของ VINTF อาจแสดงจาก APEX ของผู้ให้บริการเมื่อมี Fragment อยู่ใน etc/vintf ของ APEX

ใช้พร็อพเพอร์ตี้ prebuilts เพื่อฝัง Fragment ของ VINTF ใน APEX

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

สคริปต์เริ่มต้น

APEX สามารถรวมสคริปต์ init ได้ 2 วิธี คือ (ก) ไฟล์ข้อความที่สร้างไว้ล่วงหน้าภายในแท็ก เปย์โหลด APEX หรือ (B) สคริปต์ init ปกติใน /vendor/etc คุณสามารถตั้ง สำหรับ APEX เดียวกัน

เขียนสคริปต์เริ่มต้นใน APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

สคริปต์ Init ภายใน APEXes สามารถใส่คำจำกัดความได้เพียง service รายการเท่านั้น สคริปต์เริ่มต้น ใน APEX ของผู้ให้บริการก็มีคำสั่ง on <property> ได้เช่นกัน

โปรดระมัดระวังเมื่อใช้คำสั่ง on เนื่องจากสคริปต์ init ใน APEXes แยกวิเคราะห์และดำเนินการหลังจากเปิดใช้ APEX เหตุการณ์หรือพร็อพเพอร์ตี้บางรายการ ไม่สามารถใช้ได้ ใช้ apex.all.ready=true เพื่อเริ่มดำเนินการโดยเร็วที่สุด

เฟิร์มแวร์

ตัวอย่าง

ฝังเฟิร์มแวร์ใน APEX ของผู้ให้บริการด้วยประเภทโมดูล prebuilt_firmware เป็น ติดตาม

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

ติดตั้งโมดูล prebuilt_firmware รายการใน <apex name>/etc/firmware แล้ว ของ APEX ueventd สแกน /apex/*/etc/firmware ไดเรกทอรีไปยัง ค้นหาโมดูลเฟิร์มแวร์

file_contexts ของ APEX ควรติดป้ายกำกับรายการเพย์โหลดของเฟิร์มแวร์ เพื่อให้แน่ใจว่า ueventd เข้าถึงไฟล์เหล่านี้ได้ขณะรันไทม์ โดยปกติ ป้ายกำกับ vendor_file ก็เพียงพอแล้ว เช่น

(/.*)? u:object_r:vendor_file:s0

โมดูลเคอร์เนล

ฝังโมดูลเคอร์เนลใน APEX ของผู้ให้บริการเป็นโมดูลที่สร้างไว้ล่วงหน้า ดังนี้

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

file_contexts ของ APEX ควรติดป้ายกำกับรายการเพย์โหลดของโมดูลเคอร์เนล อย่างเหมาะสม เช่น

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

ต้องติดตั้งโมดูลเคอร์เนลอย่างชัดเจน ตัวอย่างต่อไปนี้คือสคริปต์ init ในพาร์ติชันผู้ให้บริการแสดงการติดตั้งผ่าน insmod:

my_init.rc:

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

การวางซ้อนทรัพยากรรันไทม์

ตัวอย่าง

ฝังการวางซ้อนทรัพยากรรันไทม์ใน APEX ของผู้ให้บริการ โดยใช้พร็อพเพอร์ตี้ rros

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

ไฟล์การกำหนดค่าอื่นๆ

APEX ของผู้ให้บริการรองรับไฟล์การกำหนดค่าอื่นๆ ที่มักพบในผู้ให้บริการ เป็นพาร์ติชันที่สร้างไว้ล่วงหน้าภายใน APEX ของผู้ให้บริการ และมีการเพิ่มเข้ามาอีก

ตัวอย่าง

ฟีเจอร์สำหรับการพัฒนาเพิ่มเติม

การเลือก APEX เมื่อเปิดเครื่อง

ตัวอย่าง

นักพัฒนาแอปยังสามารถติดตั้ง APEX ของผู้ให้บริการหลายเวอร์ชันที่ใช้ ชื่อและคีย์ APEX เดียวกัน แล้วเลือกเวอร์ชันที่จะเปิดใช้งานในแต่ละคีย์ เปิดเครื่องโดยใช้ sysprops ต่อเนื่อง สำหรับกรณีการใช้งานของนักพัฒนาซอฟต์แวร์บางกรณี ง่ายกว่าการติดตั้ง APEX สำเนาใหม่โดยใช้ adb install

ตัวอย่างกรณีการใช้งาน

  • ติดตั้ง APEX ของผู้ให้บริการ Wi-Fi HAL ทั้ง 3 เวอร์ชัน: ทีม QA สามารถดำเนินการด้วยตนเอง หรือการทดสอบอัตโนมัติโดยใช้เวอร์ชันหนึ่ง จากนั้นรีบูตเป็นเวอร์ชันอื่นและ ทำการทดสอบอีกครั้ง แล้วเปรียบเทียบผลลัพธ์สุดท้าย
  • ติดตั้ง APEX ของผู้ให้บริการ HAL ของกล้อง 2 เวอร์ชัน คือปัจจุบัน และ ทดลอง: ผู้ร่วม Dogfood สามารถใช้เวอร์ชันทดลองได้โดยไม่ต้อง ดาวน์โหลดและติดตั้งไฟล์เพิ่มเติม เพื่อให้สลับกลับได้โดยง่าย

ในระหว่างการเปิดเครื่อง apexd จะมองหา sysprops ตามรูปแบบที่เฉพาะเจาะจงเพื่อ เปิดใช้งานเวอร์ชัน APEX ที่ถูกต้อง

รูปแบบที่คาดไว้สำหรับคีย์พร็อพเพอร์ตี้มีดังนี้

  • การกำหนดค่าเริ่มต้น
    • ใช้เพื่อตั้งค่าเริ่มต้นในBoardConfig.mk
    • androidboot.vendor.apex.<apex name>
  • Syprop ถาวร
    • ใช้เพื่อเปลี่ยนค่าเริ่มต้น ซึ่งตั้งไว้ในอุปกรณ์ที่บูตแล้ว
    • ลบล้างค่า Bootconfig หากมี
    • persist.vendor.apex.<apex name>

ค่าของพร็อพเพอร์ตี้ควรเป็นชื่อไฟล์ของ APEX ซึ่งควรเป็น เปิดใช้งาน แล้ว

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

ควรกำหนดค่าเวอร์ชันเริ่มต้นโดยใช้ Bootconfig ใน BoardConfig.mk:

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

หลังจากเปิดเครื่องแล้ว ให้เปลี่ยนเวอร์ชันที่เปิดใช้งานโดยการตั้งค่า sysprop ถาวร:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

หากอุปกรณ์รองรับการอัปเดต Bootconfig หลังจากแฟลช (เช่น ผ่านคำสั่ง fastboot oem) จากนั้นเปลี่ยนพร็อพเพอร์ตี้ Bootconfig สำหรับการติดตั้งหลายรายการ นอกจากนี้ APEX ยังเปลี่ยนเวอร์ชันที่เปิดใช้งานเมื่อเปิดเครื่องด้วย

สำหรับอุปกรณ์อ้างอิงเสมือนโดยอิงตามหมึกกระดอง คุณจะใช้คำสั่ง --extra_bootconfig_args เพื่อตั้งค่าพร็อพเพอร์ตี้ Bootconfig ได้ โดยตรงขณะเปิด เช่น

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";