เนมสเปซสำหรับไลบรารีเนทีฟ

Android 7.0 ได้เปิดตัวเนมสเปซสําหรับไลบรารีแบบเนทีฟเพื่อจํากัดระดับการเข้าถึง API ภายในและแก้ไขสถานการณ์ที่แอปใช้ไลบรารีแพลตฟอร์มแทนไลบรารีของตนเองโดยไม่ตั้งใจ ดูการเปลี่ยนแปลงเฉพาะแอปได้ที่บล็อกโพสต์การปรับปรุงความเสถียรด้วยข้อจำกัดสัญลักษณ์ C/C++ ส่วนตัวใน Android 7.0 ของนักพัฒนาแอป Android

สถาปัตยกรรม

ใน Android 7.0 ขึ้นไป ไลบรารีของระบบจะแยกจากไลบรารีของแอป

เนมสเปซสำหรับไลบรารีเนทีฟ

รูปที่ 1 เนมสเปซสําหรับไลบรารีที่มาพร้อมเครื่อง

เนมสเปซสำหรับไลบรารีแบบเนทีฟป้องกันไม่ให้แอปใช้ API แบบเนทีฟในแพลตฟอร์มส่วนตัว (เช่นเดียวกับ OpenSSL) นอกจากนี้ ยังช่วยป้องกันไม่ให้แอปใช้ไลบรารีแพลตฟอร์มแทนไลบรารีของตนเองโดยไม่ตั้งใจ (ดังที่เห็นใน libpng) ไลบรารีแอปจะใช้ไลบรารีระบบภายในโดยไม่ตั้งใจได้ยาก (และในทางกลับกัน)

เพิ่มไลบรารีเนทีฟเพิ่มเติม

นอกจากไลบรารีเนทีฟสาธารณะมาตรฐานแล้ว ผู้ให้บริการชิป (ตั้งแต่ Android 7.0 เป็นต้นไป) และผู้ผลิตอุปกรณ์ (ตั้งแต่ Android 9 เป็นต้นไป) อาจเลือกจัดหาไลบรารีเนทีฟเพิ่มเติมที่แอปเข้าถึงได้โดยการใส่ไว้ในโฟลเดอร์ไลบรารีที่เกี่ยวข้องและแสดงรายการอย่างชัดเจนในไฟล์ .txt

โฟลเดอร์คลังมีดังนี้

  • /vendor/lib (สำหรับ 32 บิต) และ /vendor/lib64 (สำหรับ 64 บิต) สำหรับไลบรารีจากผู้ให้บริการซิลิคอน
  • /system/lib (สำหรับ 32 บิต) และ /system/lib64 (สำหรับ 64 บิต) สำหรับไลบรารีจากผู้ผลิตอุปกรณ์

ไฟล์ .txt มีดังนี้

  • /vendor/etc/public.libraries.txt สำหรับไลบรารีจากผู้ให้บริการชิป
  • /system/etc/public.libraries-COMPANYNAME.txt สำหรับคลังจากผู้ผลิตอุปกรณ์ โดยที่ COMPANYNAME หมายถึงชื่อผู้ผลิต (เช่น awesome.company) COMPANYNAME ต้องตรงกับ [A-Za-z0-9_.-]+ ซึ่งเป็นอักขระที่เป็นตัวอักษรและตัวเลขคละกัน, _, (จุด) และ - คุณมีไฟล์ .txt ดังกล่าวได้หลายไฟล์ในอุปกรณ์หากไลบรารีบางรายการมาจากผู้ให้บริการโซลูชันภายนอก

ไลบรารีแบบเนทีฟในพาร์ติชัน system ที่ผู้ผลิตอุปกรณ์เผยแพร่ต่อสาธารณะต้องตั้งชื่อว่า lib*COMPANYNAME.so เช่น libFoo.awesome.company.so กล่าวคือ libFoo.so ที่ไม่มีคำต่อท้ายชื่อบริษัทต้องไม่เผยแพร่ต่อสาธารณะ COMPANYNAME ในชื่อไฟล์ไลบรารีต้องตรงกับ COMPANYNAME ในชื่อไฟล์ txt ที่มีชื่อไลบรารีแสดงอยู่

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

ตั้งแต่ Android 8.0 เป็นต้นไป ไลบรารีสาธารณะของผู้ให้บริการจะมีข้อจำกัดเพิ่มเติมและการตั้งค่าที่จำเป็นดังต่อไปนี้

  1. ไลบรารีเนทีฟของผู้ให้บริการต้องมีการติดป้ายกำกับอย่างถูกต้องเพื่อให้แอปเข้าถึงได้ หากแอปใดก็ตาม (รวมถึงแอปของบุคคลที่สาม) จำเป็นต้องมีสิทธิ์เข้าถึง ห้องสมุดต้องติดป้ายกํากับเป็น same_process_hal_file ในไฟล์ file_contexts เฉพาะผู้ให้บริการ ดังนี้
    /vendor/lib(64)?/libnative.so u:object_r:same_process_hal_file:s0
    โดยที่ libnative.so คือชื่อของไลบรารีแบบเนทีฟ
  2. ไลบรารีต้องไม่ขึ้นอยู่กับไลบรารีระบบอื่นๆ นอกเหนือจากไลบรารี VNDK-SP และ LLNDK โดยตรงหรือโดยอ้อมผ่าน Dependency ค้นหารายการไลบรารี VNDK-SP และ LLNDK ที่ development/vndk/tools/definition/tool/datasets/eligible-list-<version>-release.csv

ตั้งแต่ Android 15 เป็นต้นไป คุณสามารถใส่ไลบรารีสาธารณะของผู้ให้บริการไว้ใน APEX ของผู้ให้บริการ เมื่อแพ็กเกจใน APEX ของผู้ให้บริการ ให้แสดงไลบรารีในพร็อพเพอร์ตี้ provideNativeLibs ในไฟล์ Manifest ของ APEX

อัปเดตแอปไม่ให้ใช้ไลบรารีเนทีฟที่ไม่เผยแพร่ต่อสาธารณะ

ฟีเจอร์นี้ใช้ได้กับแอปที่กำหนดเป้าหมายเป็น SDK เวอร์ชัน 24 ขึ้นไปเท่านั้น หากต้องการใช้กับเวอร์ชันเก่า โปรดดูตาราง 1 สิ่งที่จะเกิดขึ้นหากแอปของคุณลิงก์กับไลบรารีเนทีฟส่วนตัว รายการไลบรารี Android ที่เป็นเนทีฟซึ่งแอปเข้าถึงได้ (หรือที่เรียกว่า "ไลบรารีที่เป็นเนทีฟแบบสาธารณะ") แสดงอยู่ในส่วน 3.1.1 ของ CDD แอปที่กำหนดเป้าหมายเป็น 24 ขึ้นไปและใช้ไลบรารีที่ไม่ใช่สาธารณะควรได้รับการอัปเดต ดูรายละเอียดเพิ่มเติมได้ที่ NDK การลิงก์แอปกับไลบรารีแพลตฟอร์ม

อัปเดตแอปสำหรับทรัพยากร Dependency ของไลบรารีเนทีฟ

แอปที่กำหนดเป้าหมายเป็น SDK เวอร์ชัน 31 (Android 12) ขึ้นไปต้องระบุอย่างชัดแจ้งทรัพยากร Dependency ของไลบรารีที่แชร์แบบเนทีฟโดยใช้แท็ก <uses-native-library> ในไฟล์ Manifest ของแอป หากไม่มีส่วนใดของไลบรารีที่ขอในอุปกรณ์ แสดงว่าไม่ได้ติดตั้งแอปดังกล่าว เมื่อติดตั้งแอปแล้ว แอปจะได้รับเฉพาะไลบรารีที่ใช้ร่วมกันแบบเนทีฟที่ขอ ซึ่งหมายความว่าแอปจะเข้าถึงไลบรารีที่ใช้ร่วมกันแบบเนทีฟที่ไม่ปรากฏในไฟล์ Manifest ของแอปไม่ได้