APEX ফাইল ফরম্যাট

অ্যান্ড্রয়েড পনি এক্সপ্রেস (APEX) কন্টেইনার ফরম্যাটটি অ্যান্ড্রয়েড ১০-এ চালু করা হয়েছিল এবং এটি নিম্ন-স্তরের সিস্টেম মডিউলগুলির ইনস্টল প্রক্রিয়ায় ব্যবহৃত হয়। এই ফরম্যাটটি এমন সিস্টেম কম্পোনেন্টগুলির আপডেট সহজ করে, যেগুলো স্ট্যান্ডার্ড অ্যান্ড্রয়েড অ্যাপ্লিকেশন মডেলের সাথে খাপ খায় না। এর কিছু উদাহরণ হলো নেটিভ সার্ভিস ও লাইব্রেরি, হার্ডওয়্যার অ্যাবস্ট্রাকশন লেয়ার ( HALs ), রানটাইম ( ART ) এবং ক্লাস লাইব্রেরি।

"APEX" শব্দটি একটি APEX ফাইলকেও বোঝাতে পারে।

পটভূমি

যদিও অ্যান্ড্রয়েড প্যাকেজ ইনস্টলার অ্যাপের (যেমন গুগল প্লে স্টোর অ্যাপ) মাধ্যমে স্ট্যান্ডার্ড অ্যাপ মডেলের অন্তর্ভুক্ত মডিউলগুলোর (যেমন সার্ভিস, অ্যাক্টিভিটি) আপডেট সমর্থন করে, নিম্ন-স্তরের ওএস উপাদানগুলোর জন্য একই ধরনের মডেল ব্যবহারের নিম্নলিখিত অসুবিধাগুলো রয়েছে:

  • বুট সিকোয়েন্সের শুরুতে APK-ভিত্তিক মডিউল ব্যবহার করা যায় না। প্যাকেজ ম্যানেজার হলো অ্যাপ সম্পর্কিত তথ্যের কেন্দ্রীয় ভান্ডার এবং এটি শুধুমাত্র অ্যাক্টিভিটি ম্যানেজার থেকে চালু করা যায়, যা বুট প্রক্রিয়ার পরবর্তী পর্যায়ে প্রস্তুত হয়।
  • APK ফরম্যাট (বিশেষ করে ম্যানিফেস্ট) অ্যান্ড্রয়েড অ্যাপের জন্য ডিজাইন করা হয়েছে এবং সিস্টেম মডিউলগুলো সবসময় এর সাথে ভালোভাবে খাপ খায় না।

ডিজাইন

এই অংশে APEX ফাইল ফরম্যাটের সামগ্রিক নকশা এবং APEX ম্যানেজার সম্পর্কে বর্ণনা করা হয়েছে, যা APEX ফাইলগুলো পরিচালনা করে এমন একটি পরিষেবা।

APEX-এর জন্য এই ডিজাইনটি কেন নির্বাচন করা হয়েছিল সে সম্পর্কে আরও তথ্যের জন্য, “APEX তৈরির সময় বিবেচিত বিকল্পসমূহ” দেখুন।

এপেক্স ফরম্যাট

এটি একটি APEX ফাইলের ফরম্যাট।

APEX ফাইল ফরম্যাট

চিত্র ১. এপেক্স ফাইল ফরম্যাট

সর্বোচ্চ স্তরে, একটি APEX ফাইল হলো একটি জিপ ফাইল, যেখানে ফাইলগুলো অসংকুচিত অবস্থায় এবং ৪ কিলোবাইট সীমানায় সংরক্ষিত থাকে।

একটি APEX ফাইলে চারটি ফাইল থাকে:

  • apex_manifest.json
  • AndroidManifest.xml
  • apex_payload.img
  • apex_pubkey

apex_manifest.json ফাইলটিতে প্যাকেজের নাম এবং সংস্করণ থাকে, যা একটি APEX ফাইলকে শনাক্ত করে। এটি JSON ফরম্যাটে একটি ApexManifest প্রোটোকল বাফার।

AndroidManifest.xml ফাইলটি APEX ফাইলকে APK-সম্পর্কিত টুল এবং পরিকাঠামো, যেমন ADB, PackageManager, এবং প্যাকেজ ইনস্টলার অ্যাপ (যেমন প্লে স্টোর) ব্যবহার করার সুযোগ দেয়। উদাহরণস্বরূপ, APEX ফাইলটি aapt মতো একটি বিদ্যমান টুল ব্যবহার করে ফাইলটি থেকে মৌলিক মেটাডেটা পরীক্ষা করতে পারে। ফাইলটিতে প্যাকেজের নাম এবং ভার্সনের তথ্য থাকে। এই তথ্য সাধারণত apex_manifest.json ফাইলেও পাওয়া যায়।

নতুন কোড এবং APEX-সম্পর্কিত সিস্টেমের জন্য AndroidManifest.xml পরিবর্তে apex_manifest.json ব্যবহার করা বাঞ্ছনীয়। AndroidManifest.xml অতিরিক্ত টার্গেটিং তথ্য থাকতে পারে যা বিদ্যমান অ্যাপ পাবলিশিং টুলগুলো ব্যবহার করতে পারে।

apex_payload.img হলো dm-verity দ্বারা সমর্থিত একটি ext4 ফাইল সিস্টেম ইমেজ। ইমেজটি রানটাইমে একটি লুপব্যাক ডিভাইসের মাধ্যমে মাউন্ট করা হয়। বিশেষত, হ্যাশ ট্রি এবং মেটাডেটা ব্লক libavb লাইব্রেরি ব্যবহার করে তৈরি করা হয়। ফাইল সিস্টেম পেলোড পার্স করা হয় না (কারণ ইমেজটি ইন-প্লেস মাউন্টযোগ্য হওয়া উচিত)। সাধারণ ফাইলগুলো apex_payload.img ফাইলের ভিতরে অন্তর্ভুক্ত থাকে।

apex_pubkey হলো ফাইল সিস্টেম ইমেজ সাইন করার জন্য ব্যবহৃত পাবলিক কী। রানটাইমে, এই কী নিশ্চিত করে যে ডাউনলোড করা APEX ফাইলটি সেই একই সত্তা দ্বারা স্বাক্ষরিত হয়েছে, যে সত্তা বিল্ট-ইন পার্টিশনগুলোতে থাকা একই APEX ফাইলটি সাইন করে থাকে।

APEX নামকরণের নির্দেশিকা

প্ল্যাটফর্মের অগ্রগতির সাথে সাথে নতুন APEX-গুলোর মধ্যে নামকরণের দ্বন্দ্ব এড়াতে, নিম্নলিখিত নামকরণের নির্দেশিকাগুলো ব্যবহার করুন:

  • com.android.*
    • AOSP APEX-এর জন্য সংরক্ষিত। কোনো কোম্পানি বা ডিভাইসের জন্য স্বতন্ত্র নয়।
  • com.<companyname>.*
    • একটি কোম্পানির জন্য সংরক্ষিত। ঐ কোম্পানির একাধিক ডিভাইস দ্বারা এটি ব্যবহৃত হতে পারে।
  • com.<companyname>.<devicename>.*
    • কোনো নির্দিষ্ট ডিভাইস (বা ডিভাইসের একটি উপসেট)-এর জন্য স্বতন্ত্র APEX-গুলোর জন্য সংরক্ষিত।

এপেক্স ম্যানেজার

APEX ম্যানেজার (বা apexd ) হলো একটি স্বতন্ত্র নেটিভ প্রসেস যা APEX ফাইল যাচাই, ইনস্টল এবং আনইনস্টল করার জন্য দায়ী। এই প্রসেসটি বুট সিকোয়েন্সের শুরুতেই চালু হয় এবং প্রস্তুত থাকে। APEX ফাইলগুলো সাধারণত ডিভাইসে /system/apex অধীনে আগে থেকেই ইনস্টল করা থাকে। যদি কোনো আপডেট উপলব্ধ না থাকে, তবে APEX ম্যানেজার ডিফল্টরূপে এই প্যাকেজগুলো ব্যবহার করে।

একটি APEX-এর আপডেট ক্রমটি PackageManager ক্লাস ব্যবহার করে এবং তা নিম্নরূপ।

  1. একটি APEX ফাইল প্যাকেজ ইনস্টলার অ্যাপ, ADB বা অন্য কোনো উৎস থেকে ডাউনলোড করা হয়।
  2. প্যাকেজ ম্যানেজার ইনস্টলেশন প্রক্রিয়া শুরু করে। ফাইলটিকে APEX হিসেবে শনাক্ত করার পর, প্যাকেজ ম্যানেজার APEX ম্যানেজারের কাছে নিয়ন্ত্রণ হস্তান্তর করে।
  3. এপেক্স ম্যানেজার এপেক্স ফাইলটি যাচাই করে।
  4. APEX ফাইলটি যাচাই করা হলে, APEX ম্যানেজারের অভ্যন্তরীণ ডেটাবেস আপডেট করা হয় যাতে এটি প্রতিফলিত হয় যে পরবর্তী বুটে APEX ফাইলটি সক্রিয় হবে।
  5. প্যাকেজ সফলভাবে যাচাই করা হলে ইনস্টল অনুরোধকারী একটি ব্রডকাস্ট বার্তা পান।
  6. ইনস্টলেশন চালিয়ে যাওয়ার জন্য সিস্টেমটি রিবুট করতে হবে।
  7. পরবর্তী বুটে, APEX ম্যানেজার চালু হয়, অভ্যন্তরীণ ডেটাবেস পড়ে এবং তালিকাভুক্ত প্রতিটি APEX ফাইলের জন্য নিম্নলিখিত কাজগুলো করে:

    1. APEX ফাইলটি যাচাই করে।
    2. APEX ফাইল থেকে একটি লুপব্যাক ডিভাইস তৈরি করে।
    3. লুপব্যাক ডিভাইসের উপরে একটি ডিভাইস ম্যাপার ব্লক ডিভাইস তৈরি করে।
    4. ডিভাইস ম্যাপার ব্লক ডিভাইসটিকে একটি অনন্য পাথে (উদাহরণস্বরূপ, /apex/ name @ ver ) মাউন্ট করে।

অভ্যন্তরীণ ডেটাবেসে তালিকাভুক্ত সমস্ত APEX ফাইল মাউন্ট করা হলে, APEX ম্যানেজার অন্যান্য সিস্টেম কম্পোনেন্টকে ইনস্টল করা APEX ফাইলগুলি সম্পর্কে তথ্য জিজ্ঞাসা করার জন্য একটি বাইন্ডার পরিষেবা প্রদান করে। উদাহরণস্বরূপ, অন্যান্য সিস্টেম কম্পোনেন্টগুলি ডিভাইসে ইনস্টল করা APEX ফাইলগুলির তালিকা জিজ্ঞাসা করতে পারে অথবা একটি নির্দিষ্ট APEX যেখানে মাউন্ট করা আছে তার সঠিক পাথ জিজ্ঞাসা করতে পারে, যাতে ফাইলগুলি অ্যাক্সেস করা যায়।

APEX ফাইলগুলো হলো APK ফাইল

APEX ফাইলগুলো বৈধ APK ফাইল, কারণ এগুলো হলো স্বাক্ষরিত জিপ আর্কাইভ (APK সিগনেচার স্কিম ব্যবহার করে) এবং এগুলোর মধ্যে একটি AndroidManifest.xml ফাইল থাকে। এর ফলে APEX ফাইলগুলো APK ফাইলের জন্য ব্যবহৃত পরিকাঠামো, যেমন প্যাকেজ ইনস্টলার অ্যাপ, সাইনিং ইউটিলিটি এবং প্যাকেজ ম্যানেজার, ব্যবহার করতে পারে।

একটি APEX ফাইলের ভিতরে থাকা AndroidManifest.xml ফাইলটি খুবই সংক্ষিপ্ত, যাতে প্যাকেজের name , versionCode এবং সূক্ষ্ম টার্গেটিংয়ের জন্য ঐচ্ছিক targetSdkVersion , minSdkVersionmaxSdkVersion থাকে। এই তথ্যের ফলে APEX ফাইলগুলোকে প্যাকেজ ইনস্টলার অ্যাপ এবং ADB-এর মতো বিদ্যমান চ্যানেলগুলোর মাধ্যমে ডেলিভার করা যায়।

সমর্থিত ফাইলের প্রকার

APEX ফরম্যাট নিম্নলিখিত ফাইল প্রকারগুলিকে সমর্থন করে:

  • নেটিভ শেয়ার্ড লাইব্রেরি
  • নেটিভ এক্সিকিউটেবল
  • জার ফাইল
  • ডেটা ফাইল
  • কনফিগারেশন ফাইল

এর মানে এই নয় যে APEX এই সব ফাইল টাইপ আপডেট করতে পারে। কোনো ফাইল টাইপ আপডেট করা যাবে কি না, তা নির্ভর করে প্ল্যাটফর্ম এবং ফাইল টাইপগুলোর ইন্টারফেসের সংজ্ঞাগুলো কতটা স্থিতিশীল তার উপর।

স্বাক্ষর করার বিকল্প

APEX ফাইল দুটি উপায়ে সাইন করা হয়। প্রথমত, apex_payload.img ফাইলটি (বিশেষত, apex_payload.img এর সাথে যুক্ত vbmeta ডেসক্রিপ্টরটি) একটি কী (key) দিয়ে সাইন করা হয়। তারপর, APK সিগনেচার স্কিম v3 ব্যবহার করে সম্পূর্ণ APEX-টি সাইন করা হয়। এই প্রক্রিয়ায় দুটি ভিন্ন কী ব্যবহার করা হয়।

ডিভাইস প্রান্তে, vbmeta ডেসক্রিপ্টর স্বাক্ষর করতে ব্যবহৃত প্রাইভেট কী-এর অনুরূপ একটি পাবলিক কী ইনস্টল করা হয়। APEX ম্যানেজার ইনস্টল করার জন্য অনুরোধ করা APEX-গুলো যাচাই করতে এই পাবলিক কী ব্যবহার করে। প্রতিটি APEX অবশ্যই ভিন্ন ভিন্ন কী দিয়ে স্বাক্ষরিত হতে হবে এবং এটি বিল্ড টাইম ও রানটাইম উভয় সময়েই বলবৎ করা হয়।

বিল্ট-ইন পার্টিশনে APEX

APEX ফাইলগুলো /system মতো বিল্ট-ইন পার্টিশনে থাকতে পারে। পার্টিশনটি ইতিমধ্যেই dm-verity-এর উপরে থাকে, তাই APEX ফাইলগুলো সরাসরি লুপব্যাক ডিভাইসের উপরে মাউন্ট করা হয়।

যদি কোনো APEX বিল্ট-ইন পার্টিশনে থাকে, তবে একই প্যাকেজ নাম এবং একটি নির্দিষ্ট ভার্সন কোড সহ একটি APEX প্যাকেজ প্রদান করে APEX-টি আপডেট করা যায়। নতুন APEX-টি /data তে সংরক্ষিত হয় এবং APK-এর মতোই, নতুন ইনস্টল করা ভার্সনটি বিল্ট-ইন পার্টিশনে আগে থেকে থাকা ভার্সনটিকে আড়াল করে দেয়। কিন্তু APK-এর থেকে ভিন্ন, APEX-এর নতুন ইনস্টল করা ভার্সনটি শুধুমাত্র রিবুট করার পরেই সক্রিয় হয়।

কার্নেলের প্রয়োজনীয়তা

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

APEX মডিউল ব্যবহার করার সময় ভালো সিস্টেম পারফরম্যান্স অর্জনের জন্য লুপব্যাক ড্রাইভার এবং dm-verity-এর পারফরম্যান্স গুরুত্বপূর্ণ।

সমর্থিত কার্নেল সংস্করণ

কার্নেল সংস্করণ ৪.৪ বা তার উচ্চতর সংস্করণে ব্যবহৃত ডিভাইসগুলিতে APEX মেইনলাইন মডিউল সমর্থিত। Android 10 বা তার উচ্চতর সংস্করণসহ বাজারে আসা নতুন ডিভাইসগুলিতে APEX মডিউল সমর্থনের জন্য অবশ্যই কার্নেল সংস্করণ ৪.৯ বা তার উচ্চতর সংস্করণ ব্যবহার করতে হবে।

প্রয়োজনীয় কার্নেল প্যাচ

APEX মডিউল সমর্থন করার জন্য প্রয়োজনীয় কার্নেল প্যাচগুলো অ্যান্ড্রয়েড কমন ট্রি-তে অন্তর্ভুক্ত রয়েছে। APEX সমর্থনের জন্য প্যাচগুলো পেতে, অ্যান্ড্রয়েড কমন ট্রি-র সর্বশেষ সংস্করণটি ব্যবহার করুন।

কার্নেল সংস্করণ ৪.৪

এই সংস্করণটি শুধুমাত্র সেইসব ডিভাইসের জন্য সমর্থিত যেগুলো অ্যান্ড্রয়েড ৯ থেকে অ্যান্ড্রয়েড ১০-এ আপগ্রেড করা হয়েছে এবং APEX মডিউল সমর্থন করতে চায়। প্রয়োজনীয় প্যাচগুলো পেতে, android-4.4 ব্রাঞ্চ থেকে একটি ডাউন-মার্জ করার জন্য জোরালোভাবে সুপারিশ করা হচ্ছে। কার্নেল সংস্করণ ৪.৪-এর জন্য প্রয়োজনীয় স্বতন্ত্র প্যাচগুলোর একটি তালিকা নিচে দেওয়া হলো।

  • আপস্ট্রিম: লুপ: লজিক্যাল ব্লক সাইজ পরিবর্তনের জন্য ioctl যোগ করা হয়েছে ( 4.4 )
  • ব্যাকপোর্ট: ব্লক/লুপ: hw_sectors সেট করুন ( 4.4 )
  • আপস্ট্রিম: লুপ: কম্প্যাট আইওসিটিএল-এ ( 4.4 ) LOOP_SET_BLOCK_SIZE যোগ করুন
  • অ্যান্ড্রয়েড: mnt: next_descendent ঠিক করা হয়েছে ( 4.4 )
  • অ্যান্ড্রয়েড: mnt: রিমউন্ট স্লেভদের স্লেভদের কাছেও প্রচার করা উচিত ( 4.4 )
  • অ্যান্ড্রয়েড: mnt: রিমউন্ট সঠিকভাবে প্রচার করুন ( 4.4 )
  • "ANDROID: dm verity: add minimum prefetch size" ( 4.4 ) রিভার্ট করুন
  • আপস্ট্রিম: লুপ: অফসেট বা ব্লক_সাইজ পরিবর্তিত হলে ক্যাশে ড্রপ করুন ( 4.4 )

কার্নেল সংস্করণ ৪.৯/৪.১৪/৪.১৯

কার্নেল সংস্করণ 4.9/4.14/4.19-এর জন্য প্রয়োজনীয় প্যাচগুলো পেতে, android-common শাখা থেকে ডাউন-মার্জ করুন।

প্রয়োজনীয় কার্নেল কনফিগারেশন বিকল্পগুলি

নিচের তালিকাটি অ্যান্ড্রয়েড ১০-এ প্রবর্তিত APEX মডিউলগুলো সমর্থন করার জন্য প্রয়োজনীয় মৌলিক কনফিগারেশনের বিবরণ দেখাচ্ছে। তারকাচিহ্ন (*) যুক্ত আইটেমগুলো অ্যান্ড্রয়েড ৯ এবং তার পূর্ববর্তী সংস্করণগুলো থেকে বিদ্যমান প্রয়োজনীয়তা।

(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices)
CONFIG_BLK_DEV_LOOP=Y # for loop device support
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices
(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity
(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity
CONFIG_DM_VERITY=Y # DM-verity support

কার্নেল কমান্ড-লাইন প্যারামিটারের প্রয়োজনীয়তা

APEX সমর্থন করার জন্য, নিশ্চিত করুন যে কার্নেল কমান্ড-লাইন প্যারামিটারগুলো নিম্নলিখিত শর্তগুলো পূরণ করে:

  • loop.max_loop অবশ্যই সেট করা যাবে না।
  • loop.max_part অবশ্যই ৮ বা তার কম হতে হবে।

একটি এপেক্স তৈরি করুন

এই অংশে অ্যান্ড্রয়েড বিল্ড সিস্টেম ব্যবহার করে কীভাবে একটি APEX তৈরি করতে হয় তা বর্ণনা করা হয়েছে। নিচে apex.test নামের একটি APEX-এর জন্য Android.bp এর একটি উদাহরণ দেওয়া হলো।

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    // libc.so and libcutils.so are included in the apex
    native_shared_libs: ["libc", "libcutils"],
    binaries: ["vold"],
    java_libs: ["core-all"],
    prebuilts: ["my_prebuilt"],
    compile_multilib: "both",
    key: "apex.test.key",
    certificate: "platform",
}

apex_manifest.json উদাহরণ:

{
  "name": "com.android.example.apex",
  "version": 1
}

file_contexts উদাহরণ:

(/.*)?           u:object_r:system_file:s0
/sub(/.*)?       u:object_r:sub_file:s0
/sub/file3       u:object_r:file3_file:s0

APEX-এ ফাইলের প্রকার এবং অবস্থান

ফাইলের ধরন এপেক্সে অবস্থান
শেয়ার্ড লাইব্রেরি /lib এবং /lib64 (x86-এ অনূদিত arm-এর জন্য /lib/arm )
এক্সিকিউটেবল /bin
জাভা লাইব্রেরি /javalib
পূর্ব-নির্মিত /etc

ট্রানজিটিভ নির্ভরতা

APEX ফাইলগুলো স্বয়ংক্রিয়ভাবে নেটিভ শেয়ার্ড লাইব্রেরি বা এক্সিকিউটেবলের ট্রানজিটিভ ডিপেন্ডেন্সি অন্তর্ভুক্ত করে। উদাহরণস্বরূপ, যদি libFoo , libBar এর উপর নির্ভরশীল হয়, তাহলে native_shared_libs প্রপার্টিতে শুধুমাত্র libFoo তালিকাভুক্ত থাকলে দুটি লাইব্রেরিই অন্তর্ভুক্ত করা হয়।

একাধিক ABI পরিচালনা করুন

ডিভাইসের প্রাইমারি এবং সেকেন্ডারি উভয় অ্যাপ্লিকেশন বাইনারি ইন্টারফেসের (ABI) জন্য native_shared_libs প্রপার্টিটি ইনস্টল করুন। যদি কোনো APEX একটিমাত্র ABI (অর্থাৎ, শুধু ৩২-বিট বা শুধু ৬৪-বিট) যুক্ত ডিভাইসকে টার্গেট করে, তবে শুধুমাত্র সেই ABI-এর লাইব্রেরিগুলোই ইনস্টল করা হয়।

নিচে বর্ণিত পদ্ধতি অনুযায়ী শুধুমাত্র ডিভাইসের প্রাথমিক ABI-এর জন্য binaries প্রপার্টিটি ইনস্টল করুন:

  • ডিভাইসটি শুধুমাত্র ৩২-বিটের হলে, বাইনারিটির কেবল ৩২-বিট সংস্করণটিই ইনস্টল করা হয়।
  • ডিভাইসটি যদি শুধু ৬৪-বিটের হয়, তাহলে বাইনারিটির কেবল ৬৪-বিট সংস্করণটিই ইনস্টল করা হয়।

নেটিভ লাইব্রেরি এবং বাইনারিগুলির ABI-এর উপর সূক্ষ্ম নিয়ন্ত্রণ যোগ করতে, multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] প্রোপার্টিগুলি ব্যবহার করুন।

  • first : ডিভাইসের প্রাথমিক ABI-এর সাথে মেলে। বাইনারিগুলির জন্য এটিই ডিফল্ট।
  • lib32 : ডিভাইসের ৩২-বিট ABI-এর সাথে মেলে, যদি সমর্থিত হয়।
  • lib64 : এটি ডিভাইসের ৬৪-বিট ABI সমর্থন করে।
  • prefer32 : ডিভাইসের ৩২-বিট ABI সমর্থিত হলে, তার সাথে মেলে। যদি ৩২-বিট ABI সমর্থিত না হয়, তবে ৬৪-বিট ABI-এর সাথে মেলে।
  • both : উভয় ABI-এর সাথে মেলে। native_shared_libraries এর জন্য এটিই ডিফল্ট।

java , libraries , এবং prebuilts প্রোপার্টিগুলো ABI-অজ্ঞেয়।

এই উদাহরণটি এমন একটি ডিভাইসের জন্য যা ৩২/৬৪ সমর্থন করে এবং ৩২ পছন্দ করে না:

apex {
    // other properties are omitted
    native_shared_libs: ["libFoo"], // installed for 32 and 64
    binaries: ["exec1"], // installed for 64, but not for 32
    multilib: {
        first: {
            native_shared_libs: ["libBar"], // installed for 64, but not for 32
            binaries: ["exec2"], // same as binaries without multilib.first
        },
        both: {
            native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib
            binaries: ["exec3"], // installed for 32 and 64
        },
        prefer32: {
            native_shared_libs: ["libX"], // installed for 32, but not for 64
        },
        lib64: {
            native_shared_libs: ["libY"], // installed for 64, but not for 32
        },
    },
}

vbmeta স্বাক্ষর

প্রতিটি APEX আলাদা কী দিয়ে সাইন করুন। যখন একটি নতুন কী-এর প্রয়োজন হবে, তখন একটি পাবলিক-প্রাইভেট কী পেয়ার তৈরি করুন এবং একটি apex_key মডিউল তৈরি করুন। কী ব্যবহার করে APEX-টি সাইন করার জন্য key প্রপার্টি ব্যবহার করুন। পাবলিক কী-টি স্বয়ংক্রিয়ভাবে avb_pubkey নামে APEX-এ অন্তর্ভুক্ত হয়ে যায়।

# create an rsa key pair
openssl genrsa -out foo.pem 4096

# extract the public key from the key pair
avbtool extract_public_key --key foo.pem --output foo.avbpubkey

# in Android.bp
apex_key {
    name: "apex.test.key",
    public_key: "foo.avbpubkey",
    private_key: "foo.pem",
}

উপরের উদাহরণে, পাবলিক কী-এর নাম ( foo ) কী-টির আইডি হয়ে যায়। একটি APEX সাইন করতে ব্যবহৃত কী-এর আইডি APEX-এর মধ্যেই লেখা থাকে। রানটাইমে, apexd ডিভাইসে থাকা একই আইডিযুক্ত একটি পাবলিক কী ব্যবহার করে APEX-টি ভেরিফাই করে।

এপেক্স স্বাক্ষর

এপিকে (APK) সাইন করার মতোই এপেক্স (APEX) সাইন করুন। এপেক্স দুইবার সাইন করুন; একবার মিনি ফাইল সিস্টেমের ( apex_payload.img ফাইল) জন্য এবং একবার সম্পূর্ণ ফাইলটির জন্য।

ফাইল-স্তরে একটি APEX স্বাক্ষর করতে, এই তিনটি উপায়ের যেকোনো একটিতে certificate প্রপার্টি সেট করুন:

  • সেট করা হয়নি: যদি কোনো মান সেট করা না থাকে, তাহলে APEX-টি PRODUCT_DEFAULT_DEV_CERTIFICATE এ অবস্থিত সার্টিফিকেট দিয়ে স্বাক্ষরিত হয়। যদি কোনো ফ্ল্যাগ সেট করা না থাকে, তাহলে পাথটি ডিফল্টভাবে build/target/product/security/testkey
  • <name> : APEX-টি PRODUCT_DEFAULT_DEV_CERTIFICATE এর একই ডিরেক্টরিতে থাকা <name> সার্টিফিকেট দ্বারা স্বাক্ষরিত।
  • :<name> : APEX-টি <name> নামের Soong মডিউল দ্বারা সংজ্ঞায়িত সার্টিফিকেট দিয়ে স্বাক্ষরিত। সার্টিফিকেট মডিউলটি নিম্নরূপে সংজ্ঞায়িত করা যেতে পারে।
android_app_certificate {
    name: "my_key_name",
    certificate: "dir/cert",
    // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key)
}

মূল ব্যবস্থাপনা

টেস্ট কী ডেভেলপমেন্ট বিল্ডের জন্য ব্যবহৃত হয়, অন্যদিকে রিলিজ কী পাবলিক বিল্ড সাইন করার জন্য ব্যবহৃত হয়। APEX সাইনিং কী প্রতিস্থাপন- এ যেমন বর্ণনা করা হয়েছে, পাবলিক রিলিজের আগে সমস্ত টেস্ট কী অবশ্যই সংশ্লিষ্ট রিলিজ কী দিয়ে প্রতিস্থাপন করতে হবে। OEM বিল্ড সার্ভারগুলো sign_target_files_apks হোস্ট টুলটি ইন্টিগ্রেট করতে পারে, যা একটি target-files জিপ আর্কাইভের মধ্যে থাকা সমস্ত APEX ফাইলের জন্য ফাইল সিস্টেম ইমেজ এবং সম্পূর্ণ APEX ফাইল উভয়কেই পুনরায় সাইন করে।

নিরাপত্তার জন্য, কী ম্যানেজমেন্ট এবং রিলিজ সাইনিং অপারেশনের ক্ষেত্রে নিম্নলিখিত সর্বোত্তম অনুশীলনগুলি মেনে চলা অত্যন্ত গুরুত্বপূর্ণ:

  • রিলিজ কী-গুলিতে প্রবেশাধিকার সীমিত রাখতে সেগুলিকে একটি সুরক্ষিত পরিবেশে সংরক্ষণ করুন।

  • একটি ACL-কে অবশ্যই রিলিজ সাইনিং অপারেশনের সূচনা নিয়ন্ত্রণ করতে হবে।

  • আর্টিফ্যাক্টগুলো পরীক্ষা ও প্রকাশের জন্য প্রত্যয়িত হওয়ার পরেই কেবল একটি রিলিজ কী দিয়ে স্বাক্ষর করুন।

  • একজন ব্যক্তিকেই রিলিজ স্বাক্ষরের কার্যক্রম শুরু করতে হবে; এই প্রক্রিয়াটি স্বয়ংক্রিয় করবেন না।

  • রিলিজ-কী দ্বারা স্বাক্ষরিত প্রত্নবস্তু অবশ্যই একটি সুরক্ষিত পরিবেশে সংরক্ষণ করতে হবে।

  • রিলিজ-কী দ্বারা স্বাক্ষরিত আর্টিফ্যাক্টগুলিতে প্রবেশাধিকার শুধুমাত্র বৈধ ব্যবসায়িক কারণে সীমাবদ্ধ রাখতে হবে।

  • OEM বিল্ড সার্ভারকে অবশ্যই একটি সাইনিং ডেটাবেসে প্রতিটি সাইনিং অনুরোধের রেকর্ড রাখতে হবে।

একটি APEX ইনস্টল করুন

APEX ইনস্টল করতে ADB ব্যবহার করুন।

adb install apex_file_name
adb reboot

যদি apex_manifest.jsonsupportsRebootlessUpdate true সেট করা থাকে এবং বর্তমানে ইনস্টল করা APEX-টি অব্যবহৃত থাকে (উদাহরণস্বরূপ, এর অন্তর্ভুক্ত কোনো সার্ভিস বন্ধ করে দেওয়া হয়েছে), তাহলে --force-non-staged ফ্ল্যাগ ব্যবহার করে রিবুট ছাড়াই একটি নতুন APEX ইনস্টল করা যেতে পারে।

adb install --force-non-staged apex_file_name

একটি APEX ব্যবহার করুন

রিবুট করার পর, APEX-টি /apex/<apex_name>@<version> ডিরেক্টরিতে মাউন্ট হয়। একই APEX-এর একাধিক সংস্করণ একই সময়ে মাউন্ট করা যেতে পারে। মাউন্ট পাথগুলোর মধ্যে, সর্বশেষ সংস্করণের পাথটি /apex/<apex_name> -এ বাইন্ড-মাউন্ট করা হয়।

ক্লায়েন্টরা APEX থেকে ফাইল পড়তে বা চালাতে বাইন্ড-মাউন্টেড পাথ ব্যবহার করতে পারে।

APEX-গুলো সাধারণত নিম্নোক্তভাবে ব্যবহৃত হয়:

  1. ডিভাইসটি পাঠানোর সময় OEM বা ODM /system/apex অধীনে একটি APEX প্রি-লোড করে দেয়।
  2. APEX-এর ফাইলগুলো /apex/<apex_name>/ পাথের মাধ্যমে অ্যাক্সেস করা হয়।
  3. যখন /data/apex এ APEX-এর একটি আপডেট করা সংস্করণ ইনস্টল করা হয়, তখন রিবুটের পর পাথটি নতুন APEX-কে নির্দেশ করে।

APEX ব্যবহার করে একটি পরিষেবা আপডেট করুন

APEX ব্যবহার করে একটি পরিষেবা আপডেট করতে:

  1. সিস্টেম পার্টিশনে থাকা সার্ভিসটিকে আপডেটেবল হিসেবে চিহ্নিত করুন। সার্ভিস ডেফিনিশনে updatable অপশনটি যোগ করুন।

    /system/etc/init/myservice.rc:
    
    service myservice /system/bin/myservice
        class core
        user system
        ...
        updatable
    
  2. আপডেট করা সার্ভিসটির জন্য একটি নতুন .rc ফাইল তৈরি করুন। বিদ্যমান সার্ভিসটি পুনঃসংজ্ঞায়িত করতে override অপশনটি ব্যবহার করুন।

    /apex/my.apex/etc/init.rc:
    
    service myservice /apex/my.apex/bin/myservice
        class core
        user system
        ...
        override
    

সার্ভিস ডেফিনিশন শুধুমাত্র একটি APEX-এর .rc ফাইলে নির্ধারণ করা যায়। APEX-এ অ্যাকশন ট্রিগার সমর্থিত নয়।

যদি আপডেটেবল হিসেবে চিহ্নিত কোনো সার্ভিস APEX-গুলো অ্যাক্টিভেট হওয়ার আগে চালু হয়, তাহলে APEX-গুলোর অ্যাক্টিভেশন সম্পূর্ণ না হওয়া পর্যন্ত সেটির চালু হওয়া বিলম্বিত হয়।

APEX আপডেট সমর্থন করার জন্য সিস্টেমটি কনফিগার করুন।

APEX ফাইল আপডেট সমর্থন করার জন্য নিম্নলিখিত সিস্টেম প্রপার্টিটি ' true তে সেট করুন।

<device.mk>:

PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true

BoardConfig.mk:
TARGET_FLATTEN_APEX := false

অথবা শুধু

<device.mk>:

$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)

সমতল শীর্ষবিন্দু

পুরানো ডিভাইসগুলোর ক্ষেত্রে, APEX-কে সম্পূর্ণরূপে সমর্থন করার জন্য পুরোনো কার্নেল আপডেট করা কখনও কখনও অসম্ভব বা অবাস্তব হয়ে পড়ে। উদাহরণস্বরূপ, কার্নেলটি হয়তো CONFIG_BLK_DEV_LOOP=Y ছাড়া বিল্ড করা হয়েছিল, যা একটি APEX-এর ভিতরে ফাইল সিস্টেম ইমেজ মাউন্ট করার জন্য অত্যন্ত গুরুত্বপূর্ণ।

ফ্ল্যাটেনড এপেক্স হলো একটি বিশেষভাবে নির্মিত এপেক্স যা লিগ্যাসি কার্নেলযুক্ত ডিভাইসগুলিতে সক্রিয় করা যায়। ফ্ল্যাটেনড এপেক্সের ফাইলগুলি সরাসরি বিল্ট-ইন পার্টিশনের অধীনে একটি ডিরেক্টরিতে ইনস্টল করা হয়। উদাহরণস্বরূপ, ফ্ল্যাটেনড এপেক্স my.apex এর lib/libFoo.so ফাইলটি /system/apex/my.apex/lib/libFoo.so -তে ইনস্টল করা হয়।

একটি ফ্ল্যাটেনড এপেক্স সক্রিয় করার ক্ষেত্রে লুপ ডিভাইসের প্রয়োজন হয় না। সম্পূর্ণ ডিরেক্টরি /system/apex/my.apex সরাসরি /apex/name@ver এ বাইন্ড-মাউন্ট করা হয়।

নেটওয়ার্ক থেকে APEX-এর আপডেটেড ভার্সন ডাউনলোড করে ফ্ল্যাটেন করা APEX-গুলো আপডেট করা যায় না, কারণ ডাউনলোড করা APEX-গুলোকে ফ্ল্যাটেন করা যায় না। ফ্ল্যাটেন করা APEX-গুলো শুধুমাত্র একটি সাধারণ OTA-এর মাধ্যমেই আপডেট করা যায়।

ফ্ল্যাটেনড এপেক্স হলো ডিফল্ট কনফিগারেশন। এর মানে হলো, সব এপেক্স ডিফল্টভাবে ফ্ল্যাটেনড থাকে, যদি না আপনি এপেক্স আপডেট সমর্থন করার জন্য (যেমনটা উপরে ব্যাখ্যা করা হয়েছে) আপনার ডিভাইসকে স্পষ্টভাবে নন-ফ্ল্যাটেনড এপেক্স তৈরি করার জন্য কনফিগার করেন।

একটি ডিভাইসে ফ্ল্যাটেনড এবং নন-ফ্ল্যাটেনড APEX-এর মিশ্রণ সমর্থিত নয়। একটি ডিভাইসের APEX-গুলো হয় সম্পূর্ণ নন-ফ্ল্যাটেনড অথবা সম্পূর্ণ ফ্ল্যাটেনড হতে হবে। মেইনলাইনের মতো প্রোজেক্টের জন্য প্রি-সাইনড APEX প্রি-বিল্ট সরবরাহ করার ক্ষেত্রে এটি বিশেষভাবে গুরুত্বপূর্ণ। যে APEX-গুলো প্রি-সাইনড নয় (অর্থাৎ, সোর্স থেকে বিল্ড করা), সেগুলোও অবশ্যই নন-ফ্ল্যাটেনড হতে হবে এবং যথাযথ কী (key) দিয়ে সাইনড হতে হবে। "একটি APEX দিয়ে একটি সার্ভিস আপডেট করা" অংশে যেমন ব্যাখ্যা করা হয়েছে, ডিভাইসটিকে অবশ্যই updatable_apex.mk থেকে ইনহেরিট করতে হবে।

সংকুচিত এপেক্স

অ্যান্ড্রয়েড ১২ এবং এর পরবর্তী সংস্করণগুলোতে আপডেটযোগ্য এপেক্স প্যাকেজগুলোর স্টোরেজ ব্যবহারের পরিমাণ কমানোর জন্য এপেক্স কম্প্রেশন ফিচার রয়েছে। কোনো এপেক্স আপডেট ইনস্টল করার পর, যদিও এর আগে থেকে ইনস্টল করা সংস্করণটি আর ব্যবহৃত হয় না, তবুও এটি আগের মতোই একই পরিমাণ জায়গা দখল করে রাখে। দখল করা সেই জায়গাটি অব্যবহারযোগ্যই থেকে যায়।

APEX কম্প্রেশন রিড-অনলি পার্টিশনে (যেমন /system পার্টিশন) অত্যন্ত সংকুচিত APEX ফাইল ব্যবহার করে স্টোরেজের উপর এই প্রভাব কমিয়ে আনে। Android 12 এবং এর পরবর্তী সংস্করণগুলো Deflate zip কম্প্রেশন অ্যালগরিদম ব্যবহার করে।

কম্প্রেশন নিম্নলিখিত বিষয়গুলিতে অপ্টিমাইজেশন প্রদান করে না:

  • যে APEX গুলোকে বুট সিকোয়েন্সের একদম শুরুতে মাউন্ট করা প্রয়োজন, সেগুলোকে বুটস্ট্র্যাপ করুন।

  • আপডেট-অযোগ্য APEX-সমূহ। কম্প্রেশন কেবল তখনই উপকারী হয়, যখন /data পার্টিশনে কোনো APEX-এর আপডেটেড সংস্করণ ইনস্টল করা থাকে। আপডেটযোগ্য APEX-সমূহের একটি সম্পূর্ণ তালিকা মডিউলার সিস্টেম কম্পোনেন্টস পৃষ্ঠায় পাওয়া যাবে।

  • ডাইনামিক শেয়ার্ড লাইব্রেরি APEX-গুলোর ক্ষেত্রে, যেহেতু apexd সবসময় এই ধরনের APEX-গুলোর উভয় সংস্করণই (পূর্ব-ইনস্টল করা এবং আপগ্রেড করা) সক্রিয় করে, তাই এগুলোকে কম্প্রেস করলে কোনো বাড়তি সুবিধা হয় না।

সংকুচিত APEX ফাইল ফরম্যাট

এটি একটি সংকুচিত APEX ফাইলের ফরম্যাট।

Diagram shows the format of a compressed APEX file

চিত্র ২. সংকুচিত APEX ফাইল ফরম্যাট

সর্বোচ্চ স্তরে, একটি কম্প্রেসড এপেক্স ফাইল হলো একটি জিপ ফাইল, যার মধ্যে মূল এপেক্স ফাইলটি ডিফলেটেড ফর্মে ৯ কম্প্রেশন লেভেলে থাকে এবং অন্যান্য ফাইলগুলো আনকম্প্রেসড অবস্থায় সংরক্ষিত থাকে।

একটি APEX ফাইল চারটি ফাইল নিয়ে গঠিত:

  • original_apex : কম্প্রেশন লেভেল ৯ সহ ডিফ্লেটেড। এটি মূল, অসংকুচিত APEX ফাইল
  • apex_manifest.pb : শুধুমাত্র সংরক্ষিত
  • AndroidManifest.xml : শুধুমাত্র সংরক্ষিত
  • apex_pubkey : শুধুমাত্র সংরক্ষিত

apex_manifest.pb , AndroidManifest.xml এবং apex_pubkey ফাইলগুলো হলো original_apex এ থাকা তাদের সংশ্লিষ্ট ফাইলগুলোর অনুলিপি।

সংকুচিত APEX তৈরি করুন

system/apex/tools এ অবস্থিত apex_compression_tool.py টুলটি ব্যবহার করে কম্প্রেসড APEX তৈরি করা যায়।

বিল্ড সিস্টেমে এপেক্স কম্প্রেশন সম্পর্কিত বেশ কিছু প্যারামিটার উপলব্ধ রয়েছে।

Android.bp তে একটি APEX ফাইল সংকোচনযোগ্য কিনা তা compressible প্রপার্টি দ্বারা নিয়ন্ত্রিত হয়:

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    compressible: true,
}

PRODUCT_COMPRESSED_APEX প্রোডাক্ট ফ্ল্যাগটি নিয়ন্ত্রণ করে যে, সোর্স থেকে বিল্ড করা একটি সিস্টেম ইমেজে কম্প্রেসড APEX ফাইল থাকতে হবে কি না।

স্থানীয় পরীক্ষণের জন্য আপনি OVERRIDE_PRODUCT_COMPRESSED_APEX= এর মান true সেট করে APEX ফাইলগুলোকে বিল্ডে কম্প্রেস করতে বাধ্য করতে পারেন।

বিল্ড সিস্টেম দ্বারা তৈরি কম্প্রেসড APEX ফাইলগুলোর .capex এক্সটেনশন থাকে। এই এক্সটেনশনটি একটি APEX ফাইলের কম্প্রেসড এবং আনকম্প্রেসড ভার্সনের মধ্যে পার্থক্য করা সহজ করে তোলে।

সমর্থিত কম্প্রেশন অ্যালগরিদম

অ্যান্ড্রয়েড ১২ শুধুমাত্র ডিফ্লেট জিপ কম্প্রেশন সমর্থন করে।

বুট করার সময় একটি সংকুচিত APEX ফাইল সক্রিয় করুন

একটি কম্প্রেসড APEX অ্যাক্টিভেট করার আগে, এর ভেতরের original_apex ফাইলটিকে /data/apex/decompressed ডিরেক্টরিতে ডিকম্প্রেস করা হয়। ফলস্বরূপ ডিকম্প্রেসড APEX ফাইলটি /data/apex/active ডিরেক্টরির সাথে হার্ড-লিঙ্ক করা থাকে।

উপরে বর্ণিত প্রক্রিয়াটির দৃষ্টান্তস্বরূপ নিম্নলিখিত উদাহরণটি বিবেচনা করুন।

/system/apex/com.android.foo.capex ভার্সন কোড ৩৭ সহ সক্রিয় করা হচ্ছে এমন একটি কম্প্রেসড APEX হিসেবে বিবেচনা করুন।

  1. /system/apex/com.android.foo.capex ভিতরে থাকা original_apex ফাইলটি /data/apex/decompressed/com.android.foo@37.apex এ ডিকম্প্রেস করা হয়েছে।
  2. এটির একটি সঠিক SELinux লেবেল আছে কিনা তা যাচাই করার জন্য restorecon /data/apex/decompressed/com.android.foo@37.apex চালানো হয়।
  3. /data/apex/decompressed/com.android.foo@37.apex এর বৈধতা নিশ্চিত করার জন্য যাচাইকরণ পরীক্ষা করা হয়: apexd /data/apex/decompressed/com.android.foo@37.apex এ থাকা পাবলিক কী-টি /system/apex/com.android.foo.capex এ থাকা কী-টির সমান কি না, তা যাচাই করার জন্য পরীক্ষা করে।
  4. /data/apex/decompressed/com.android.foo@37.apex ফাইলটি /data/apex/active/com.android.foo@37.apex ডিরেক্টরির সাথে হার্ড-লিঙ্ক করা আছে।
  5. অসংকুচিত APEX ফাইলগুলির নিয়মিত অ্যাক্টিভেশন লজিক /data/apex/active/com.android.foo@37.apex -এ সম্পাদিত হয়।

OTA-এর সাথে মিথস্ক্রিয়া

কম্প্রেসড APEX ফাইলগুলো OTA ডেলিভারি এবং অ্যাপ্লিকেশনের উপর প্রভাব ফেলে। যেহেতু একটি OTA আপডেটে ডিভাইসে সক্রিয় থাকা ভার্সনের চেয়ে উচ্চতর ভার্সনের একটি কম্প্রেসড APEX ফাইল থাকতে পারে, তাই OTA আপডেটটি প্রয়োগ করার জন্য ডিভাইসটি রিবুট করার আগে একটি নির্দিষ্ট পরিমাণ খালি জায়গা সংরক্ষণ করতে হয়।

OTA সিস্টেমকে সমর্থন করার জন্য, apexd এই দুটি বাইন্ডার API উন্মুক্ত করে:

  • calculateSizeForCompressedApex - একটি OTA প্যাকেজে থাকা APEX ফাইলগুলো ডিকম্প্রেস করার জন্য প্রয়োজনীয় সাইজ গণনা করে। কোনো OTA ডাউনলোড হওয়ার আগে ডিভাইসে পর্যাপ্ত জায়গা আছে কিনা, তা যাচাই করতে এটি ব্যবহার করা যেতে পারে।
  • reserveSpaceForCompressedApex - OTA প্যাকেজের ভিতরে থাকা সংকুচিত APEX ফাইলগুলিকে ডিকম্প্রেস করার জন্য apexd এর ভবিষ্যৎ ব্যবহারের জন্য ডিস্কে জায়গা সংরক্ষণ করে।

A/B OTA আপডেটের ক্ষেত্রে, apexd পোস্টইনস্টল OTA রুটিনের অংশ হিসেবে ব্যাকগ্রাউন্ডে ডিকম্প্রেশন করার চেষ্টা করে। যদি ডিকম্প্রেশন ব্যর্থ হয়, তবে apexd সেই বুটের সময় ডিকম্প্রেশনটি সম্পন্ন করে, যেটি OTA আপডেটটি প্রয়োগ করে।

APEX বিকাশের সময় বিবেচিত বিকল্পগুলি

APEX ফাইল ফরম্যাট ডিজাইন করার সময় AOSP যে বিকল্পগুলো বিবেচনা করেছিল, এবং কেন সেগুলো অন্তর্ভুক্ত বা বাদ দেওয়া হয়েছিল, তা এখানে তুলে ধরা হলো।

নিয়মিত প্যাকেজ ব্যবস্থাপনা সিস্টেম

লিনাক্স ডিস্ট্রিবিউশনগুলোতে dpkg এবং rpm মতো প্যাকেজ ম্যানেজমেন্ট সিস্টেম রয়েছে, যেগুলো শক্তিশালী, উন্নত এবং নির্ভরযোগ্য। তবে, APEX-এর জন্য এগুলো গ্রহণ করা হয়নি, কারণ ইনস্টলেশনের পরে এগুলো প্যাকেজগুলোকে সুরক্ষিত রাখতে পারে না। যাচাইকরণ শুধুমাত্র প্যাকেজ ইনস্টল করার সময়ই করা হয়। আক্রমণকারীরা অলক্ষ্যে ইনস্টল করা প্যাকেজগুলোর অখণ্ডতা নষ্ট করে ফেলতে পারে। এটি অ্যান্ড্রয়েডের জন্য একটি রিগ্রেশন, যেখানে সমস্ত সিস্টেম কম্পোনেন্ট রিড-অনলি ফাইল সিস্টেমে সংরক্ষিত থাকত, যার অখণ্ডতা প্রতিটি I/O-এর জন্য dm-verity দ্বারা সুরক্ষিত। সিস্টেম কম্পোনেন্টগুলোতে যেকোনো ধরনের হস্তক্ষেপ হয় নিষিদ্ধ করতে হবে, অথবা তা শনাক্তযোগ্য হতে হবে, যাতে ডিভাইসটি ক্ষতিগ্রস্ত হলে বুট করতে অস্বীকার করতে পারে।

অখণ্ডতার জন্য ডিএম-ক্রিপ্ট

একটি APEX কন্টেইনারের ফাইলগুলো বিল্ট-ইন পার্টিশন (যেমন, /system পার্টিশন) থেকে আসে, যা dm-verity দ্বারা সুরক্ষিত থাকে। এই পার্টিশনগুলো মাউন্ট করার পরেও ফাইলগুলোতে কোনো ধরনের পরিবর্তন করা নিষিদ্ধ। ফাইলগুলোতে একই স্তরের নিরাপত্তা প্রদানের জন্য, একটি APEX-এর সমস্ত ফাইল একটি ফাইল সিস্টেম ইমেজে সংরক্ষণ করা হয়, যা একটি হ্যাশ ট্রি এবং একটি vbmeta ডেসক্রিপ্টরের সাথে যুক্ত থাকে। dm-verity ছাড়া, /data পার্টিশনে থাকা একটি APEX যাচাই এবং ইনস্টল করার পরে করা অনাকাঙ্ক্ষিত পরিবর্তনের জন্য ঝুঁকিপূর্ণ হয়ে পড়ে।

প্রকৃতপক্ষে, /data পার্টিশনটিও dm-crypt-এর মতো এনক্রিপশন স্তর দ্বারা সুরক্ষিত থাকে। যদিও এটি টেম্পারিংয়ের বিরুদ্ধে কিছুটা সুরক্ষা প্রদান করে, এর প্রাথমিক উদ্দেশ্য হলো গোপনীয়তা, অখণ্ডতা নয়। যখন কোনো আক্রমণকারী /data পার্টিশনে প্রবেশাধিকার পায়, তখন আর কোনো অতিরিক্ত সুরক্ষা থাকতে পারে না, এবং এটিও প্রতিটি সিস্টেম কম্পোনেন্ট /system পার্টিশনে থাকার তুলনায় একটি পশ্চাদপসরণ। একটি APEX ফাইলের ভেতরের হ্যাশ ট্রি, dm-verity-এর সাথে মিলে একই স্তরের কন্টেন্ট সুরক্ষা প্রদান করে।

/system থেকে /apex-এ পাথ পুনঃনির্দেশ করুন

APEX-এ প্যাকেজ করা সিস্টেম কম্পোনেন্ট ফাইলগুলো এখন /apex/<name>/lib/libfoo.so এর মতো নতুন পাথের মাধ্যমে অ্যাক্সেস করা যায়। যখন ফাইলগুলো /system পার্টিশনের অংশ ছিল, তখন সেগুলো /system/lib/libfoo.so এর মতো পাথের মাধ্যমে অ্যাক্সেস করা যেত। একটি APEX ফাইলের ক্লায়েন্টকে (অন্যান্য APEX ফাইল বা প্ল্যাটফর্ম) অবশ্যই নতুন পাথগুলো ব্যবহার করতে হবে। এই পাথ পরিবর্তনের ফলে আপনার বিদ্যমান কোড আপডেট করার প্রয়োজন হতে পারে।

যদিও পাথ পরিবর্তন এড়ানোর একটি উপায় হলো /system পার্টিশনের উপর একটি APEX ফাইলের বিষয়বস্তু ওভারলে করা, অ্যান্ড্রয়েড টিম /system পার্টিশনের উপর ফাইল ওভারলে না করার সিদ্ধান্ত নিয়েছে। এর কারণ হলো, ওভারলে করা ফাইলের সংখ্যা (সম্ভবত একটির পর একটি সাজানো) বাড়লে এটি পারফরম্যান্সের উপর প্রভাব ফেলতে পারে।

আরেকটি বিকল্প ছিল open , stat , এবং readlink মতো ফাইল-অ্যাক্সেস ফাংশনগুলোকে হাইজ্যাক করা, যাতে /system দিয়ে শুরু হওয়া পাথগুলো /apex অধীনে তাদের সংশ্লিষ্ট পাথে রিডাইরেক্ট হয়ে যায়। অ্যান্ড্রয়েড টিম এই বিকল্পটি বাতিল করে দিয়েছে, কারণ পাথ গ্রহণকারী সমস্ত ফাংশন পরিবর্তন করা সম্ভব নয়। উদাহরণস্বরূপ, কিছু অ্যাপ Bionic-কে স্ট্যাটিক্যালি লিঙ্ক করে, যা এই ফাংশনগুলো ইমপ্লিমেন্ট করে। এই ধরনের ক্ষেত্রে, সেই অ্যাপগুলো রিডাইরেক্ট হয় না।