ตัวเชื่อมโยงแบบไดนามิกจัดการกับความท้าทายสองประการในการออกแบบ Treble VNDK:
- ไลบรารีที่แบ่งใช้ SP-HAL และการขึ้นต่อกัน รวมถึงไลบรารี VNDK-SP จะถูกโหลดเข้าสู่กระบวนการเฟรมเวิร์ก ควรมีกลไกบางอย่างเพื่อป้องกันความขัดแย้งของสัญลักษณ์
-
dlopen()
และandroid_dlopen_ext()
สามารถแนะนำการพึ่งพารันไทม์บางอย่างที่ไม่สามารถมองเห็นได้ในขณะสร้างและอาจตรวจพบได้ยากโดยใช้การวิเคราะห์แบบคงที่
ความท้าทายทั้งสองนี้สามารถแก้ไขได้โดยกลไกเนม สเปซของลิงก์เกอร์ กลไกนี้จัดทำโดยตัวเชื่อมโยงแบบไดนามิก มันสามารถแยกไลบรารีที่แชร์ในเนมสเปซของลิงก์เกอร์ที่แตกต่างกันได้ ดังนั้นไลบรารีที่มีชื่อไลบรารีเดียวกัน แต่มีสัญลักษณ์ต่างกันจะไม่ขัดแย้งกัน
ในทางกลับกัน กลไกเนมสเปซของลิงก์เกอร์มอบความยืดหยุ่นเพื่อให้ไลบรารีที่แบ่งใช้บางไลบรารีสามารถส่งออกโดยเนมสเปซของลิงก์เกอร์ และใช้โดยเนมสเปซของลิงก์เกอร์อื่น ไลบรารีที่แบ่งใช้ที่ส่งออกเหล่านี้สามารถกลายเป็นอินเทอร์เฟซการเขียนโปรแกรมแอปพลิเคชันที่เปิดเผยต่อโปรแกรมอื่นในขณะที่ซ่อนรายละเอียดการใช้งานไว้ภายในเนมสเปซของลิงก์เกอร์
ตัวอย่างเช่น /system/lib[64]/libcutils.so
และ /system/lib[64]/vndk-sp-${VER}/libcutils.so
เป็นไลบรารีที่แบ่งใช้สองไลบรารี ไลบรารีทั้งสองนี้สามารถมีสัญลักษณ์ที่แตกต่างกันได้ พวกมันถูกโหลดลงในเนมสเปซตัวเชื่อมโยงที่แตกต่างกันเพื่อให้โมดูลเฟรมเวิร์กสามารถขึ้นอยู่กับ /system/lib[64]/libcutils.so
และไลบรารีที่ใช้ร่วมกัน SP-HAL สามารถขึ้นอยู่กับ /system/lib[64]/vndk-sp-${VER}/libcutils.so
ในทางกลับกัน /system/lib[64]/libc.so
เป็นตัวอย่างของไลบรารีสาธารณะที่ส่งออกโดยเนมสเปซของลิงก์เกอร์ และนำเข้าสู่เนมสเปซของลิงก์เกอร์จำนวนมาก การขึ้นต่อกันของ /system/lib[64]/libc.so
เช่น libnetd_client.so
จะถูกโหลดลงในเนมสเปซซึ่งมี /system/lib[64]/libc.so
อยู่ เนมสเปซอื่นๆ จะไม่มีสิทธิ์เข้าถึงการอ้างอิงเหล่านั้น กลไกนี้สรุปรายละเอียดการใช้งานในขณะที่จัดเตรียมอินเทอร์เฟซสาธารณะ
มันทำงานอย่างไร?
ตัวเชื่อมโยงแบบไดนามิกมีหน้าที่โหลดไลบรารีที่แบ่งใช้ที่ระบุในรายการ DT_NEEDED
หรือไลบรารีที่แบ่งใช้ที่ระบุโดยอาร์กิวเมนต์ของ dlopen()
หรือ android_dlopen_ext()
ในทั้งสองกรณี ตัวเชื่อมโยงแบบไดนามิกจะค้นหาเนมสเปซของตัวเชื่อมโยงที่มีผู้เรียกอยู่ และพยายามโหลดการขึ้นต่อกันลงในเนมสเปซของตัวเชื่อมโยงเดียวกัน หากตัวเชื่อมโยงแบบไดนามิกไม่สามารถโหลดไลบรารีที่ใช้ร่วมกันลงในเนมสเปซของตัวเชื่อมโยงที่ระบุ ตัวเชื่อมโยงจะถามเนม สเปซตัวเชื่อมโยงที่เชื่อมโยง สำหรับไลบรารีที่ใช้ร่วมกันที่ส่งออก
รูปแบบไฟล์การกำหนดค่า
รูปแบบไฟล์การกำหนดค่าจะขึ้นอยู่กับรูปแบบไฟล์ INI ไฟล์การกำหนดค่าทั่วไปมีลักษณะดังนี้:
dir.system = /system/bin dir.system = /system/xbin dir.vendor = /vendor/bin [system] additional.namespaces = sphal,vndk namespace.default.isolated = true namespace.default.search.paths = /system/${LIB} namespace.default.permitted.paths = /system/${LIB}/hw namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.default.asan.permitted.paths = /data/asan/system/${LIB}/hw:/system/${LIB}/hw namespace.sphal.isolated = true namespace.sphal.visible = true namespace.sphal.search.paths = /odm/${LIB}:/vendor/${LIB} namespace.sphal.permitted.paths = /odm/${LIB}:/vendor/${LIB} namespace.sphal.asan.search.paths = /data/asan/odm/${LIB}:/odm/${LIB} namespace.sphal.asan.search.paths += /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.asan.permitted.paths = /data/asan/odm/${LIB}:/odm/${LIB} namespace.sphal.asan.permitted.paths += /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.links = default,vndk namespace.sphal.link.default.shared_libs = libc.so:libm.so namespace.sphal.link.vndk.shared_libs = libbase.so:libcutils.so namespace.vndk.isolated = true namespace.vndk.search.paths = /system/${LIB}/vndk-sp-29 namespace.vndk.permitted.paths = /system/${LIB}/vndk-sp-29 namespace.vndk.links = default namespace.vndk.link.default.shared_libs = libc.so:libm.so [vendor] namespace.default.isolated = false namespace.default.search.paths = /vendor/${LIB}:/system/${LIB}
ไฟล์การกำหนดค่าประกอบด้วย:
- คุณสมบัติการแมปส่วนไดเร็กทอรีหลายอย่างที่จุดเริ่มต้นสำหรับตัวเชื่อมโยงแบบไดนามิกเพื่อเลือกส่วนที่มีประสิทธิภาพ
- ส่วนการกำหนดค่าเนมสเปซตัวเชื่อมโยงหลายส่วน:
- แต่ละส่วนประกอบด้วยเนมสเปซหลายอัน (จุดยอดกราฟ) และลิงก์ทางเลือกหลายรายการระหว่างเนมสเปซ (ส่วนโค้งของกราฟ)
- แต่ละเนมสเปซมีการแยก เส้นทางการค้นหา เส้นทางที่อนุญาต และการตั้งค่าการเปิดเผยของตัวเอง
ตารางด้านล่างนี้อธิบายความหมายของแต่ละคุณสมบัติโดยละเอียด
คุณสมบัติการแมปส่วนไดเรกทอรี
คุณสมบัติ | คำอธิบาย | ตัวอย่าง |
---|---|---|
| เส้นทางไปยังไดเร็กทอรีที่ใช้ส่วน แต่ละคุณสมบัติจะจับคู่ไฟล์ปฏิบัติการภายใต้ไดเร็กทอรีกับส่วนการกำหนดค่าเนมสเปซของลิงก์เกอร์ อาจมีคุณสมบัติสองรายการ (หรือมากกว่า) ที่มี | สิ่งนี้บ่งชี้ว่าการกำหนดค่าที่ระบุในส่วน การกำหนดค่าที่ระบุในส่วน |
คุณสมบัติความสัมพันธ์
คุณสมบัติ | คำอธิบาย | ตัวอย่าง |
---|---|---|
additional. namespaces | รายการเนมสเปซเพิ่มเติมที่คั่นด้วยเครื่องหมายจุลภาค (นอกเหนือจากเนมสเปซ | สิ่งนี้บ่งชี้ว่ามีสามเนมสเปซ ( |
namespace. name . links | รายการเนมสเปซทางเลือกที่คั่นด้วยเครื่องหมายจุลภาค หากไม่พบไลบรารีที่ใช้ร่วมกันในเนมสเปซปัจจุบัน ตัวเชื่อมโยงแบบไดนามิกจะพยายามโหลดไลบรารีที่ใช้ร่วมกันจากเนมสเปซทางเลือก เนมสเปซที่ระบุที่จุดเริ่มต้นของรายการมีลำดับความสำคัญสูงกว่า | หากไลบรารีที่ใช้ร่วมกันหรือไฟล์ปฏิบัติการร้องขอไลบรารีที่ใช้ร่วมกันที่ไม่สามารถโหลดลงในเนมสเป จากนั้น หากไม่สามารถโหลดไลบรารีที่แบ่งใช้จากเนมสเปซ สุดท้ายนี้ หากความพยายามทั้งหมดล้มเหลว ตัวเชื่อมโยงแบบไดนามิกจะส่งกลับข้อผิดพลาด |
namespace. name . link. other . shared_libs | รายการไลบรารีที่แบ่งใช้ที่คั่นด้วยโคลอนซึ่งสามารถค้นหาได้ในเนมสเปซ คุณสมบัตินี้ใช้กับ | สิ่งนี้บ่งชี้ว่าลิงก์ทางเลือกยอมรับเฉพาะ |
namespace. name . link. other . allow_all_shared_libs | ค่าบูลีนที่ระบุว่าไลบรารีที่แบ่งใช้ทั้งหมดสามารถค้นหาในเนมสเปซ คุณสมบัตินี้ใช้กับ | สิ่งนี้บ่งชี้ว่าชื่อไลบรารีทั้งหมดสามารถเดินผ่านลิงก์สำรองจาก |
คุณสมบัติเนมสเปซ
คุณสมบัติ | คำอธิบาย | ตัวอย่าง |
---|---|---|
namespace. name . isolated | ค่าบูลีนที่ระบุว่าตัวเชื่อมโยงแบบไดนามิกควรตรวจสอบว่าไลบรารีที่แบ่งใช้อยู่ที่ใด หาก หาก | สิ่งนี้บ่งชี้ว่าเฉพาะไลบรารีที่แบ่งใช้เท่านั้นใน |
namespace. name . search.paths | รายการไดเร็กทอรีที่คั่นด้วยโคลอนเพื่อค้นหาไลบรารีที่แบ่งใช้ ไดเร็กทอรีที่ระบุใน เมื่อ ตัวอย่างเช่น หาก | สิ่งนี้บ่งชี้ว่าตัวเชื่อมโยงแบบไดนามิกค้นหา |
namespace. name . asan.search.paths | รายการไดเรกทอรีที่คั่นด้วยโคลอนเพื่อค้นหาไลบรารีที่ใช้ร่วมกันเมื่อเปิดใช้งาน AddressSanitizer (ASan) | สิ่งนี้บ่งชี้ว่าเมื่อเปิดใช้งาน ASan ตัวลิงก์แบบไดนามิกจะค้นหา |
namespace. name . permitted.paths | รายการไดเร็กทอรีที่คั่นด้วยโคลอน (รวมถึงไดเร็กทอรีย่อย) ซึ่งตัวเชื่อมโยงแบบไดนามิกสามารถโหลดไลบรารีที่แบ่งใช้ (นอกเหนือจาก ไลบรารีแบบแบ่งใช้ที่อยู่ภายใต้ไดเร็กทอรีย่อยของ หาก | สิ่งนี้บ่งชี้ว่าไลบรารีแบบแบ่งใช้ภายใต้ ตัวอย่างเช่น หากไม่มี |
namespace. name . asan.permitted.paths | รายการไดเรกทอรีที่คั่นด้วยโคลอนซึ่งตัวเชื่อมโยงแบบไดนามิกสามารถโหลดไลบรารีที่แบ่งใช้ได้เมื่อเปิดใช้งาน ASan | สิ่งนี้บ่งชี้ว่าเมื่อเปิดใช้งาน ASan ไลบรารีแบบแบ่งใช้ภายใต้ |
namespace. name . visible | ค่าบูลีนที่ระบุว่าโปรแกรม (นอกเหนือจาก หาก หาก | สิ่งนี้บ่งชี้ว่า |
การสร้างเนมสเปซของลิงก์เกอร์
ใน Android 11 การกำหนดค่าตัวเชื่อมโยงจะถูกสร้างขึ้นที่รันไทม์ภายใต้ /linkerconfig
แทนที่จะใช้ไฟล์ข้อความธรรมดาใน ${android-src}/system/core/rootdir/etc
การกำหนดค่าจะถูกสร้างขึ้นในเวลาบูตตามสภาพแวดล้อมรันไทม์ ซึ่งรวมถึงรายการต่อไปนี้:
- หากอุปกรณ์รองรับ VNDK
- เวอร์ชัน VNDK เป้าหมายของพาร์ติชันผู้ขาย
- เวอร์ชัน VNDK ของพาร์ติชันผลิตภัณฑ์
- ติดตั้งโมดูล APEX แล้ว
การกำหนดค่า Linker ถูกสร้างขึ้นโดยการแก้ไขการขึ้นต่อกันระหว่างเนมสเปซของ Linker ตัวอย่างเช่น หากมีการอัปเดตใดๆ ในโมดูล APEX ที่มีการอัปเดตการพึ่งพา การกำหนดค่าตัวเชื่อมโยงจะถูกสร้างขึ้นโดยสะท้อนถึงการเปลี่ยนแปลงเหล่านี้ ดูรายละเอียดเพิ่มเติมในการสร้างการกำหนดค่าลิงเกอร์ได้ใน ${android-src}/system/linkerconfig
การแยกเนมสเปซของลิงก์เกอร์
มีการกำหนดค่าสามประเภท ขึ้นอยู่กับค่าของ PRODUCT_TREBLE_LINKER_NAMESPACES
และ BOARD_VNDK_VERSION
ใน BoardConfig.mk
การกำหนดค่าที่เกี่ยวข้องจะถูกสร้างขึ้นในเวลาบูต
PRODUCT_TREBLE_ LINKER_NAMESPACES | BOARD_VNDK_ VERSION | การกำหนดค่าที่เลือก | ข้อกำหนดวีทีเอส |
---|---|---|---|
true | current | VNDK | บังคับสำหรับอุปกรณ์ที่เปิดตัวด้วย Android 9 ขึ้นไป |
ว่างเปล่า | VNDK Lite | บังคับสำหรับอุปกรณ์ที่เปิดตัวด้วย Android 8.x | |
false | ว่างเปล่า | Legacy | สำหรับอุปกรณ์ที่ไม่ใช่เสียงแหลม |
การกำหนดค่า VNDK Lite แยกไลบรารีที่ใช้ร่วมกัน SP-HAL และ VNDK-SP ใน Android 8.0 นี่จะต้องเป็นไฟล์การกำหนดค่าสำหรับตัวเชื่อมโยงแบบไดนามิกเมื่อ PRODUCT_TREBLE_LINKER_NAMESPACES
เป็น true
การกำหนดค่า VNDK ยังแยกไลบรารีที่ใช้ร่วมกัน SP-HAL และ VNDK-SP นอกจากนี้ การกำหนดค่านี้จัดให้มีการแยกตัวเชื่อมโยงแบบไดนามิกเต็มรูปแบบ ช่วยให้มั่นใจได้ว่าโมดูลในพาร์ติชันระบบจะไม่ขึ้นอยู่กับไลบรารีแบบแบ่งใช้ในพาร์ติชันของผู้จำหน่ายและในทางกลับกัน
ใน Android 8.1 หรือสูงกว่า การกำหนดค่า VNDK เป็นการกำหนดค่าเริ่มต้น และขอแนะนำอย่างยิ่งให้เปิดใช้งานการแยกตัวเชื่อมโยงแบบไดนามิกเต็มรูปแบบโดยการตั้ง BOARD_VNDK_VERSION
เป็น current
การกำหนดค่า VNDK
การกำหนดค่า VNDK แยกการพึ่งพาไลบรารีแบบแบ่งใช้ระหว่างพาร์ติชันระบบและพาร์ติชันผู้จำหน่าย เมื่อเปรียบเทียบกับการกำหนดค่าที่กล่าวถึงในส่วนย่อยก่อนหน้า ความแตกต่างมีดังต่อไปนี้:
กระบวนการกรอบงาน
- เนมสเปซ
default
,vndk
,sphal
และrs
ถูกสร้างขึ้น - เนมสเปซทั้งหมดจะถูกแยกออกจากกัน
- ไลบรารีที่ใช้ร่วมกันของระบบถูกโหลดลงในเนมสเปซ
default
- SP-HAL ถูกโหลดลงในเนมสเปซ
sphal
- โหลดไลบรารีที่แบ่งใช้ VNDK-SP ลงในเนมสเปซ
vndk
- เนมสเปซ
กระบวนการของผู้จัดจำหน่าย
-
default
,vndk
, และเนมสเปซsystem
ถูกสร้างขึ้น - เนมสเปซ
default
จะถูกแยกออก - ไลบรารีที่ใช้ร่วมกันของผู้จัดจำหน่ายถูกโหลดลงในเนมสเปซ
default
- ไลบรารีที่แบ่งใช้ VNDK และ VNDK-SP ถูกโหลดลงในเนมสเปซ
vndk
- LL-NDK และการขึ้นต่อกันถูกโหลดลงในเนมสเปซ
system
-
ความสัมพันธ์ระหว่างเนมสเปซของลิงก์เกอร์แสดงไว้ด้านล่าง
ในภาพด้านบน LL-NDK และ VNDK-SP ย่อมาจากไลบรารีที่แบ่งใช้ต่อไปนี้:
- LL-NDK
-
libEGL.so
-
libGLESv1_CM.so
-
libGLESv2.so
-
libGLESv3.so
-
libandroid_net.so
-
libc.so
-
libdl.so
-
liblog.so
-
libm.so
-
libnativewindow.so
-
libneuralnetworks.so
-
libsync.so
-
libvndksupport.so
-
libvulkan.so
-
- VNDK-SP
-
android.hardware.graphics.common@1.0.so
-
android.hardware.graphics.mapper@2.0.so
-
android.hardware.renderscript@1.0.so
-
android.hidl.memory@1.0.so
-
libRSCpuRef.so
-
libRSDriver.so
-
libRS_internal.so
-
libbase.so
-
libbcinfo.so
-
libc++.so
-
libcutils.so
-
libhardware.so
-
libhidlbase.so
-
libhidlmemory.so
-
libhidltransport.so
-
libhwbinder.so
-
libion.so
-
libutils.so
-
libz.so
-
คุณสามารถดูรายละเอียดเพิ่มเติมได้ใน /linkerconfig/ld.config.txt
จากอุปกรณ์
การกำหนดค่า VNDK Lite
ใน Android 8.0 ตัวเชื่อมโยงแบบไดนามิกได้รับการกำหนดค่าให้แยกไลบรารีที่ใช้ร่วมกัน SP-HAL และ VNDK-SP เพื่อให้สัญลักษณ์ไม่ขัดแย้งกับไลบรารีที่ใช้ร่วมกันของเฟรมเวิร์กอื่น ๆ ความสัมพันธ์ระหว่างเนมสเปซของลิงก์เกอร์แสดงอยู่ด้านล่าง
LL-NDK และ VNDK-SP ย่อมาจากไลบรารีที่แบ่งใช้ดังต่อไปนี้:
- LL-NDK
-
libEGL.so
-
libGLESv1_CM.so
-
libGLESv2.so
-
libc.so
-
libdl.so
-
liblog.so
-
libm.so
-
libnativewindow.so
-
libstdc++.so
(ไม่อยู่ในการกำหนดค่า) -
libsync.so
-
libvndksupport.so
-
libz.so
(ย้ายไปที่ VNDK-SP ในการกำหนดค่า)
-
- VNDK-SP
-
android.hardware.graphics.common@1.0.so
-
android.hardware.graphics.mapper@2.0.so
-
android.hardware.renderscript@1.0.so
-
android.hidl.memory@1.0.so
-
libbase.so
-
libc++.so
-
libcutils.so
-
libhardware.so
-
libhidlbase.so
-
libhidlmemory.so
-
libhidltransport.so
-
libhwbinder.so
-
libion.so
-
libutils.so
-
ตารางด้านล่างแสดงรายการการกำหนดค่าเนมสเปซสำหรับกระบวนการเฟรมเวิร์ก ซึ่งคัดลอกมาจากส่วน [system]
ในการกำหนดค่า VNDK Lite
เนมสเปซ | คุณสมบัติ | ค่า |
---|---|---|
default | search.paths | /system/${LIB} /odm/${LIB} /vendor/${LIB} /product/${LIB} |
isolated | false | |
sphal | search.paths | /odm/${LIB} /vendor/${LIB} |
permitted.paths | /odm/${LIB} /vendor/${LIB} | |
isolated | true | |
visible | true | |
links | default,vndk,rs | |
link.default.shared_libs | LL-NDK | |
link.vndk.shared_libs | VNDK-SP | |
link.rs.shared_libs | libRS_internal.so | |
vndk (สำหรับ VNDK-SP) | search.paths | /odm/${LIB}/vndk-sp /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-sp-${VER} |
permitted.paths | /odm/${LIB}/hw /odm/${LIB}/egl /vendor/${LIB}/hw /vendor/${LIB}/egl /system/${LIB}/vndk-sp-${VER}/hw | |
isolated | true | |
visible | true | |
links | default | |
link.default.shared_libs | LL-NDK | |
rs (สำหรับ RenderScript) | search.paths | /odm/${LIB}/vndk-sp /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-sp-${VER} /odm/${LIB} /vendor/${LIB} |
permitted.paths | /odm/${LIB} /vendor/${LIB} /data (สำหรับเคอร์เนล RS ที่คอมไพล์แล้ว) | |
isolated | true | |
visible | true | |
links | default,vndk | |
link.default.shared_libs | LL-NDKlibmediandk.so libft2.so | |
link.vndk.shared_libs | VNDK-SP |
ตารางด้านล่างแสดงการกำหนดค่าเนมสเปซสำหรับกระบวนการของผู้ขาย ซึ่งคัดลอกมาจากส่วน [vendor]
ในการกำหนดค่า VNDK Lite
เนมสเปซ | คุณสมบัติ | ค่า |
---|---|---|
default | search.paths | /odm/${LIB} /odm/${LIB}/vndk /odm/${LIB}/vndk-sp /vendor/${LIB} /vendor/${LIB}/vndk /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-${VER} /system/${LIB}/vndk-sp-${VER} /system/${LIB} (เลิกใช้แล้ว)/product/${LIB} (เลิกใช้แล้ว) |
isolated | false |
ดูรายละเอียดเพิ่มเติมได้ใน /linkerconfig/ld.config.txt
จากอุปกรณ์
ประวัติเอกสาร
การเปลี่ยนแปลงของ Android 11
- ใน Android 11 ไฟล์
ld.config.*.txt
แบบคงที่จะถูกลบออกจากโค้ดเบส และ LinkerConfig จะสร้างไฟล์เหล่านั้นในรันไทม์แทน
การเปลี่ยนแปลงของ Android 9
- ใน Android 9 เนมสเปซตัวเชื่อมโยง
vndk
จะถูกเพิ่มในกระบวนการของผู้ขาย และไลบรารีที่ใช้ร่วมกันของ VNDK จะถูกแยกออกจากเนมสเปซตัวเชื่อมโยงเริ่มต้น - แทนที่
PRODUCT_FULL_TREBLE
ด้วยPRODUCT_TREBLE_LINKER_NAMESPACES
ที่เจาะจงมากขึ้น - Android 9 เปลี่ยนชื่อของไฟล์การกำหนดค่าตัวเชื่อมโยงแบบไดนามิกต่อไปนี้
แอนดรอยด์ 8.x แอนดรอยด์ 9 คำอธิบาย ld.config.txt.in
ld.config.txt
สำหรับอุปกรณ์ที่มีการแยกเนมสเปซตัวเชื่อมโยงรันไทม์ ld.config.txt
ld.config.vndk_lite.txt
สำหรับอุปกรณ์ที่มีการแยกเนมสเปซตัวเชื่อมโยง VNDK-SP ld.config.legacy.txt
ld.config.legacy.txt
สำหรับอุปกรณ์รุ่นเก่าที่ใช้ Android 7.x หรือต่ำกว่า - ลบ
android.hardware.graphics.allocator@2.0.so
- มีการเพิ่มพาร์ติชัน
product
และodm