Android 11, product
पार्टीशन को अनबंड कर देता है. इससे यह system
और vendor
पार्टीशन से अलग हो जाता है. इन बदलावों के तहत, अब आपके पास product
partition के नेटिव और Java इंटरफ़ेस के ऐक्सेस को कंट्रोल करने का विकल्प है. यह उसी तरह काम करता है जिस तरह vendor
partition के लिए इंटरफ़ेस लागू करने की सुविधा काम करती है.
नेटिव इंटरफ़ेस लागू करना
नेटिव इंटरफ़ेस की नीति उल्लंघन ठीक करने के तरीके (एनफ़ोर्समेंट) चालू करने के लिए, PRODUCT_PRODUCT_VNDK_VERSION
को current
पर सेट करें. (टारगेट के लिए शिपिंग एपीआई लेवल 29 से ज़्यादा होने पर, वर्शन अपने-आप current
पर सेट हो जाता है.) एनफ़ोर्समेंट की मदद से:
product
पार्टीशन में मौजूद नेटिव मॉड्यूल, जिन्हें लिंक करना है:product
सेक्शन में मौजूद दूसरे मॉड्यूल में, स्टैटिक या डाइनैमिक तौर पर लागू किया जा सकता है. इन मॉड्यूल में स्टैटिक, शेयर की गई या हेडर लाइब्रेरी शामिल होती हैं.system
पार्टीशन में, VNDK लाइब्रेरी को डाइनैमिक तौर पर.
product
पार्टीशन में मौजूद, बंडल नहीं किए गए APKs में JNI लाइब्रेरी, ताकि उन्हें/product/lib
या/product/lib64
में मौजूद लाइब्रेरी से लिंक किया जा सके. यह लाइब्रेरी, NDK लाइब्रेरी के अलावा होती हैं.
नीति उल्लंघन ठीक करने की सुविधा, product
पार्टिशन के अलावा किसी दूसरे पार्टिशन से लिंक करने की अनुमति नहीं देती.
बिल्ड टाइम नीति उल्लंघन ठीक करने का तरीका (Android.bp)
Android 11 में, सिस्टम मॉड्यूल, प्रॉडक्ट इमेज के कोर और वेंडर इमेज वैरिएंट के अलावा, प्रॉडक्ट इमेज का वैरिएंट भी बना सकते हैं. नेटिव इंटरफ़ेस एनफ़ोर्समेंट चालू होने पर (PRODUCT_PRODUCT_VNDK_VERSION
को current
पर सेट किया गया है):
product
पार्टीशन में मौजूद नेटिव मॉड्यूल, कोर वैरिएंट के बजाय प्रॉडक्ट वैरिएंट में होते हैं.जिन मॉड्यूल की
Android.bp
फ़ाइलों मेंproduct_available: true
है वे प्रॉडक्ट वैरिएंट के लिए उपलब्ध होते हैं.product_specific: true
बताने वाली लाइब्रेरी या बाइनरी, अपनीAndroid.bp
फ़ाइलों मेंproduct_specific: true
याproduct_available: true
बताने वाली अन्य लाइब्रेरी से लिंक हो सकती हैं.VNDK लाइब्रेरी की
Android.bp
फ़ाइलों मेंproduct_available: true
होना ज़रूरी है, ताकिproduct
बाइनरी, VNDK लाइब्रेरी से लिंक हो सकें.
इस टेबल में, इमेज के वैरिएंट बनाने के लिए इस्तेमाल की जाने वाली Android.bp
प्रॉपर्टी के बारे में खास जानकारी दी गई है.
Android.bp में प्रॉपर्टी | बनाए गए वैरिएंट | |
---|---|---|
नीति उल्लंघन ठीक करने के लिए उठाए जाने वाले कदम से पहले | नीति उल्लंघन ठीक करने के तरीके (एनफ़ोर्समेंट) के बाद | |
डिफ़ॉल्ट (कोई नहीं) | मुख्य
(इसमें /system , /system_ext , और
/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 |
लागू नहीं | core, product, vendor |
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
partition की तरह ही, product
partition में मौजूद किसी ऐप्लिकेशन या Java लाइब्रेरी को सिर्फ़ सार्वजनिक और सिस्टम एपीआई का इस्तेमाल करने की अनुमति है. साथ ही, ऐसी लाइब्रेरी से लिंक करने की अनुमति नहीं है जो छिपे हुए एपीआई का इस्तेमाल करती है. इस पाबंदी में, बिल्ड के समय लिंक करने और रनटाइम में रिफ़्लेक्शन शामिल है.
बिल्ड प्रोसेस में लगने वाले समय को लागू करना
बिल्ड के समय, Make और Soong यह पुष्टि करते हैं कि product
partition में मौजूद Java मॉड्यूल, platform_apis
और sdk_version
फ़ील्ड की जांच करके, छिपे हुए एपीआई का इस्तेमाल नहीं करते. product
पार्टीशन में मौजूद ऐप्लिकेशन के sdk_version
एट्रिब्यूट की वैल्यू के तौर पर, एपीआई के current
, system_current
या अंकों वाले वर्शन का इस्तेमाल किया जाना चाहिए. साथ ही, platform_apis
फ़ील्ड खाली होना चाहिए.
रनटाइम पर लागू होने वाले नियम
Android रनटाइम इस बात की पुष्टि करता है कि product
पार्टिशन में मौजूद ऐप्लिकेशन, छिपे हुए एपीआई का इस्तेमाल नहीं करते. इनमें रिफ़्लेक्शन भी शामिल है. ज़्यादा जानकारी के लिए, SDK के अलावा अन्य इंटरफ़ेस पर पाबंदियां लेख पढ़ें.
प्रॉडक्ट इंटरफ़ेस लागू करने की सुविधा चालू करना
प्रॉडक्ट इंटरफ़ेस पर, नीति उल्लंघन ठीक करने के तरीके (एनफ़ोर्समेंट) को चालू करने के लिए, इस सेक्शन में दिया गया तरीका अपनाएं.
चरण | टास्क | ज़रूरी है |
---|---|---|
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
partition के लिए सामान्य मेकफ़ाइल को इनहेरिट करें और आर्टफ़ैक्ट पाथ की ज़रूरी शर्तों की जांच करने की सुविधा चालू करें. उदाहरण के लिए:$(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
फ़ाइल में या किसी शामिल Makefile में तय करना होगा.
जिन पाथ पर मॉड्यूल इंस्टॉल करने की अनुमति नहीं है उन पर मॉड्यूल इंस्टॉल करने की कोशिश करने पर, बिल्डिंग रुक जाती है. ब्रेक को ठीक करने के लिए, इनमें से कोई एक काम करें:
पहला विकल्प:
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
सेट करें.डिवाइस बनाएं और बिल्ड से जुड़ी गड़बड़ियों का पता लगाएं. आपको प्रॉडक्ट के वैरिएंट या मुख्य वैरिएंट मौजूद न होने की वजह से, कुछ बिल्ड ब्रेक दिख सकते हैं. सामान्य ब्रेक
hidl_interface
मॉड्यूल मेंproduct_specific: true
होने पर, वह सिस्टम मॉड्यूल के लिए उपलब्ध नहीं होगा. इस समस्या को ठीक करने के लिए,product_specific: true
कोsystem_ext_specific: true
से बदलें.- ऐसा हो सकता है कि मॉड्यूल में प्रॉडक्ट के वैरिएंट की जानकारी मौजूद न हो. यह जानकारी, प्रॉडक्ट के लिए ज़रूरी है. इसे ठीक करने के लिए,
product_available: true
को सेट करके उस मॉड्यूल कोproduct
partition के लिए उपलब्ध कराएं याproduct_specific: true
को सेट करके मॉड्यूल कोproduct
partition में ले जाएं.
बिल्ड से जुड़ी गड़बड़ियों को ठीक करें और पक्का करें कि डिवाइस का बिल्ड सही तरीके से हो.
इमेज को फ़्लैश करें और डिवाइस के बूट और लॉग में रनटाइम की गड़बड़ियां देखें.
- अगर टेस्ट केस लॉग का
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