Android 11, product পার্টিশন আনবান্ডেল করে, এটি
system এবং vendor পার্টিশন থেকে স্বতন্ত্র হয়ে যায়। এইসব পরিবর্তনের অংশ হিসেবে,
আপনি এখন নেটিভ ও Java
ইন্টারফেসের (যা vendor
পার্টিশনের জন্য ইন্টারফেস এনফোর্সমেন্ট কীভাবে কাজ করে তার মতোই) অ্যাক্সেস product পার্টিশনকে নিয়ন্ত্রণ করতে পারবেন।
নেটিভ ইন্টারফেস প্রয়োগ করা
নেটিভ ইন্টারফেস এনফোর্সমেন্ট চালু করতে, PRODUCT_PRODUCT_VNDK_VERSION
কে current হিসেবে সেট করুন। (টার্গেটের জন্য শিপিং API লেভেল ২৯-এর বেশি হলে, ভার্সন অটোমেটিক current-এ সেট হয়ে যায়।) এনফোর্সমেন্ট এগুলির অনুমতি দেয়:
- লিঙ্ক করার জন্য
productপার্টিশনে নেটিভ মডিউল:productপার্টিশনের মধ্যে থাকা অন্যান্য মডিউলে স্ট্যাটিক বা ডাইনামিক উপায়ে, যার মধ্যে স্ট্যাটিক, শেয়ার করা বা হেডার লাইব্রেরি অন্তর্ভুক্ত।systemপার্টিশনে VNDK লাইব্রেরিতে ডাইনামিকালি।
/product/libবা/product/lib64-এর লাইব্রেরির সাথে লিঙ্ক করার জন্য আনবান্ডেল করা APK-তেproductপার্টিশনে JNI লাইব্রেরি (এটি NDK লাইব্রেরি ছাড়াও)।
এনফোর্সমেন্ট product
পার্টিশন ছাড়া অন্য পার্টিশনে লিঙ্ক করার অনুমতি দেয় না।
বিল্ড টাইম এনফোর্সমেন্ট (Android.bp)
Android 11-এ, সিস্টেম মডিউল, কোর ও ভেন্ডর ইমেজ ভ্যারিয়েন্ট ছাড়াও, প্রোডাক্ট
ইমেজ ভ্যারিয়েন্ট তৈরি করতে পারে। নেটিভ
ইন্টারফেস এনফোর্সমেন্ট চালু করা থাকলে (PRODUCT_PRODUCT_VNDK_VERSION-এর মান
current হিসেবে সেট করা থাকলে):
productপার্টিশনের নেটিভ মডিউলগুলি কোর ভেরিয়েন্টের পরিবর্তে প্রোডাক্ট ভেরিয়েন্টে থাকে।Android.bpফাইলেproduct_available: trueআছে এমন মডিউলগুলি প্রোডাক্ট ভেরিয়েন্টের জন্য উপলভ্য।product_specific: trueনির্দিষ্ট করে এমন লাইব্রেরি বা বাইনারি,product_specific: trueবাproduct_available: trueনির্দিষ্ট করে এমন অন্যান্য লাইব্রেরির সাথে সেগুলিরAndroid.bpফাইলে লিঙ্ক করতে পারে।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 |
N/A | কোর, প্রোডাক্ট |
vendor_available: true ও product_available:
true |
N/A | কোর, প্রোডাক্ট, ভেন্ডর |
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 ইন্টারফেস এনফোর্সমেন্ট চালু করতে, PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE-কে true হিসেবে সেট করুন। (টার্গেটের জন্য শিপিং API লেভেল ২৯-এর
চেয়ে বেশি হলে, ভ্যালু অটোমেটিক true হিসেবে সেট হয়ে যায়।) চালু করা হলে, এনফোর্সমেন্ট নিম্নলিখিত অ্যাক্সেস
অনুমতি দেয় বা দেয় না:
| API | /system | /system_ext | /product | /vendor | /data |
|---|---|---|---|---|---|
| পাবলিক API | |||||
| @SystemApi | |||||
| @hide API |
vendor পার্টিশনের মতো, product পার্টিশনে কোনও অ্যাপ বা জাভা লাইব্রেরিকে শুধুমাত্র পাবলিক এবং সিস্টেম API ব্যবহার করার অনুমতি দেওয়া হয়; লুকানো API ব্যবহার করে এমন লাইব্রেরির সাথে লিঙ্ক করার অনুমতি দেওয়া হয় না। এই বিধিনিষেধের মধ্যে বিল্ড
টাইমে লিঙ্ক করা এবং রানটাইমে রিফ্লেকশন অন্তর্ভুক্ত।
বিল্ড টাইম এনফোর্সমেন্ট
বিল্ড করার সময়, Make এবং Soong যাচাই করে যে product
পার্টিশনে Java মডিউল platform_apis এবং
sdk_version ফিল্ড চেক করে লুকানো API ব্যবহার করে না। product পার্টিশনের অ্যাপের sdk_version-এ current, system_current বা API-এর নিউমেরিক ভার্সন থাকতে হবে
এবং platform_apis ফিল্ড খালি থাকতে হবে।
রানটাইম এনফোর্সমেন্ট
Android রানটাইম যাচাই করে যে product পার্টিশনে থাকা অ্যাপগুলি রিফ্লেকশন সহ
লুকানো API ব্যবহার করে না। বিবরণের জন্য, নন-SDK
ইন্টারফেসের
উপর বিধিনিষেধ দেখুন।
প্রোডাক্ট ইন্টারফেস এনফোর্সমেন্ট চালু করুন
প্রোডাক্ট ইন্টারফেস এনফোর্সমেন্ট চালু করতে এই বিভাগে দেওয়া ধাপগুলি অনুসরণ করুন।
| ধাপ | টাস্ক | প্রয়োজনীয় |
|---|---|---|
| 1 | আপনার নিজস্ব সিস্টেম মেকফাইল নির্ধারণ করুন যা system পার্টিশনের জন্য প্যাকেজ নির্দিষ্ট করে, তারপর device.mk-এ আর্টিফ্যাক্ট পাথ প্রয়োজনীয়তা চেক সেট করুন (system পার্টিশনে ননসিস্টেম মডিউল ইনস্টল করা প্রতিরোধ করতে)। |
না |
| 2 | অনুমতি আছে এমন তালিকা পরিষ্কার করুন। | না |
| 3 | নেটিভ ইন্টারফেস এনফোর্স করুন এবং রানটাইম লিঙ্ক সংক্রান্ত সমস্যা শনাক্ত করুন (Java এনফোর্সমেন্টের সাথে সমান্তরালভাবে রান করতে পারে)। | Y |
| 4 | Java ইন্টারফেস প্রয়োগ করুন এবং রানটাইম আচরণ যাচাই করুন (নেটিভ প্রয়োগের সাথে সমান্তরালভাবে রান করতে পারে)। | Y |
| 5 | রানটাইম আচরণ চেক করুন। | Y |
| 6 | প্রোডাক্ট ইন্টারফেস এনফোর্সমেন্ট সহ device.mk আপডেট করুন। |
Y |
ধাপ ১: makefile তৈরি করুন এবং আর্টিফ্যাক্ট পাথ চেক করার সুবিধা চালু করুন
এই ধাপে, আপনি system মেকফাইল নির্ধারণ করেন।
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-এর বাইরের makefile, root বা system পার্টিশনে
ইনস্টল করা মডিউল অন্তর্ভুক্ত করতে পারবে না। এইসব মডিউল অন্তর্ভুক্ত করতে, আপনাকে অবশ্যই
oem_system.mk ফাইলেই অথবা অন্তর্ভুক্ত মেকফাইলে এগুলি সংজ্ঞায়িত করতে হবে।
অননুমোদিত পাথে মডিউল ইনস্টল করার চেষ্টা করলে বিল্ড ভেঙে যায়।
ব্রেক ঠিক করতে, নিম্নলিখিতগুলির মধ্যে একটি করুন:
বিকল্প ১:
oem_system.mk-এ অন্তর্ভুক্ত makefile-এ সিস্টেম মডিউল অন্তর্ভুক্ত করুন। এর ফলে আর্টিফ্যাক্ট পাথের প্রয়োজনীয়তা পূরণ হয় (কারণ মডিউল এখন অন্তর্ভুক্ত মেকফাইলে আছে) এবং এর ফলে `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_available: trueসেট করেproductপার্টিশনে সেই মডিউল উপলভ্য করুন অথবাproduct_specific: trueসেট করেproductপার্টিশনে মডিউলটি সরান।
বিল্ড সংক্রান্ত সমস্যার সমাধান করুন এবং নিশ্চিত করুন যে ডিভাইসটি সফলভাবে বিল্ড করা হয়েছে।
ইমেজ ফ্ল্যাশ করুন এবং ডিভাইস বুট ও লগে রানটাইম সংক্রান্ত সমস্যা আছে কিনা দেখুন।
- টেস্ট কেস লগ থেকে
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.প্রতীক সংক্রান্ত সমস্যা। এই সমস্যার অর্থ হল, কোনও সিম্বল খুঁজে পাওয়া যাচ্ছে না কারণ এটি একটি লুকানো API-তে আছে। এটি ঠিক করতে, দৃশ্যমান (লুকানো নয়) API ব্যবহার করুন অথবা বিকল্প খুঁজে নিন। সমস্যার উদাহরণ:
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 (যা অ্যাপ কোনও লুকানো API ব্যবহার করলে
লগ তৈরি করে) ব্যবহার করে
লগের মাধ্যমে লুকানো API-এর ব্যবহার মনিটর করতে পারবেন। এছাড়াও, আপনি ব্যবহারের ধরন (লিঙ্কিং বা রিফ্লেকশন),
বিধিনিষেধের লেভেল এবং কল স্ট্যাক পেতে
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 := currentPRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true