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

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

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

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

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

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

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

অ্যান্ড্রয়েড ১১-এ, সিস্টেম মডিউলগুলি কোর এবং ভেন্ডর ইমেজ ভেরিয়েন্টের পাশাপাশি একটি প্রোডাক্ট ইমেজ ভেরিয়েন্ট তৈরি করতে পারে। যখন নেটিভ ইন্টারফেস এনফোর্সমেন্ট সক্ষম করা থাকে ( PRODUCT_PRODUCT_VNDK_VERSION current তে সেট করা থাকে ):

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

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

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

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

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

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

এপিআই /সিস্টেম /সিস্টেম_এক্সটি /পণ্য /বিক্রেতা /ডেটা
পাবলিক এপিআই
@সিস্টেমএপি
@hide API

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

বিল্ড টাইম এনফোর্সমেন্ট

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

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

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

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

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

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

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

এই ধাপে, আপনি 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 এ সংজ্ঞায়িত পাথের বাইরে আর্টিফ্যাক্ট ইনস্টল করা থেকে বিরত রাখে।

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

  • বিকল্প ১: oem_system.mk এ অন্তর্ভুক্ত makefiles-এ সিস্টেম মডিউল অন্তর্ভুক্ত করুন। এর ফলে আর্টিফ্যাক্ট পাথের প্রয়োজনীয়তা পূরণ হয় (যেহেতু মডিউলগুলি এখন একটি অন্তর্ভুক্ত 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 সেট করুন, তারপর বিল্ড এবং রানটাইম ত্রুটিগুলি সন্ধান করুন এবং সেগুলি সমাধান করুন। ডিভাইস বুট এবং লগগুলি পরীক্ষা করতে এবং রানটাইম লিঙ্ক ব্যর্থতাগুলি খুঁজে বের করতে এবং ঠিক করতে:

  1. PRODUCT_PRODUCT_VNDK_VERSION := current সেট করুন।

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

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

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

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

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

এই ধাপে, আপনি 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
    

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

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

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

    ./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;
    

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

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

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

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true