अपैक्स फ़ाइल स्वरूप

एंड्रॉइड पोनी एक्सप्रेस (एपेक्स) कंटेनर प्रारूप एंड्रॉइड 10 में पेश किया गया था और इसका उपयोग निचले स्तर के सिस्टम मॉड्यूल के लिए इंस्टॉल फ़्लो में किया जाता है। यह प्रारूप उन सिस्टम घटकों के अपडेट की सुविधा प्रदान करता है जो मानक एंड्रॉइड एप्लिकेशन मॉडल में फिट नहीं होते हैं। कुछ उदाहरण घटक मूल सेवाएँ और लाइब्रेरीज़, हार्डवेयर एब्स्ट्रैक्शन लेयर्स ( HALs ), रनटाइम ( ART ), और क्लास लाइब्रेरीज़ हैं।

शब्द "APEX" एक APEX फ़ाइल को भी संदर्भित कर सकता है।

पृष्ठभूमि

हालाँकि एंड्रॉइड उन मॉड्यूल के अपडेट का समर्थन करता है जो पैकेज इंस्टॉलर ऐप (जैसे Google Play Store ऐप) के माध्यम से मानक ऐप मॉडल (उदाहरण के लिए, सेवाएं, गतिविधियां) के भीतर फिट होते हैं, निचले स्तर के ओएस घटकों के लिए समान मॉडल का उपयोग करने में निम्नलिखित कमियां हैं:

  • एपीके-आधारित मॉड्यूल का उपयोग बूट अनुक्रम के प्रारंभ में नहीं किया जा सकता है। पैकेज मैनेजर ऐप्स के बारे में जानकारी का केंद्रीय भंडार है और इसे केवल गतिविधि प्रबंधक से शुरू किया जा सकता है, जो बूट प्रक्रिया के बाद के चरण में तैयार हो जाता है।
  • एपीके प्रारूप (विशेष रूप से मेनिफेस्ट) एंड्रॉइड ऐप्स के लिए डिज़ाइन किया गया है और सिस्टम मॉड्यूल हमेशा उपयुक्त नहीं होते हैं।

डिज़ाइन

यह अनुभाग APEX फ़ाइल स्वरूप और APEX प्रबंधक के उच्च-स्तरीय डिज़ाइन का वर्णन करता है, जो एक सेवा है जो APEX फ़ाइलों का प्रबंधन करती है।

APEX के लिए इस डिज़ाइन को क्यों चुना गया, इस बारे में अधिक जानकारी के लिए, APEX को विकसित करते समय विकल्पों पर विचार किया गया देखें।

शीर्ष प्रारूप

यह APEX फ़ाइल का प्रारूप है.

एपेक्स फ़ाइल स्वरूप

चित्र 1. शीर्ष फ़ाइल स्वरूप

शीर्ष स्तर पर, एक APEX फ़ाइल एक ज़िप फ़ाइल है जिसमें फ़ाइलें असंपीड़ित संग्रहीत होती हैं और 4 KB सीमाओं पर स्थित होती हैं।

APEX फ़ाइल में चार फ़ाइलें हैं:

  • apex_manifest.json
  • AndroidManifest.xml
  • apex_payload.img
  • apex_pubkey

apex_manifest.json फ़ाइल में पैकेज का नाम और संस्करण शामिल है, जो APEX फ़ाइल की पहचान करता है। यह JSON प्रारूप में एक ApexManifest प्रोटोकॉल बफ़र है।

AndroidManifest.xml फ़ाइल APEX फ़ाइल को एपीके-संबंधित टूल और बुनियादी ढांचे जैसे एडीबी, पैकेजमैनेजर और पैकेज इंस्टॉलर ऐप्स (जैसे प्ले स्टोर) का उपयोग करने की अनुमति देती है। उदाहरण के लिए, APEX फ़ाइल फ़ाइल से बुनियादी मेटाडेटा का निरीक्षण करने के लिए aapt जैसे मौजूदा टूल का उपयोग कर सकती है। फ़ाइल में पैकेज का नाम और संस्करण की जानकारी है। यह जानकारी आम तौर पर apex_manifest.json में भी उपलब्ध है।

APEX से संबंधित नए कोड और सिस्टम के लिए AndroidManifest.xml की तुलना में apex_manifest.json अनुशंसा की जाती है। AndroidManifest.xml में अतिरिक्त लक्ष्यीकरण जानकारी हो सकती है जिसका उपयोग मौजूदा ऐप प्रकाशन टूल द्वारा किया जा सकता है।

apex_payload.img एक ext4 फ़ाइल सिस्टम छवि है जो dm-verity द्वारा समर्थित है। छवि को लूपबैक डिवाइस के माध्यम से रनटाइम पर माउंट किया जाता है। विशेष रूप से, हैश ट्री और मेटाडेटा ब्लॉक libavb लाइब्रेरी का उपयोग करके बनाए जाते हैं। फ़ाइल सिस्टम पेलोड को पार्स नहीं किया गया है (क्योंकि छवि को अपनी जगह पर माउंट किया जाना चाहिए)। नियमित फ़ाइलें apex_payload.img फ़ाइल के अंदर शामिल की जाती हैं।

apex_pubkey सार्वजनिक कुंजी है जिसका उपयोग फ़ाइल सिस्टम छवि पर हस्ताक्षर करने के लिए किया जाता है। रनटाइम पर, यह कुंजी सुनिश्चित करती है कि डाउनलोड किया गया APEX उसी इकाई के साथ हस्ताक्षरित है जो अंतर्निहित विभाजन में समान APEX पर हस्ताक्षर करता है।

एपेक्स नामकरण दिशानिर्देश

प्लेटफ़ॉर्म के आगे बढ़ने पर नए APEX के बीच नामकरण संबंधी विवादों को रोकने में मदद के लिए, निम्नलिखित नामकरण दिशानिर्देशों का उपयोग करें:

  • com.android.*
    • AOSP एपेक्स के लिए आरक्षित। किसी कंपनी या डिवाइस के लिए अद्वितीय नहीं।
  • com.<companyname>.*
    • एक कंपनी के लिए आरक्षित. संभावित रूप से उस कंपनी के कई उपकरणों द्वारा उपयोग किया जाता है।
  • com.<companyname>.<devicename>.*
    • किसी विशिष्ट उपकरण (या उपकरणों के उपसमूह) के लिए अद्वितीय APEXes के लिए आरक्षित।

शीर्ष प्रबंधक

APEX प्रबंधक (या apexd ) एक स्टैंडअलोन मूल प्रक्रिया है जो APEX फ़ाइलों को सत्यापित करने, स्थापित करने और अनइंस्टॉल करने के लिए जिम्मेदार है। यह प्रक्रिया लॉन्च हो गई है और बूट अनुक्रम में जल्दी तैयार हो गई है। APEX फ़ाइलें सामान्यतः /system/apex के अंतर्गत डिवाइस पर पहले से इंस्टॉल होती हैं। यदि कोई अद्यतन उपलब्ध नहीं है तो APEX प्रबंधक इन पैकेजों का उपयोग करने में चूक करता है।

APEX का अद्यतन अनुक्रम पैकेजमैनेजर वर्ग का उपयोग करता है और इस प्रकार है।

  1. एक APEX फ़ाइल पैकेज इंस्टॉलर ऐप, ADB, या अन्य स्रोत के माध्यम से डाउनलोड की जाती है।
  2. पैकेज मैनेजर इंस्टॉलेशन प्रक्रिया शुरू करता है। यह पहचानने पर कि फ़ाइल एक APEX है, पैकेज प्रबंधक नियंत्रण को APEX प्रबंधक को स्थानांतरित कर देता है।
  3. APEX प्रबंधक APEX फ़ाइल का सत्यापन करता है।
  4. यदि APEX फ़ाइल सत्यापित है, तो APEX प्रबंधक के आंतरिक डेटाबेस को यह दर्शाने के लिए अद्यतन किया जाता है कि APEX फ़ाइल अगले बूट पर सक्रिय हो जाती है।
  5. सफल पैकेज सत्यापन पर इंस्टॉल अनुरोधकर्ता को एक प्रसारण प्राप्त होता है।
  6. इंस्टॉलेशन जारी रखने के लिए, सिस्टम को रीबूट करना होगा।
  7. अगले बूट पर, APEX प्रबंधक प्रारंभ होता है, आंतरिक डेटाबेस को पढ़ता है, और सूचीबद्ध प्रत्येक APEX फ़ाइल के लिए निम्नलिखित कार्य करता है:

    1. APEX फ़ाइल को सत्यापित करता है।
    2. APEX फ़ाइल से एक लूपबैक डिवाइस बनाता है।
    3. लूपबैक डिवाइस के शीर्ष पर एक डिवाइस मैपर ब्लॉक डिवाइस बनाता है।
    4. डिवाइस मैपर ब्लॉक डिवाइस को एक अद्वितीय पथ पर माउंट करता है (उदाहरण के लिए, /apex/ name @ ver )।

जब आंतरिक डेटाबेस में सूचीबद्ध सभी APEX फ़ाइलें माउंट की जाती हैं, तो APEX प्रबंधक स्थापित APEX फ़ाइलों के बारे में जानकारी क्वेरी करने के लिए अन्य सिस्टम घटकों के लिए एक बाइंडर सेवा प्रदान करता है। उदाहरण के लिए, अन्य सिस्टम घटक डिवाइस में स्थापित APEX फ़ाइलों की सूची को क्वेरी कर सकते हैं या उस सटीक पथ को क्वेरी कर सकते हैं जहां एक विशिष्ट APEX माउंट किया गया है, ताकि फ़ाइलों तक पहुंचा जा सके।

एपेक्स फ़ाइलें एपीके फ़ाइलें हैं

APEX फ़ाइलें मान्य APK फ़ाइलें हैं क्योंकि उनमें AndroidManifest.xml फ़ाइल युक्त ज़िप अभिलेखागार (APK हस्ताक्षर योजना का उपयोग करके) पर हस्ताक्षर किए गए हैं। यह APEX फ़ाइलों को एपीके फ़ाइलों के लिए बुनियादी ढांचे का उपयोग करने की अनुमति देता है, जैसे पैकेज इंस्टॉलर ऐप, साइनिंग यूटिलिटी और पैकेज मैनेजर।

APEX फ़ाइल के अंदर AndroidManifest.xml फ़ाइल न्यूनतम है, जिसमें बेहतर लक्ष्यीकरण के लिए पैकेज name , versionCode और वैकल्पिक targetSdkVersion , minSdkVersion और maxSdkVersion शामिल हैं। यह जानकारी APEX फ़ाइलों को मौजूदा चैनलों जैसे पैकेज इंस्टॉलर ऐप्स और ADB के माध्यम से वितरित करने की अनुमति देती है।

फ़ाइल प्रकार समर्थित

APEX प्रारूप इन फ़ाइल प्रकारों का समर्थन करता है:

  • मूलनिवासी साझा काम
  • मूल निष्पादनयोग्य
  • जार फ़ाइलें
  • डेटा की फ़ाइलें
  • कॉन्फ़िग फ़ाइलें

इसका मतलब यह नहीं है कि APEX इन सभी फ़ाइल प्रकारों को अपडेट कर सकता है। फ़ाइल प्रकार को अद्यतन किया जा सकता है या नहीं यह प्लेटफ़ॉर्म पर निर्भर करता है और फ़ाइल प्रकारों के लिए इंटरफ़ेस की परिभाषाएँ कितनी स्थिर हैं।

हस्ताक्षर करने के विकल्प

APEX फ़ाइलों पर दो तरह से हस्ताक्षर किए जाते हैं। सबसे पहले, apex_payload.img (विशेष रूप से, apex_payload.img से जुड़ा वीबीमेटा डिस्क्रिप्टर) फ़ाइल को एक कुंजी के साथ हस्ताक्षरित किया जाता है। फिर, एपीके हस्ताक्षर योजना v3 का उपयोग करके संपूर्ण APEX पर हस्ताक्षर किए जाते हैं। इस प्रक्रिया में दो अलग-अलग कुंजियों का उपयोग किया जाता है।

डिवाइस साइड पर, vbmeta डिस्क्रिप्टर पर हस्ताक्षर करने के लिए उपयोग की जाने वाली निजी कुंजी से संबंधित एक सार्वजनिक कुंजी स्थापित है। APEX प्रबंधक उन APEX को सत्यापित करने के लिए सार्वजनिक कुंजी का उपयोग करता है जिन्हें स्थापित करने का अनुरोध किया गया है। प्रत्येक APEX को अलग-अलग कुंजियों के साथ हस्ताक्षरित किया जाना चाहिए और निर्माण समय और रनटाइम दोनों पर लागू किया जाना चाहिए।

अंतर्निर्मित विभाजनों में APEX

APEX फ़ाइलें /system जैसे अंतर्निहित विभाजनों में स्थित हो सकती हैं। विभाजन पहले से ही dm-verity पर है, इसलिए APEX फ़ाइलें सीधे लूपबैक डिवाइस पर माउंट की जाती हैं।

यदि एक APEX एक अंतर्निर्मित विभाजन में मौजूद है, तो APEX को समान पैकेज नाम और उससे अधिक या उसके बराबर संस्करण कोड के साथ एक APEX पैकेज प्रदान करके अद्यतन किया जा सकता है। नया APEX /data में संग्रहीत है और, एपीके के समान, नया स्थापित संस्करण अंतर्निहित विभाजन में पहले से मौजूद संस्करण को छाया देता है। लेकिन एपीके के विपरीत, एपेक्स का नया स्थापित संस्करण केवल रिबूट के बाद ही सक्रिय होता है।

कर्नेल आवश्यकताएँ

एंड्रॉइड डिवाइस पर एपेक्स मेनलाइन मॉड्यूल का समर्थन करने के लिए, निम्नलिखित लिनक्स कर्नेल सुविधाओं की आवश्यकता होती है: लूपबैक ड्राइवर और डीएम-वेरिटी। लूपबैक ड्राइवर फ़ाइल सिस्टम छवि को APEX मॉड्यूल में माउंट करता है और dm-verity APEX मॉड्यूल को सत्यापित करता है।

एपेक्स मॉड्यूल का उपयोग करते समय अच्छे सिस्टम प्रदर्शन को प्राप्त करने के लिए लूपबैक ड्राइवर और डीएम-वेरिटी का प्रदर्शन महत्वपूर्ण है।

समर्थित कर्नेल संस्करण

APEX मेनलाइन मॉड्यूल कर्नेल संस्करण 4.4 या उच्चतर का उपयोग करने वाले उपकरणों पर समर्थित हैं। एंड्रॉइड 10 या उच्चतर के साथ लॉन्च होने वाले नए उपकरणों को APEX मॉड्यूल का समर्थन करने के लिए कर्नेल संस्करण 4.9 या उच्चतर का उपयोग करना होगा।

आवश्यक कर्नेल पैच

APEX मॉड्यूल का समर्थन करने के लिए आवश्यक कर्नेल पैच एंड्रॉइड कॉमन ट्री में शामिल हैं। APEX का समर्थन करने के लिए पैच प्राप्त करने के लिए, एंड्रॉइड कॉमन ट्री के नवीनतम संस्करण का उपयोग करें।

कर्नेल संस्करण 4.4

यह संस्करण केवल उन उपकरणों के लिए समर्थित है जो एंड्रॉइड 9 से एंड्रॉइड 10 में अपग्रेड किए गए हैं और APEX मॉड्यूल का समर्थन करना चाहते हैं। आवश्यक पैच प्राप्त करने के लिए, android-4.4 शाखा से डाउन-मर्ज की दृढ़ता से अनुशंसा की जाती है। कर्नेल संस्करण 4.4 के लिए आवश्यक व्यक्तिगत पैच की सूची निम्नलिखित है।

  • अपस्ट्रीम: लूप: तार्किक ब्लॉक आकार बदलने के लिए ioctl जोड़ें ( 4.4 )
  • बैकपोर्ट: ब्लॉक/लूप: hw_sectors सेट करें ( 4.4 )
  • अपस्ट्रीम: लूप: कंपैटर ioctl ( 4.4 ) में LOOP_SET_BLOCK_SIZE जोड़ें
  • एंड्रॉइड: एमएनटी: नेक्स्ट_डिसेंटेंट को ठीक करें ( 4.4 )
  • एंड्रॉइड: एमएनटी: रिमाउंट को दासों के दासों के लिए प्रचारित किया जाना चाहिए ( 4.4 )
  • एंड्रॉइड: एमएनटी: रिमाउंट को सही ढंग से प्रचारित करें ( 4.4 )
  • "एंड्रॉइड: डीएम सत्यता: न्यूनतम प्रीफ़ेच आकार जोड़ें" वापस लाएं ( 4.4 )
  • अपस्ट्रीम: लूप: यदि ऑफसेट या ब्लॉक_साइज बदल दिया जाए तो कैश ड्रॉप करें ( 4.4 )

कर्नेल संस्करण 4.9/4.14/4.19

कर्नेल संस्करण 4.9/4.14/4.19 के लिए आवश्यक पैच प्राप्त करने के लिए, android-common शाखा से डाउन-मर्ज करें।

आवश्यक कर्नेल कॉन्फ़िगरेशन विकल्प

निम्नलिखित सूची एपेक्स मॉड्यूल का समर्थन करने के लिए आधार कॉन्फ़िगरेशन आवश्यकताओं को दिखाती है जो एंड्रॉइड 10 में पेश किए गए थे। तारांकन चिह्न (*) वाले आइटम एंड्रॉइड 9 और उससे पहले की मौजूदा आवश्यकताएं हैं।

(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices)
CONFIG_BLK_DEV_LOOP=Y # for loop device support
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices
(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity
(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity
CONFIG_DM_VERITY=Y # DM-verity support

कर्नेल कमांड-लाइन पैरामीटर आवश्यकताएँ

APEX का समर्थन करने के लिए, सुनिश्चित करें कि कर्नेल कमांड-लाइन पैरामीटर निम्नलिखित आवश्यकताओं को पूरा करते हैं:

  • loop.max_loop सेट नहीं होना चाहिए
  • loop.max_part <= 8 होना चाहिए

एक एपेक्स बनाएं

यह अनुभाग वर्णन करता है कि एंड्रॉइड बिल्ड सिस्टम का उपयोग करके APEX कैसे बनाया जाए। निम्नलिखित apex.test नामक APEX के लिए Android.bp का एक उदाहरण है।

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    // libc.so and libcutils.so are included in the apex
    native_shared_libs: ["libc", "libcutils"],
    binaries: ["vold"],
    java_libs: ["core-all"],
    prebuilts: ["my_prebuilt"],
    compile_multilib: "both",
    key: "apex.test.key",
    certificate: "platform",
}

apex_manifest.json उदाहरण:

{
  "name": "com.android.example.apex",
  "version": 1
}

file_contexts उदाहरण:

(/.*)?           u:object_r:system_file:s0
/sub(/.*)?       u:object_r:sub_file:s0
/sub/file3       u:object_r:file3_file:s0

APEX में फ़ाइल प्रकार और स्थान

फाइल का प्रकार एपेक्स में स्थान
साझा पुस्तकालय /lib और /lib64 (x86 में अनुवादित बांह के लिए /lib/arm )
निष्पादनयोग्य /bin
जावा पुस्तकालय /javalib
पूर्वनिर्मित /etc

सकर्मक निर्भरताएँ

APEX फ़ाइलों में स्वचालित रूप से मूल साझा libs या निष्पादन योग्य की सकर्मक निर्भरताएँ शामिल होती हैं। उदाहरण के लिए, यदि libFoo libBar पर निर्भर करता है, तो दो libs शामिल किए जाते हैं जब केवल libFoo native_shared_libs संपत्ति में सूचीबद्ध होता है।

एकाधिक एबीआई को संभालें

डिवाइस के प्राथमिक और द्वितीयक एप्लिकेशन बाइनरी इंटरफेस (एबीआई) दोनों के लिए native_shared_libs प्रॉपर्टी इंस्टॉल करें। यदि कोई APEX एकल ABI (अर्थात केवल 32 बिट या केवल 64 बिट) वाले उपकरणों को लक्षित करता है, तो केवल संबंधित ABI वाली लाइब्रेरी ही स्थापित की जाती हैं।

नीचे बताए अनुसार केवल डिवाइस के प्राथमिक एबीआई के लिए binaries प्रॉपर्टी स्थापित करें:

  • यदि डिवाइस केवल 32 बिट है, तो बाइनरी का केवल 32-बिट संस्करण स्थापित किया गया है।
  • यदि डिवाइस केवल 64 बिट है, तो बाइनरी का केवल 64-बिट संस्करण स्थापित किया जाता है।

मूल पुस्तकालयों और बायनेरिज़ के एबीआई पर सूक्ष्म नियंत्रण जोड़ने के लिए, multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] गुणों का उपयोग करें।

  • first : डिवाइस के प्राथमिक एबीआई से मेल खाता है। यह बायनेरिज़ के लिए डिफ़ॉल्ट है.
  • lib32 : यदि समर्थित है, तो डिवाइस के 32-बिट ABI से मेल खाता है।
  • lib64 : डिवाइस के 64-बिट ABI से मेल खाता है, यह समर्थित है।
  • prefer32 : यदि समर्थित हो तो डिवाइस के 32-बिट ABI से मेल खाता है। यदि 32-बिट एबीआई समर्थित नहीं है, तो 64-बिट एबीआई से मेल खाता है।
  • both : दोनों एबीआई से मेल खाता है। यह native_shared_libraries के लिए डिफ़ॉल्ट है।

java , libraries और prebuilts गुण एबीआई-अज्ञेयवादी हैं।

यह उदाहरण उस डिवाइस के लिए है जो 32/64 का समर्थन करता है और 32 को प्राथमिकता नहीं देता:

apex {
    // other properties are omitted
    native_shared_libs: ["libFoo"], // installed for 32 and 64
    binaries: ["exec1"], // installed for 64, but not for 32
    multilib: {
        first: {
            native_shared_libs: ["libBar"], // installed for 64, but not for 32
            binaries: ["exec2"], // same as binaries without multilib.first
        },
        both: {
            native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib
            binaries: ["exec3"], // installed for 32 and 64
        },
        prefer32: {
            native_shared_libs: ["libX"], // installed for 32, but not for 64
        },
        lib64: {
            native_shared_libs: ["libY"], // installed for 64, but not for 32
        },
    },
}

vbmeta पर हस्ताक्षर

प्रत्येक APEX पर अलग-अलग कुंजियों से हस्ताक्षर करें। जब एक नई कुंजी की आवश्यकता होती है, तो एक सार्वजनिक-निजी कुंजी जोड़ी बनाएं और एक apex_key मॉड्यूल बनाएं। कुंजी का उपयोग करके APEX पर हस्ताक्षर करने के लिए key गुण का उपयोग करें। सार्वजनिक कुंजी स्वचालित रूप से avb_pubkey नाम के साथ APEX में शामिल हो जाती है।

# create an rsa key pair
openssl genrsa -out foo.pem 4096

# extract the public key from the key pair
avbtool extract_public_key --key foo.pem --output foo.avbpubkey

# in Android.bp
apex_key {
    name: "apex.test.key",
    public_key: "foo.avbpubkey",
    private_key: "foo.pem",
}

उपरोक्त उदाहरण में, सार्वजनिक कुंजी का नाम ( foo ) कुंजी की आईडी बन जाता है। APEX पर हस्ताक्षर करने के लिए उपयोग की जाने वाली कुंजी की आईडी APEX में लिखी जाती है। रनटाइम पर, apexd डिवाइस में समान आईडी के साथ सार्वजनिक कुंजी का उपयोग करके एपेक्स को सत्यापित करता है।

शीर्ष पर हस्ताक्षर

APEX पर उसी तरह हस्ताक्षर करें जैसे आप APK पर हस्ताक्षर करते हैं। एपेक्स पर दो बार हस्ताक्षर करें; एक बार मिनी फ़ाइल सिस्टम ( apex_payload.img फ़ाइल) के लिए और एक बार पूरी फ़ाइल के लिए।

फ़ाइल-स्तर पर APEX पर हस्ताक्षर करने के लिए, certificate संपत्ति को इन तीन तरीकों में से एक में सेट करें:

  • सेट नहीं: यदि कोई मान सेट नहीं है, तो APEX को PRODUCT_DEFAULT_DEV_CERTIFICATE पर स्थित प्रमाणपत्र के साथ हस्ताक्षरित किया जाता है। यदि कोई ध्वज सेट नहीं है, तो पथ डिफ़ॉल्ट रूप से build/target/product/security/testkey जाता है।
  • <name> : APEX को PRODUCT_DEFAULT_DEV_CERTIFICATE जैसी ही निर्देशिका में <name> प्रमाणपत्र के साथ हस्ताक्षरित किया गया है।
  • :<name> : APEX को उस प्रमाणपत्र के साथ हस्ताक्षरित किया गया है जिसे <name> नामक Soong मॉड्यूल द्वारा परिभाषित किया गया है। प्रमाणपत्र मॉड्यूल को निम्नानुसार परिभाषित किया जा सकता है।
android_app_certificate {
    name: "my_key_name",
    certificate: "dir/cert",
    // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key)
}

एक एपेक्स स्थापित करें

APEX स्थापित करने के लिए, ADB का उपयोग करें।

adb install apex_file_name
adb reboot

यदि supportsRebootlessUpdate apex_manifest.json में true पर सेट किया गया है और वर्तमान में स्थापित APEX अप्रयुक्त है (उदाहरण के लिए, इसमें मौजूद सभी सेवाओं को रोक दिया गया है), तो --force-non-staged ध्वज के साथ रिबूट के बिना एक नया APEX स्थापित किया जा सकता है .

adb install --force-non-staged apex_file_name

एक एपेक्स का प्रयोग करें

रीबूट के बाद, APEX को /apex/<apex_name>@<version> निर्देशिका पर माउंट किया जाता है। एक ही APEX के एकाधिक संस्करण एक ही समय में माउंट किए जा सकते हैं। माउंट पथों में से, जो नवीनतम संस्करण से मेल खाता है उसे /apex/<apex_name> पर बाइंड-माउंट किया गया है।

ग्राहक APEX से फ़ाइलों को पढ़ने या निष्पादित करने के लिए बाइंड-माउंटेड पथ का उपयोग कर सकते हैं।

APEXes का उपयोग आमतौर पर इस प्रकार किया जाता है:

  1. जब डिवाइस भेजा जाता है तो OEM या ODM /system/apex के अंतर्गत एक APEX प्रीलोड करता है।
  2. APEX में फ़ाइलें /apex/<apex_name>/ पथ के माध्यम से एक्सेस की जाती हैं।
  3. जब APEX का एक अद्यतन संस्करण /data/apex में स्थापित किया जाता है, तो पथ रीबूट के बाद नए APEX की ओर इंगित करता है।

किसी सेवा को APEX के साथ अपडेट करें

APEX का उपयोग करके किसी सेवा को अद्यतन करने के लिए:

  1. सिस्टम विभाजन में सेवा को अद्यतन करने योग्य के रूप में चिह्नित करें। सेवा परिभाषा में updatable विकल्प जोड़ें।

    /system/etc/init/myservice.rc:
    
    service myservice /system/bin/myservice
        class core
        user system
        ...
        updatable
    
  2. अद्यतन सेवा के लिए एक नई .rc फ़ाइल बनाएँ। मौजूदा सेवा को फिर से परिभाषित करने के लिए override विकल्प का उपयोग करें।

    /apex/my.apex/etc/init.rc:
    
    service myservice /apex/my.apex/bin/myservice
        class core
        user system
        ...
        override
    

सेवा परिभाषाएँ केवल APEX की .rc फ़ाइल में परिभाषित की जा सकती हैं। APEXes में एक्शन ट्रिगर समर्थित नहीं हैं।

यदि अद्यतन योग्य के रूप में चिह्नित कोई सेवा APEXes सक्रिय होने से पहले शुरू होती है, तो APEXes की सक्रियता पूरी होने तक प्रारंभ में देरी होती है।

APEX अद्यतनों का समर्थन करने के लिए सिस्टम कॉन्फ़िगर करें

APEX फ़ाइल अद्यतनों का समर्थन करने के लिए निम्न सिस्टम प्रॉपर्टी को true पर सेट करें।

<device.mk>:

PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true

BoardConfig.mk:
TARGET_FLATTEN_APEX := false

या केवल

<device.mk>:

$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)

चपटा शीर्ष

पुराने उपकरणों के लिए, APEX को पूरी तरह से समर्थन देने के लिए पुराने कर्नेल को अपडेट करना कभी-कभी असंभव या संभव नहीं होता है। उदाहरण के लिए, कर्नेल CONFIG_BLK_DEV_LOOP=Y के बिना बनाया गया हो सकता है, जो APEX के अंदर फ़ाइल सिस्टम छवि को माउंट करने के लिए महत्वपूर्ण है।

फ़्लैटेंड APEX एक विशेष रूप से निर्मित APEX है जिसे लीगेसी कर्नेल वाले उपकरणों पर सक्रिय किया जा सकता है। एक चपटे APEX में फ़ाइलें सीधे अंतर्निहित विभाजन के अंतर्गत एक निर्देशिका में स्थापित की जाती हैं। उदाहरण के लिए, एक चपटे APEX में lib/libFoo.so my.apex /system/apex/my.apex/lib/libFoo.so पर स्थापित किया गया है।

चपटे एपेक्स को सक्रिय करने में लूप डिवाइस शामिल नहीं है। संपूर्ण निर्देशिका /system/apex/my.apex सीधे /apex/name@ver पर बाइंड-माउंटेड है।

नेटवर्क से APEXes के अद्यतन संस्करणों को डाउनलोड करके फ़्लैट किए गए APEXes को अपडेट नहीं किया जा सकता क्योंकि डाउनलोड किए गए APEXes को फ़्लैट नहीं किया जा सकता है। चपटे एपेक्स को केवल नियमित ओटीए के माध्यम से अद्यतन किया जा सकता है।

चपटा APEX डिफ़ॉल्ट कॉन्फ़िगरेशन है। इसका मतलब यह है कि सभी APEX डिफ़ॉल्ट रूप से चपटे होते हैं जब तक कि आप APEX अपडेट का समर्थन करने के लिए गैर-चपटा APEX बनाने के लिए अपने डिवाइस को स्पष्ट रूप से कॉन्फ़िगर नहीं करते हैं (जैसा कि ऊपर बताया गया है)।

किसी डिवाइस में चपटे और गैर-चपटे एपेक्स को मिलाना समर्थित नहीं है। किसी डिवाइस में एपेक्स या तो सभी गैर-चपटे या सभी चपटे होने चाहिए। यह विशेष रूप से महत्वपूर्ण है जब मेनलाइन जैसी परियोजनाओं के लिए पूर्व-हस्ताक्षरित एपेक्स प्रीबिल्ट की शिपिंग की जाती है। जो APEX निर्धारित नहीं हैं (अर्थात स्रोत से निर्मित हैं) उन्हें भी गैर-चपटा किया जाना चाहिए और उचित कुंजियों के साथ हस्ताक्षरित किया जाना चाहिए। डिवाइस को updatable_apex.mk से इनहेरिट करना चाहिए जैसा कि APEX के साथ एक सेवा को अपडेट करना में बताया गया है।

संपीडित शीर्ष

अद्यतन करने योग्य APEX पैकेजों के भंडारण प्रभाव को कम करने के लिए Android 12 और बाद में APEX संपीड़न की सुविधा है। किसी APEX में अद्यतन स्थापित होने के बाद, हालाँकि इसका पूर्व-स्थापित संस्करण अब उपयोग नहीं किया जाता है, फिर भी यह उतनी ही जगह घेरता है। वह अधिग्रहीत स्थान अनुपलब्ध रहता है.

APEX संपीड़न केवल पढ़ने योग्य विभाजन (जैसे /system विभाजन) पर APEX फ़ाइलों के अत्यधिक संपीड़ित सेट का उपयोग करके इस भंडारण प्रभाव को कम करता है। Android 12 और बाद के संस्करण DEFLATE ज़िप संपीड़न एल्गोरिदम का उपयोग करते हैं।

संपीड़न निम्नलिखित को अनुकूलन प्रदान नहीं करता है:

  • बूटस्ट्रैप एपेक्स जिन्हें बूट अनुक्रम में बहुत पहले माउंट किया जाना आवश्यक है।

  • गैर अद्यतन योग्य शीर्ष। संपीड़न केवल तभी फायदेमंद होता है जब APEX का अद्यतन संस्करण /data विभाजन पर स्थापित हो। अद्यतन योग्य APEXes की एक पूरी सूची मॉड्यूलर सिस्टम घटक पृष्ठ पर उपलब्ध है।

  • गतिशील साझा libs APEXes। चूंकि apexd हमेशा ऐसे एपेक्स के दोनों संस्करणों को सक्रिय करता है (पूर्व-स्थापित और अपग्रेड किया गया), उन्हें संपीड़ित करने से कोई मूल्य नहीं जुड़ता है।

संपीड़ित APEX फ़ाइल स्वरूप

यह एक संपीड़ित APEX फ़ाइल का प्रारूप है.

Diagram shows the format of a compressed APEX file

चित्र 2. संपीड़ित एपेक्स फ़ाइल स्वरूप

शीर्ष स्तर पर, एक संपीड़ित एपेक्स फ़ाइल एक ज़िप फ़ाइल होती है जिसमें मूल एपेक्स फ़ाइल 9 के संपीड़न स्तर के साथ डिफ़्लेटेड रूप में होती है, और अन्य फ़ाइलें असंपीड़ित रूप से संग्रहीत होती हैं।

चार फ़ाइलों में एक APEX फ़ाइल शामिल है:

  • original_apex : 9 के संपीड़न स्तर के साथ डिफ्लेटेड यह मूल, असंपीड़ित एपेक्स फ़ाइल है।
  • apex_manifest.pb : केवल संग्रहीत
  • AndroidManifest.xml : केवल संग्रहीत
  • apex_pubkey : केवल संग्रहीत

apex_manifest.pb , AndroidManifest.xml , और apex_pubkey फ़ाइलें original_apex में उनकी संबंधित फ़ाइलों की प्रतियां हैं।

संपीड़ित एपेक्स का निर्माण करें

संपीड़ित APEX को system/apex/tools पर स्थित apex_compression_tool.py टूल का उपयोग करके बनाया जा सकता है।

अपेक्स कम्प्रेशन से संबंधित कई पैरामीटर बिल्ड सिस्टम में उपलब्ध हैं।

Android.bp में APEX फ़ाइल संपीड़ित है या नहीं, इसे compressible संपत्ति द्वारा नियंत्रित किया जाता है:

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    compressible: true,
}

PRODUCT_COMPRESSED_APEX उत्पाद ध्वज नियंत्रित करता है कि स्रोत से निर्मित सिस्टम छवि में संपीड़ित APEX फ़ाइलें होनी चाहिए या नहीं।

स्थानीय प्रयोग के लिए आप OVERRIDE_PRODUCT_COMPRESSED_APEX= true पर सेट करके किसी बिल्ड को APEXes को संपीड़ित करने के लिए बाध्य कर सकते हैं।

बिल्ड सिस्टम द्वारा उत्पन्न संपीड़ित APEX फ़ाइलों में .capex एक्सटेंशन होता है। एक्सटेंशन APEX फ़ाइल के संपीड़ित और असम्पीडित संस्करणों के बीच अंतर करना आसान बनाता है।

समर्थित संपीड़न एल्गोरिदम

एंड्रॉइड 12 केवल डिफ्लेट-ज़िप संपीड़न का समर्थन करता है।

बूट के दौरान एक संपीड़ित APEX फ़ाइल को सक्रिय करें

संपीड़ित APEX को सक्रिय करने से पहले, इसके अंदर की original_apex फ़ाइल को /data/apex/decompressed निर्देशिका में विघटित कर दिया जाता है। परिणामी डीकंप्रेस्ड APEX फ़ाइल /data/apex/active निर्देशिका से हार्ड-लिंक है।

ऊपर वर्णित प्रक्रिया के उदाहरण के रूप में निम्नलिखित उदाहरण पर विचार करें।

/system/apex/com.android.foo.capex को एक संपीड़ित APEX के रूप में सक्रिय किया जा रहा है, संस्करण कोड 37 के साथ।

  1. /system/apex/com.android.foo.capex के अंदर original_apex फ़ाइल को /data/apex/decompressed/com.android.foo@37.apex में विघटित किया गया है।
  2. यह सत्यापित करने के लिए कि इसमें सही SELinux लेबल है restorecon /data/apex/decompressed/com.android.foo@37.apex किया जाता है।
  3. इसकी वैधता सुनिश्चित करने के लिए सत्यापन जांच /data/apex/decompressed/com.android.foo@37.apex पर की जाती है: apexd /data/apex/decompressed/com.android.foo@37.apex में बंडल की गई सार्वजनिक कुंजी की जांच करता है सत्यापित करें कि यह /system/apex/com.android.foo.capex में बंडल किए गए बंडल के बराबर है।
  4. /data/apex/decompressed/com.android.foo@37.apex फ़ाइल /data/apex/active/com.android.foo@37.apex निर्देशिका से हार्ड-लिंक है।
  5. असम्पीडित APEX फ़ाइलों के लिए नियमित सक्रियण तर्क /data/apex/active/com.android.foo@37.apex पर किया जाता है।

ओटीए के साथ बातचीत

संपीड़ित APEX फ़ाइलों का OTA डिलीवरी और एप्लिकेशन पर प्रभाव पड़ता है। चूँकि OTA अपडेट में किसी डिवाइस पर सक्रिय संस्करण की तुलना में उच्च संस्करण स्तर वाली एक संपीड़ित APEX फ़ाइल हो सकती है, OTA अपडेट लागू करने के लिए डिवाइस को रीबूट करने से पहले एक निश्चित मात्रा में खाली स्थान आरक्षित किया जाना चाहिए।

ओटीए प्रणाली का समर्थन करने के लिए, apexd इन दो बाइंडर एपीआई को उजागर करता है:

  • calculateSizeForCompressedApex - ओटीए पैकेज में एपेक्स फाइलों को डीकंप्रेस करने के लिए आवश्यक आकार की गणना करता है। इसका उपयोग यह सत्यापित करने के लिए किया जा सकता है कि ओटीए डाउनलोड होने से पहले डिवाइस में पर्याप्त जगह है।
  • reserveSpaceForCompressedApex - ओटीए पैकेज के अंदर संपीड़ित एपेक्स फ़ाइलों को डीकंप्रेस करने के लिए apexd द्वारा भविष्य में उपयोग के लिए डिस्क पर स्थान आरक्षित करता है।

ए/बी ओटीए अपडेट के मामले में, apexd पोस्टइंस्टॉल ओटीए रूटीन के हिस्से के रूप में पृष्ठभूमि में डीकंप्रेसन का प्रयास करता है। यदि डीकंप्रेसन विफल हो जाता है, apexd बूट के दौरान डीकंप्रेसन करता है जो ओटीए अपडेट लागू करता है।

APEX विकसित करते समय विकल्पों पर विचार किया गया

यहां कुछ विकल्प दिए गए हैं जिन पर एओएसपी ने एपेक्स फ़ाइल प्रारूप को डिज़ाइन करते समय विचार किया था, और उन्हें या तो शामिल या बाहर क्यों किया गया था।

नियमित पैकेज प्रबंधन प्रणाली

लिनक्स वितरण में dpkg और rpm जैसी पैकेज प्रबंधन प्रणालियाँ हैं, जो शक्तिशाली, परिपक्व और मजबूत हैं। हालाँकि, उन्हें APEX के लिए नहीं अपनाया गया क्योंकि वे इंस्टॉलेशन के बाद पैकेजों की सुरक्षा नहीं कर सकते। सत्यापन केवल तभी किया जाता है जब पैकेज स्थापित किए जा रहे हों। हमलावर बिना ध्यान दिए स्थापित पैकेजों की अखंडता को तोड़ सकते हैं। यह एंड्रॉइड के लिए एक प्रतिगमन है जहां सभी सिस्टम घटकों को केवल-पढ़ने योग्य फ़ाइल सिस्टम में संग्रहीत किया गया था जिनकी अखंडता प्रत्येक I/O के लिए dm-verity द्वारा संरक्षित है। सिस्टम घटकों में किसी भी तरह की छेड़छाड़ को या तो प्रतिबंधित किया जाना चाहिए, या पता लगाने योग्य होना चाहिए ताकि समझौता होने पर डिवाइस बूट होने से इंकार कर सके।

अखंडता के लिए डीएम-क्रिप्ट

APEX कंटेनर में फ़ाइलें अंतर्निहित विभाजन (उदाहरण के लिए, /system विभाजन) से होती हैं जो dm-verity द्वारा संरक्षित होती हैं, जहां विभाजन माउंट होने के बाद भी फ़ाइलों में कोई भी संशोधन निषिद्ध है। फ़ाइलों को समान स्तर की सुरक्षा प्रदान करने के लिए, APEX की सभी फ़ाइलों को एक फ़ाइल सिस्टम छवि में संग्रहीत किया जाता है जिसे हैश ट्री और vbmeta डिस्क्रिप्टर के साथ जोड़ा जाता है। डीएम-सत्यापन के बिना, /data विभाजन में एक एपेक्स अनपेक्षित संशोधनों के प्रति संवेदनशील है जो सत्यापित और स्थापित होने के बाद किए जाते हैं।

वास्तव में, /data विभाजन डीएम-क्रिप्ट जैसी एन्क्रिप्शन परतों द्वारा भी संरक्षित है। हालाँकि यह छेड़छाड़ के विरुद्ध कुछ स्तर की सुरक्षा प्रदान करता है, लेकिन इसका प्राथमिक उद्देश्य गोपनीयता है, अखंडता नहीं। जब कोई हमलावर /data विभाजन तक पहुंच प्राप्त करता है, तो कोई और सुरक्षा नहीं हो सकती है, और यह फिर से /system विभाजन में मौजूद प्रत्येक सिस्टम घटक की तुलना में एक प्रतिगमन है। APEX फ़ाइल के अंदर हैश ट्री dm-verity के साथ मिलकर समान स्तर की सामग्री सुरक्षा प्रदान करता है।

पथों को /system से /apex पर पुनर्निर्देशित करें

APEX में पैक की गई सिस्टम घटक फ़ाइलें /apex/<name>/lib/libfoo.so जैसे नए पथों के माध्यम से पहुंच योग्य हैं। जब फ़ाइलें /system विभाजन का हिस्सा थीं, तो वे /system/lib/libfoo.so जैसे पथों के माध्यम से पहुंच योग्य थीं। APEX फ़ाइल (अन्य APEX फ़ाइलें या प्लेटफ़ॉर्म) के क्लाइंट को नए पथों का उपयोग करना होगा। पथ परिवर्तन के परिणामस्वरूप आपको मौजूदा कोड को अद्यतन करने की आवश्यकता हो सकती है।

हालाँकि पथ परिवर्तन से बचने का एक तरीका APEX फ़ाइल में फ़ाइल सामग्री को /system विभाजन पर ओवरले करना है, Android टीम ने /system विभाजन पर फ़ाइलों को ओवरले नहीं करने का निर्णय लिया क्योंकि इससे प्रदर्शन पर प्रभाव पड़ सकता है क्योंकि फ़ाइलों की संख्या ओवरलेड हो सकती है ( संभवत: एक के बाद एक ढेर भी हो गए) बढ़ गए।

एक अन्य विकल्प open , stat और readlink जैसे फ़ाइल-एक्सेस फ़ंक्शंस को हाईजैक करना था, ताकि /system से शुरू होने वाले पथों को /apex के अंतर्गत उनके संबंधित पथों पर पुनर्निर्देशित किया जा सके। एंड्रॉइड टीम ने इस विकल्प को खारिज कर दिया क्योंकि पथ स्वीकार करने वाले सभी फ़ंक्शन को बदलना संभव नहीं है। उदाहरण के लिए, कुछ ऐप्स स्थिर रूप से बायोनिक को लिंक करते हैं, जो फ़ंक्शंस को कार्यान्वित करता है। ऐसे मामलों में, वे ऐप्स रीडायरेक्ट नहीं होते हैं।