প্রোডাক্ট পার্টিশন ইন্টারফেস প্রয়োগ করা

অ্যান্ড্রয়েড 11 product পার্টিশনটিকে আনবান্ড করে, এটিকে system এবং vendor পার্টিশন থেকে স্বাধীন করে। এই পরিবর্তনগুলির অংশ হিসাবে, আপনি এখন নেটিভ এবং জাভা ইন্টারফেসে product পার্টিশনের অ্যাক্সেস নিয়ন্ত্রণ করতে পারেন (যা vendor পার্টিশনের জন্য ইন্টারফেস এনফোর্সমেন্ট কীভাবে কাজ করে তার অনুরূপ)।

নেটিভ ইন্টারফেস প্রয়োগ করা হচ্ছে

নেটিভ ইন্টারফেস এনফোর্সমেন্ট সক্ষম করতে, PRODUCT_PRODUCT_VNDK_VERSION কে current এ সেট করুন। (লক্ষ্যের জন্য শিপিং এপিআই স্তর 29-এর বেশি হলে সংস্করণটি স্বয়ংক্রিয়ভাবে current হিসাবে সেট করা হয়।) এনফোর্সমেন্ট অনুমতি দেয়:

  • product পার্টিশনে নেটিভ মডিউল লিঙ্ক করতে:
    • স্ট্যাটিক বা গতিশীল product পার্টিশনের অন্যান্য মডিউলের সাথে যা স্ট্যাটিক, শেয়ার করা বা হেডার লাইব্রেরি অন্তর্ভুক্ত করে।
    • system পার্টিশনে ভিএনডিকে লাইব্রেরিতে গতিশীলভাবে।
  • /product/lib বা /product/lib64 (এটি NDK লাইব্রেরি ছাড়াও) লাইব্রেরির সাথে লিঙ্ক করার জন্য product পার্টিশনে আনবান্ডেড APK-এ JNI লাইব্রেরি।

এনফোর্সমেন্ট product পার্টিশন ব্যতীত অন্য পার্টিশনে অন্য লিঙ্কের অনুমতি দেয় না।

বিল্ড টাইম এনফোর্সমেন্ট (Android.bp)

অ্যান্ড্রয়েড 11-এ, সিস্টেম মডিউলগুলি মূল এবং বিক্রেতার চিত্রের বৈকল্পিক ছাড়াও একটি পণ্য চিত্রের বৈকল্পিক তৈরি করতে পারে। যখন নেটিভ ইন্টারফেস এনফোর্সমেন্ট সক্ষম করা হয় ( PRODUCT_PRODUCT_VNDK_VERSION current সেট করা হয়):

  • product পার্টিশনের নেটিভ মডিউলগুলি মূল ভেরিয়েন্টের পরিবর্তে প্রোডাক্ট ভেরিয়েন্টে থাকে।

  • product_available: true তাদের Android.bp ফাইলগুলিতে সত্য পণ্যের ভেরিয়েন্টে উপলব্ধ।

  • লাইব্রেরি বা বাইনারি যেগুলি product_specific: true অন্য লাইব্রেরির সাথে লিঙ্ক করতে পারে যেগুলি তাদের Android.bp ফাইলগুলিতে product_specific: true বা product_available: true নির্দিষ্ট করে।

  • VNDK লাইব্রেরিগুলির অবশ্যই product_available থাকতে হবে: তাদের Android.bp ফাইলগুলিতে product_available: true যাতে product বাইনারিগুলি VNDK libs-এর সাথে লিঙ্ক করতে পারে৷

নিচের সারণীতে 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 পার্টিশনের বাইরে লাইব্রেরির সাথে লিঙ্ক করতে পারে না (তবে, এই ধরনের প্রক্রিয়াগুলি ভিএনডিকে লাইব্রেরির লিঙ্ক)। রানটাইম লিঙ্ক কনফিগারেশন লঙ্ঘন করার প্রচেষ্টা প্রক্রিয়াটি ব্যর্থ হয় এবং একটি CANNOT LINK EXECUTABLE ত্রুটি বার্তা তৈরি করে।

জাভা ইন্টারফেস প্রয়োগ করা হচ্ছে

জাভা ইন্টারফেস এনফোর্সমেন্ট সক্ষম করতে, PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE কে true সেট করুন। (লক্ষ্যের জন্য শিপিং API স্তর 29-এর বেশি হলে মানটি স্বয়ংক্রিয়ভাবে true সেট করা হয়।) যখন সক্ষম করা হয়, তখন প্রয়োগকারী নিম্নলিখিত অ্যাক্সেসের অনুমতি/অনুমতি দেয়।

API /পদ্ধতি /system_ext / পণ্য /বিক্রেতা /ডেটা
পাবলিক API
@SystemApi
@লুকান API

vendor পার্টিশনের মতো, product পার্টিশনে একটি অ্যাপ বা একটি জাভা লাইব্রেরি শুধুমাত্র সর্বজনীন এবং সিস্টেম API ব্যবহার করার জন্য অনুমোদিত; লুকানো API ব্যবহার করে এমন একটি লাইব্রেরির সাথে লিঙ্ক করা অনুমোদিত নয়। এই সীমাবদ্ধতার মধ্যে রয়েছে বিল্ড টাইমে লিঙ্ক করা এবং রানটাইমে প্রতিফলন।

সময় প্রয়োগ করুন

বিল্ড টাইমে, মেক এবং সুং যাচাই করে যে product পার্টিশনের জাভা মডিউল platform_apis এবং sdk_version ক্ষেত্রগুলি পরীক্ষা করে লুকানো API ব্যবহার করে না। product পার্টিশনে থাকা অ্যাপের sdk_version অবশ্যই current , system_current , বা API-এর সাংখ্যিক সংস্করণ দিয়ে পূর্ণ হতে হবে এবং platform_apis ক্ষেত্রটি খালি থাকতে হবে।

রানটাইম এনফোর্সমেন্ট

অ্যান্ড্রয়েড রানটাইম যাচাই করে যে product পার্টিশনে থাকা অ্যাপগুলি প্রতিফলন সহ লুকানো API ব্যবহার করে না। বিশদ বিবরণের জন্য, নন-SDK ইন্টারফেসে সীমাবদ্ধতা পড়ুন।

পণ্য ইন্টারফেস এনফোর্সমেন্ট সক্ষম করা হচ্ছে

পণ্য ইন্টারফেস প্রয়োগ সক্ষম করতে এই বিভাগে পদক্ষেপগুলি ব্যবহার করুন৷

ধাপ টাস্ক প্রয়োজন
1 আপনার নিজস্ব সিস্টেম মেকফাইল সংজ্ঞায়িত করুন যা system পার্টিশনের জন্য প্যাকেজগুলি নির্দিষ্ট করে, তারপর device.mk এ আর্টিফ্যাক্ট পাথের প্রয়োজনীয়তা পরীক্ষা সেট করুন (ননসিস্টেম মডিউলগুলিকে system পার্টিশনে ইনস্টল করা থেকে বিরত রাখতে)। এন
2 অনুমোদিত তালিকা পরিষ্কার করুন। এন
3 নেটিভ ইন্টারফেস প্রয়োগ করুন এবং রানটাইম লিঙ্ক ব্যর্থতা সনাক্ত করুন (জাভা এনফোর্সমেন্টের সাথে সমান্তরালভাবে চলতে পারে)। Y
4 জাভা ইন্টারফেস প্রয়োগ করুন এবং রানটাইম আচরণ যাচাই করুন (নেটিভ এনফোর্সমেন্টের সাথে সমান্তরালে চলতে পারে)। Y
5 রানটাইম আচরণ পরীক্ষা করুন. Y
6 পণ্য ইন্টারফেস প্রয়োগের সাথে device.mk আপডেট করুন। Y

ধাপ 1: মেকফাইল তৈরি করুন এবং আর্টিফ্যাক্ট পাথ চেক সক্ষম করুন

এই ধাপে, আপনি system মেকফাইল সংজ্ঞায়িত করুন।

  1. একটি মেকফাইল তৈরি করুন যা 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),)
    
  2. 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 দেয়। require-artifacts-in-path

উপরের উদাহরণে, PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS এর সাথে strict সেট করা হয়েছে, oem_system.mk বাইরের মেকফাইলগুলি root বা system পার্টিশনে ইনস্টল করা মডিউলগুলিকে অন্তর্ভুক্ত করতে পারে না। এই মডিউলগুলি অন্তর্ভুক্ত করার জন্য, আপনাকে অবশ্যই সেগুলি oem_system.mk ফাইলে অথবা একটি অন্তর্ভুক্ত মেকফাইলে সংজ্ঞায়িত করতে হবে। অননুমোদিত পাথে মডিউল ইনস্টল করার প্রচেষ্টা বিল্ড ব্রেক সৃষ্টি করে। বিরতি ঠিক করতে, নিম্নলিখিতগুলির মধ্যে একটি করুন:

  • বিকল্প 1: oem_system.mk এ অন্তর্ভুক্ত মেকফাইলে সিস্টেম মডিউল অন্তর্ভুক্ত করুন। এর ফলে আর্টিফ্যাক্ট পাথের প্রয়োজনীয়তা পূরণ হয় (যেমন মডিউলগুলি এখন একটি অন্তর্ভুক্ত মেকফাইলে বিদ্যমান) এবং এইভাবে `require-artifacts-in-path-এ পাথের সেটে ইনস্টলেশনের অনুমতি দেয়।

  • বিকল্প 2: system_ext বা product পার্টিশনে মডিউল ইনস্টল করুন (এবং system পার্টিশনে মডিউল ইনস্টল করবেন না)।

  • বিকল্প 3: PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST এ মডিউল যোগ করুন। এই তালিকাগুলি মডিউলগুলি ইনস্টল করার অনুমতি দেয়৷

ধাপ 2: অনুমোদিত তালিকা খালি করুন

এই ধাপে, আপনি PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST খালি করেন যাতে oem_system.mk শেয়ার করা সমস্ত ডিভাইস একটি একক system চিত্রও শেয়ার করতে পারে৷ অনুমোদিত তালিকা খালি করার জন্য, তালিকার যেকোনো মডিউল system_ext বা product পার্টিশনে সরান অথবা system মেক ফাইলে যোগ করুন। এই পদক্ষেপটি ঐচ্ছিক কারণ পণ্য ইন্টারফেস প্রয়োগ সক্ষম করার জন্য একটি সাধারণ system চিত্র সংজ্ঞায়িত করার প্রয়োজন নেই। যাইহোক, অনুমোদিত তালিকা খালি করা system_ext এর সাথে system সীমানা নির্ধারণের জন্য সহায়ক।

ধাপ 3: নেটিভ ইন্টারফেস প্রয়োগ করুন

এই ধাপে, আপনি PRODUCT_PRODUCT_VNDK_VERSION := current সেট করেন, তারপর বিল্ড এবং রানটাইম ত্রুটিগুলি সন্ধান করুন এবং সেগুলি সমাধান করুন৷ ডিভাইস বুট এবং লগ পরীক্ষা করতে এবং রানটাইম লিঙ্ক ব্যর্থতা খুঁজে পেতে এবং ঠিক করতে:

  1. PRODUCT_PRODUCT_VNDK_VERSION := current

  2. ডিভাইসটি তৈরি করুন এবং বিল্ড ত্রুটিগুলি সন্ধান করুন। আপনি অনুপস্থিত পণ্য ভেরিয়েন্ট বা মূল ভেরিয়েন্টের জন্য কয়েকটি বিল্ড বিরতি দেখতে পারেন। সাধারণ বিরতির মধ্যে রয়েছে:

    • যে কোনো hidl_interface মডিউল যেটিতে product_specific: true সিস্টেম মডিউলের জন্য উপলব্ধ হবে না। ঠিক করতে, product_specific: true দিয়ে system_ext_specfic: true প্রতিস্থাপন করুন।
    • মডিউলগুলি পণ্য মডিউলগুলির জন্য প্রয়োজনীয় পণ্যের বৈকল্পিক অনুপস্থিত থাকতে পারে। ঠিক করতে, product_available: true সেট করে সেই মডিউলটিকে product পার্টিশনে উপলব্ধ করুন অথবা product_specific: true সেট করে product পার্টিশনে মডিউলটি সরান।
  3. বিল্ড ত্রুটিগুলি সমাধান করুন এবং নিশ্চিত করুন যে ডিভাইসটি সফলভাবে তৈরি হয়েছে৷

  4. ছবিটি ফ্ল্যাশ করুন এবং ডিভাইস বুট এবং লগগুলিতে রানটাইম ত্রুটিগুলি সন্ধান করুন৷

    • যদি একটি টেস্ট কেস লগ থেকে linker ট্যাগ একটি CANNOT LINK EXECUTABLE মেসেজ দেখায়, মেক ফাইলটি একটি নির্ভরতা অনুপস্থিত (এবং নির্মাণের সময় ক্যাপচার করা হয়নি)।
    • বিল্ড সিস্টেম থেকে এটি পরীক্ষা করতে, shared_libs: বা required: ক্ষেত্রে প্রয়োজনীয় লাইব্রেরি যোগ করুন।
  5. উপরে দেওয়া নির্দেশিকা ব্যবহার করে অনুপস্থিত নির্ভরতাগুলি সমাধান করুন।

ধাপ 4: জাভা ইন্টারফেস প্রয়োগ করুন

এই ধাপে, আপনি PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true সেট করুন, তারপর ফলাফল বিল্ড ত্রুটিগুলি খুঁজুন এবং ঠিক করুন৷ দুটি নির্দিষ্ট ধরনের ত্রুটির জন্য দেখুন:

  • লিঙ্ক টাইপ ত্রুটি. এই ত্রুটিটি নির্দেশ করে যে একটি অ্যাপ জাভা মডিউলের সাথে লিঙ্ক করে যার একটি বিস্তৃত 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
    

ধাপ 5: রানটাইম আচরণ পরীক্ষা করুন

এই ধাপে, আপনি রানটাইম আচরণ প্রত্যাশিত হিসাবে যাচাই করুন. ডিবাগযোগ্য অ্যাপগুলির জন্য, আপনি StrictMode.detectNonSdkApiUsage ব্যবহার করে লুকানো API ব্যবহার নিরীক্ষণ করতে পারেন (যা অ্যাপটি একটি লুকানো API ব্যবহার করলে একটি লগ তৈরি করে)। বিকল্পভাবে, আপনি ব্যবহারের ধরন (লিঙ্কিং বা প্রতিফলন), সীমাবদ্ধতা স্তর এবং কল স্ট্যাক পেতে ভেরিডেক্স স্ট্যাটিক বিশ্লেষণ টুল ব্যবহার করতে পারেন।

  • ভেরিডেক্স সিনট্যাক্স:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
    
  • উদাহরণ ভেরিডেক্স ফলাফল:

    #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;
    

ভেরিডেক্স ব্যবহারের বিস্তারিত জানার জন্য, ভেরিডেক্স টুল ব্যবহার করে পরীক্ষা দেখুন।

ধাপ 6: device.mk আপডেট করুন

সমস্ত বিল্ড এবং রানটাইম ব্যর্থতা ঠিক করার পরে, এবং রানটাইম আচরণগুলি প্রত্যাশিত হিসাবে যাচাই করার পরে, device.mk এ নিম্নলিখিতগুলি সেট করুন:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true