Android 11 में, product
पार्टिशन को अलग कर दिया गया है. इससे यह system
और vendor
पार्टिशन से अलग हो जाता है. इन बदलावों के तहत, अब आपके पास यह कंट्रोल करने का विकल्प है कि product
पार्टीशन, नेटिव और Java इंटरफ़ेस को ऐक्सेस कर सकता है या नहीं. यह ठीक उसी तरह काम करता है जिस तरह product
पार्टीशन के लिए इंटरफ़ेस लागू करने की सुविधा काम करती है.vendor
नेटिव इंटरफ़ेस लागू करें
नेटिव इंटरफ़ेस लागू करने की सुविधा चालू करने के लिए, PRODUCT_PRODUCT_VNDK_VERSION
को current
पर सेट करें. (अगर टारगेट के लिए शिपिंग एपीआई का लेवल 29 से ज़्यादा है, तो वर्शन अपने-आप current
पर सेट हो जाता है.) एनफ़ोर्समेंट की मदद से:
- लिंक करने के लिए,
product
पार्टीशन में मौजूद नेटिव मॉड्यूल:- स्टैटिक या डाइनैमिक तौर पर,
product
पार्टीशन के अन्य मॉड्यूल में. इनमें स्टैटिक, शेयर की गई या हेडर लाइब्रेरी शामिल हैं. system
पार्टिशन में मौजूद वीएनडीके लाइब्रेरी को डाइनैमिक रूप से लिंक किया जाता है.
- स्टैटिक या डाइनैमिक तौर पर,
product
पार्टीशन में मौजूद अनबंडल्ड APK में JNI लाइब्रेरी,/product/lib
या/product/lib64
में मौजूद लाइब्रेरी से लिंक करने के लिए (यह NDK लाइब्रेरी के अलावा है).
नीति उल्लंघन ठीक करने के लिए, product
पार्टिशन के अलावा, अन्य पार्टिशन के लिंक इस्तेमाल नहीं किए जा सकते.
बिल्ड टाइम एनफ़ोर्समेंट (Android.bp)
Android 11 में, सिस्टम मॉड्यूल, कोर और वेंडर इमेज वैरिएंट के अलावा, प्रॉडक्ट इमेज वैरिएंट भी बना सकते हैं. नेटिव इंटरफ़ेस एनफ़ोर्समेंट चालू होने पर (PRODUCT_PRODUCT_VNDK_VERSION
को current
पर सेट किया गया हो):
product
पार्टीशन में मौजूद नेटिव मॉड्यूल, कोर वैरिएंट के बजाय प्रॉडक्ट वैरिएंट में हैं.Android.bp
फ़ाइलों में मौजूदAndroid.bp
वाले मॉड्यूल, प्रॉडक्ट वैरिएंट के लिए उपलब्ध होते हैं.product_available: true
product_specific: true
के बारे में बताने वाली लाइब्रेरी या बाइनरी,product_specific: true
याproduct_available: true
के बारे में बताने वाली अन्य लाइब्रेरी से लिंक हो सकती हैं. इसके लिए, उन्हें अपनीAndroid.bp
फ़ाइलों में ऐसा करना होगा.वीएनडीके लाइब्रेरी की
Android.bp
फ़ाइलों मेंproduct_available: true
होना चाहिए, ताकिproduct
बाइनरी, वीएनडीके लाइब्रेरी से लिंक हो सकें.
यहां दी गई टेबल में, इमेज के अलग-अलग वर्शन बनाने के लिए इस्तेमाल की गई Android.bp
प्रॉपर्टी के बारे में खास जानकारी दी गई है.
Android.bp फ़ाइल में मौजूद प्रॉपर्टी | बनाए गए वैरिएंट | |
---|---|---|
नीति उल्लंघन ठीक करने के लिए कार्रवाई करने से पहले | नीति उल्लंघन ठीक करने के बाद | |
डिफ़ॉल्ट (कोई नहीं) | core
(includes /system , /system_ext and
/product ) |
कोर
(इसमें /system और /system_ext शामिल हैं, लेकिन /product नहीं) |
system_ext_specific: true |
कोर | कोर |
product_specific: true |
कोर | प्रॉडक्ट |
vendor: true |
वेंडर | वेंडर |
vendor_available: true |
कोर, वेंडर | कोर, वेंडर |
product_available: true |
लागू नहीं | कोर, प्रॉडक्ट |
vendor_available: true और product_available:
true |
लागू नहीं | कोर, प्रॉडक्ट, वेंडर |
system_ext_specific: true और vendor_available:
true |
कोर, वेंडर | कोर, वेंडर |
product_specific: true और vendor_available:
true |
कोर, वेंडर | प्रॉडक्ट, वेंडर |
बिल्ड टाइम एनफ़ोर्समेंट (Android.mk)
नेटिव इंटरफ़ेस लागू होने पर, product
पार्टीशन में इंस्टॉल किए गए नेटिव मॉड्यूल में native:product
लिंक टाइप होता है. यह सिर्फ़ अन्य native:product
या native:vndk
मॉड्यूल से लिंक हो सकता है. इनके अलावा, किसी अन्य मॉड्यूल से लिंक करने की कोशिश करने पर, बिल्ड सिस्टम लिंक टाइप की जांच से जुड़ी गड़बड़ी जनरेट करता है.
रनटाइम के दौरान लागू होने वाली नीतियां
नेटिव इंटरफ़ेस एनफ़ोर्समेंट चालू होने पर, बायोनिक लिंकर के लिए लिंकर कॉन्फ़िगरेशन, सिस्टम प्रोसेस को product
लाइब्रेरी इस्तेमाल करने की अनुमति नहीं देता. इससे product
प्रोसेस के लिए product
सेक्शन बनता है. ये प्रोसेस, product
पार्टिशन के बाहर मौजूद लाइब्रेरी से लिंक नहीं हो सकतीं. हालांकि, ये प्रोसेस वीएनडीके लाइब्रेरी से लिंक हो सकती हैं. रनटाइम लिंक कॉन्फ़िगरेशन का उल्लंघन करने की कोशिश करने पर, प्रोसेस पूरी नहीं हो पाती और CANNOT LINK EXECUTABLE
गड़बड़ी का मैसेज जनरेट होता है.
Java इंटरफ़ेस लागू करना
Java इंटरफ़ेस लागू करने की सुविधा चालू करने के लिए, PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
को true
पर सेट करें. (अगर टारगेट के लिए शिपिंग एपीआई का लेवल 29 से ज़्यादा है, तो वैल्यू अपने-आप true
पर सेट हो जाती है.) चालू होने पर, एनफ़ोर्समेंट की सुविधा से यह तय किया जा सकता है कि इन सुविधाओं का ऐक्सेस दिया जाए या नहीं:
एपीआई | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
Public API | |||||
@SystemApi | |||||
@hide API |
vendor
पार्टीशन की तरह ही, product
पार्टीशन में मौजूद किसी ऐप्लिकेशन या Java लाइब्रेरी को सिर्फ़ सार्वजनिक और सिस्टम एपीआई इस्तेमाल करने की अनुमति होती है. छिपे हुए एपीआई का इस्तेमाल करने वाली लाइब्रेरी से लिंक करने की अनुमति नहीं होती. यह पाबंदी, बिल्ड टाइम में लिंक करने और रनटाइम में रिफ़्लेक्शन पर लागू होती है.
बिल्ड टाइम पर नीति लागू करना
बिल्ड के समय, Make और Soong यह पुष्टि करते हैं कि product
पार्टिशन में मौजूद Java मॉड्यूल, छिपे हुए एपीआई का इस्तेमाल नहीं करते हैं. इसके लिए, वे platform_apis
और sdk_version
फ़ील्ड की जांच करते हैं. product
पार्टीशन में मौजूद ऐप्लिकेशन के sdk_version
फ़ील्ड में, current
, system_current
या एपीआई का संख्या वाला वर्शन होना चाहिए. साथ ही, platform_apis
फ़ील्ड खाली होना चाहिए.
रनटाइम के दौरान लागू होने वाली नीतियां
Android रनटाइम यह पुष्टि करता है कि product
पार्टीशन में मौजूद ऐप्लिकेशन, छिपे हुए एपीआई का इस्तेमाल नहीं करते हैं. इनमें रिफ़्लेक्शन भी शामिल है. ज़्यादा जानकारी के लिए, नॉन-एसडीके इंटरफ़ेस पर पाबंदियां लेख पढ़ें.
प्रॉडक्ट इंटरफ़ेस लागू करने की सुविधा चालू करना
प्रॉडक्ट इंटरफ़ेस लागू करने की सुविधा चालू करने के लिए, इस सेक्शन में दिया गया तरीका अपनाएं.
चरण | टास्क | ज़रूरी है |
---|---|---|
1 | अपना सिस्टम मेकफ़ाइल तय करें. इससे system पार्टिशन के लिए पैकेज तय किए जा सकते हैं. इसके बाद, device.mk में आर्टफ़ैक्ट के पाथ की ज़रूरी शर्तों की जांच सेट करें, ताकि सिस्टम से बाहर के मॉड्यूल को system पार्टिशन में इंस्टॉल होने से रोका जा सके. |
नहीं |
2 | अनुमति वाली सूची को अपडेट करें. | नहीं |
3 | नेटिव इंटरफ़ेस लागू करें और रनटाइम लिंक फ़ेल होने की पहचान करें. यह सुविधा, Java लागू करने की सुविधा के साथ-साथ काम कर सकती है. | Y |
4 | Java इंटरफ़ेस लागू करता है और रनटाइम के व्यवहार की पुष्टि करता है. इसे नेटिव एनफ़ोर्समेंट के साथ-साथ चलाया जा सकता है. | Y |
5 | रनटाइम से जुड़े तरीकों की जांच करें. | Y |
6 | प्रॉडक्ट इंटरफ़ेस लागू करने के साथ device.mk को अपडेट करें. |
Y |
पहला चरण: मेकफ़ाइल बनाएं और आर्टफ़ैक्ट पाथ की जांच करने की सुविधा चालू करें
इस चरण में, system
makefile तय किया जाता है.
एक मेकफ़ाइल बनाएं, जो
system
पार्टीशन के लिए पैकेज तय करती हो. उदाहरण के लिए, यहां दिए गए कॉन्टेंट के साथoem_system.mk
फ़ाइल बनाएं:$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk) # Applications PRODUCT_PACKAGES += \ CommonSystemApp1 \ CommonSystemApp2 \ CommonSystemApp3 \ # Binaries PRODUCT_PACKAGES += \ CommonSystemBin1 \ CommonSystemBin2 \ CommonSystemBin3 \ # Libraries PRODUCT_PACKAGES += \ CommonSystemLib1 \ CommonSystemLib2 \ CommonSystemLib3 \ PRODUCT_SYSTEM_NAME := oem_system PRODUCT_SYSTEM_BRAND := Android PRODUCT_SYSTEM_MANUFACTURER := Android PRODUCT_SYSTEM_MODEL := oem_system PRODUCT_SYSTEM_DEVICE := generic # For system-as-root devices, system.img should be mounted at /, so we # include ROOT here. _my_paths := \ $(TARGET_COPY_OUT_ROOT)/ \ $(TARGET_COPY_OUT_SYSTEM)/ \ $(call require-artifacts-in-path, $(_my_paths),)
device.mk
फ़ाइल में,system
पार्टीशन के लिए सामान्य मेकफ़ाइल इनहेरिट करें और आर्टफ़ैक्ट पाथ की ज़रूरी शर्तों की जांच करने की सुविधा चालू करें. उदाहरण के लिए:$(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk) # Enable artifact path requirements checking PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
आर्टफ़ैक्ट पाथ की ज़रूरी शर्तों के बारे में जानकारी
जब PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
को true
या strict
पर सेट किया जाता है, तो बिल्ड सिस्टम, अन्य मेकफ़ाइल में तय किए गए पैकेज को require-artifacts-in-path
में तय किए गए पाथ पर इंस्टॉल होने से रोकता है और मौजूदा मेकफ़ाइल में तय किए गए पैकेज को require-artifacts-in-path
में तय किए गए पाथ के बाहर आर्टफ़ैक्ट इंस्टॉल होने से रोकता है.
ऊपर दिए गए उदाहरण में, PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
को strict
पर सेट किया गया है. इसलिए, oem_system.mk
के बाहर मौजूद मेकफ़ाइल में, root
या system
पार्टिशन में इंस्टॉल किए गए मॉड्यूल शामिल नहीं किए जा सकते. इन मॉड्यूल को शामिल करने के लिए, आपको इन्हें oem_system.mk
फ़ाइल में या शामिल की गई मेकफ़ाइल में तय करना होगा.
अनुमति न दिए गए पाथ पर मॉड्यूल इंस्टॉल करने की कोशिश करने पर, बिल्ड प्रोसेस रुक जाती है. लाइन टूटने की समस्या ठीक करने के लिए, इनमें से कोई एक काम करें:
पहला विकल्प: सिस्टम मॉड्यूल को
oem_system.mk
में शामिल मेकफ़ाइलों में शामिल करें. इससे आर्टफ़ैक्ट पाथ की ज़रूरी शर्त पूरी हो जाती है, क्योंकि अब मॉड्यूल, शामिल की गई मेकफ़ाइल में मौजूद हैं. इसलिए, `require-artifacts-in-path` में मौजूद पाथ के सेट में इंस्टॉलेशन की अनुमति मिलती है.दूसरा विकल्प: मॉड्यूल को
system_ext
याproduct
पार्टिशन में इंस्टॉल करें. साथ ही, मॉड्यूल कोsystem
पार्टिशन में इंस्टॉल न करें.तीसरा विकल्प:
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
में मॉड्यूल जोड़ें. इसमें इंस्टॉल किए जा सकने वाले मॉड्यूल की सूची होती है.
दूसरा चरण: अनुमति वाली सूची को खाली करना
इस चरण में, PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
को खाली कर दिया जाता है, ताकि oem_system.mk
शेयर करने वाले सभी डिवाइस, एक ही system
इमेज शेयर कर सकें. अनुमति वाली सूची को खाली करने के लिए, सूची में मौजूद किसी भी मॉड्यूल को system_ext
या product
पार्टीशन में ले जाएं या उन्हें system
फ़ाइलें बनाने के लिए जोड़ें. यह चरण ज़रूरी नहीं है, क्योंकि प्रॉडक्ट इंटरफ़ेस लागू करने के लिए, सामान्य system
इमेज तय करना ज़रूरी नहीं है. हालांकि, अनुमति वाले डोमेन की सूची को खाली करने से, system_ext
की मदद से system
की सीमा तय करने में मदद मिलती है.
तीसरा चरण: नेटिव इंटरफ़ेस लागू करना
इस चरण में, PRODUCT_PRODUCT_VNDK_VERSION := current
सेट किया जाता है. इसके बाद, बिल्ड और रनटाइम से जुड़ी गड़बड़ियों का पता लगाया जाता है और उन्हें ठीक किया जाता है. डिवाइस बूट और लॉग की जांच करने के लिए. साथ ही, रनटाइम लिंक फ़ेल होने की गड़बड़ियों को ढूंढने और उन्हें ठीक करने के लिए:
PRODUCT_PRODUCT_VNDK_VERSION := current
सेट करें.डिवाइस बनाएं और बिल्ड से जुड़ी गड़बड़ियों का पता लगाएं. ऐसा हो सकता है कि आपको प्रॉडक्ट के वैरिएंट या मुख्य वैरिएंट मौजूद न होने की वजह से, कुछ बिल्ड ब्रेक दिखें. आम तौर पर, इन ब्रेक का इस्तेमाल किया जाता है:
product_specific: true
वाला कोई भीhidl_interface
मॉड्यूल, सिस्टम मॉड्यूल के लिए उपलब्ध नहीं होगा. इस समस्या को ठीक करने के लिए,product_specific: true
कोsystem_ext_specific: true
से बदलें.- ऐसा हो सकता है कि मॉड्यूल में, प्रॉडक्ट मॉड्यूल के लिए ज़रूरी प्रॉडक्ट वैरिएंट मौजूद न हो. इस समस्या को ठीक करने के लिए, उस मॉड्यूल को
product
पार्टीशन के लिए उपलब्ध कराएं. इसके लिए,product_available: true
सेट करें या मॉड्यूल कोproduct
पार्टीशन में ले जाएं. इसके लिए,product_specific: true
सेट करें.
बिल्ड से जुड़ी गड़बड़ियों को ठीक करें और पक्का करें कि डिवाइस सफलतापूर्वक बिल्ड हो गया हो.
इमेज को फ़्लैश करें और डिवाइस के बूट होने और लॉग में रनटाइम की गड़बड़ियों का पता लगाएं.
- अगर टेस्ट केस के लॉग में मौजूद
linker
टैग,CANNOT LINK EXECUTABLE
मैसेज दिखाता है, तो इसका मतलब है कि मेक फ़ाइल में कोई डिपेंडेंसी मौजूद नहीं है. साथ ही, इसे बिल्ड टाइम पर कैप्चर नहीं किया गया था. - इसे बिल्ड सिस्टम से देखने के लिए,
shared_libs:
याrequired:
फ़ील्ड में ज़रूरी लाइब्रेरी जोड़ें.
- अगर टेस्ट केस के लॉग में मौजूद
ऊपर दिए गए दिशा-निर्देशों का इस्तेमाल करके, ज़रूरी डिपेंडेंसी की समस्या हल करें.
चौथा चरण: Java इंटरफ़ेस लागू करना
इस चरण में, PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
सेट किया जाता है. इसके बाद, बिल्ड से जुड़ी गड़बड़ियां ढूंढकर उन्हें ठीक किया जाता है. दो तरह की गड़बड़ियों का पता लगाएं:
लिंक टाइप से जुड़ी गड़बड़ियां. इस गड़बड़ी का मतलब है कि ऐप्लिकेशन, Java मॉड्यूल से लिंक करता है. इन मॉड्यूल में
sdk_version
शामिल हैं. इस समस्या को ठीक करने के लिए, ऐप्लिकेशन केsdk_version
को बढ़ाया जा सकता है या लाइब्रेरी केsdk_version
को सीमित किया जा सकता है. गड़बड़ी के उदाहरण:error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
सिंबल से जुड़ी गड़बड़ियां. इस गड़बड़ी से पता चलता है कि किसी सिंबल को नहीं ढूँढा जा सका, क्योंकि वह छिपे हुए एपीआई में है. इस समस्या को ठीक करने के लिए, दिखने वाला (छिपा हुआ नहीं) एपीआई इस्तेमाल करें या कोई दूसरा विकल्प ढूंढें. गड़बड़ी के उदाहरण:
frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader( ^ symbol: class ProxyAuthenticate location: class SipSessionGroup.SipSessionImpl
पांचवां चरण: रनटाइम से जुड़े तरीकों की जांच करना
इस चरण में, यह पुष्टि की जाती है कि रनटाइम से जुड़े तरीके उम्मीद के मुताबिक काम कर रहे हैं. जिन ऐप्लिकेशन को डीबग किया जा सकता है उनके लिए, छिपे हुए एपीआई के इस्तेमाल को लॉग के ज़रिए मॉनिटर किया जा सकता है. इसके लिए, StrictMode.detectNonSdkApiUsage
का इस्तेमाल करें. इससे, ऐप्लिकेशन के छिपे हुए एपीआई का इस्तेमाल करने पर लॉग जनरेट होता है. इसके अलावा, इस्तेमाल के टाइप (लिंक करना या रिफ़्लेक्शन), पाबंदी का लेवल, और कॉल स्टैक की जानकारी पाने के लिए, veridex स्टैटिक विश्लेषण टूल का इस्तेमाल किया जा सकता है.
Veridex सिंटैक्स:
./art/tools/veridex/appcompat.sh --dex-file={apk file}
Veridex के नतीजे का उदाहरण:
#1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s): Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s): Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
veridex के इस्तेमाल के बारे में जानकारी के लिए, veridex टूल का इस्तेमाल करके टेस्ट करना लेख पढ़ें.
छठा चरण: device.mk फ़ाइल अपडेट करना
बिल्ड और रनटाइम से जुड़ी सभी गड़बड़ियों को ठीक करने के बाद, पुष्टि करें कि रनटाइम के व्यवहार आपकी उम्मीद के मुताबिक हैं. इसके बाद, device.mk
में ये सेटिंग करें:
PRODUCT_PRODUCT_VNDK_VERSION := current
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true