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
partition के अलावा किसी दूसरे partition के लिंक को अनुमति नहीं देती.
बिल्ड टाइम पर लागू होने वाला नीति उल्लंघन ठीक करने का तरीका (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 |
लागू नहीं | core, product |
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
पार्टीशन के बाहर की लाइब्रेरी से लिंक नहीं हो सकता. हालांकि, ऐसी प्रोसेस, VNDK लाइब्रेरी से लिंक हो सकती हैं. रनटाइम लिंक कॉन्फ़िगरेशन का उल्लंघन करने की कोशिश करने पर, प्रोसेस पूरी नहीं हो पाती और 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
फ़ाइल में या शामिल की गई किसी मेकफ़ाइल में तय करना होगा.
जिन पाथ पर मॉड्यूल इंस्टॉल करने की अनुमति नहीं है उन पर मॉड्यूल इंस्टॉल करने की कोशिश करने पर, बिल्डिंग रुक जाती है. ब्रेक को ठीक करने के लिए, इनमें से कोई एक काम करें:
पहला विकल्प:
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