বিক্রেতা APEX

আপনি নিম্ন-স্তরের অ্যান্ড্রয়েড ওএস মডিউলগুলো প্যাকেজ ও ইনস্টল করার জন্য APEX ফাইল ফরম্যাট ব্যবহার করতে পারেন। এটি নেটিভ সার্ভিস ও লাইব্রেরি, HAL ইমপ্লিমেন্টেশন, ফার্মওয়্যার, কনফিগারেশন ফাইল ইত্যাদির মতো কম্পোনেন্টগুলোকে স্বাধীনভাবে বিল্ড ও ইনস্টল করার সুযোগ দেয়।

ভেন্ডর APEX-গুলো বিল্ড সিস্টেম দ্বারা স্বয়ংক্রিয়ভাবে /vendor পার্টিশনে ইনস্টল করা হয় এবং অন্যান্য পার্টিশনের APEX-গুলোর মতোই রানটাইমে apexd দ্বারা সক্রিয় করা হয়।

ব্যবহারের ক্ষেত্র

বিক্রেতার চিত্রের মডুলারাইজেশন

APEX-গুলি ভেন্ডর ইমেজে ফিচার ইমপ্লিমেন্টেশনগুলির স্বাভাবিক বান্ডলিং এবং মডুলারাইজেশনকে সহজতর করে।

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

উদাহরণস্বরূপ, একজন OEM তাদের ডিভাইসটি AOSP ওয়াইফাই ইমপ্লিমেন্টেশন APEX, SoC ব্লুটুথ ইমপ্লিমেন্টেশন APEX, এবং একটি কাস্টম OEM টেলিফোনি ইমপ্লিমেন্টেশন APEX দিয়ে তৈরি করতে পারেন।

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

ডেভেলপার পুনরাবৃত্তি

ভেন্ডর এপেক্স (Vendor APEX) ডেভেলপারদের ভেন্ডর মডিউল ডেভেলপ করার সময় দ্রুত পুনরাবৃত্তি করতে সাহায্য করে, কারণ এটি ওয়াইফাই এইচএএল (wifi HAL)-এর মতো একটি সম্পূর্ণ ফিচার ইমপ্লিমেন্টেশনকে একটি ভেন্ডর এপেক্স-এর মধ্যে বান্ডল করে রাখে। এর ফলে ডেভেলপাররা পুরো ভেন্ডর ইমেজটি রি-বিল্ড করার পরিবর্তে, পরিবর্তনগুলো পরীক্ষা করার জন্য ভেন্ডর এপেক্সটি বিল্ড করে আলাদাভাবে পুশ করতে পারেন।

এটি সেইসব ডেভেলপারদের জন্য কাজের পুনরাবৃত্তি চক্রকে সহজ ও দ্রুততর করে, যারা প্রধানত একটি ফিচার ক্ষেত্রে কাজ করেন এবং শুধু সেই ফিচার ক্ষেত্রটিতেই পুনরাবৃত্তি করতে চান।

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

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

কর্মপ্রবাহের উদাহরণ:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

উদাহরণ

মৌলিক বিষয়

ডিভাইসের প্রয়োজনীয়তা, ফাইল ফরম্যাটের বিবরণ এবং ইনস্টলেশনের ধাপসহ সাধারণ APEX তথ্যের জন্য মূল APEX ফাইল ফরম্যাট পৃষ্ঠাটি দেখুন।

Android.bp তে, vendor: true প্রপার্টি সেট করলে একটি APEX মডিউল ভেন্ডর APEX-এ পরিণত হয়।

apex {
  ..
  vendor: true,
  ..
}

বাইনারি এবং শেয়ার করা লাইব্রেরি

একটি APEX পেলোডের মধ্যে ট্রানজিটিভ ডিপেন্ডেন্সিগুলো অন্তর্ভুক্ত থাকে, যদি না সেগুলোর স্টেবল ইন্টারফেস থাকে।

ভেন্ডর APEX ডিপেন্ডেন্সিগুলোর জন্য স্থিতিশীল নেটিভ ইন্টারফেসের মধ্যে stubs cc_library এবং LLNDK লাইব্রেরি অন্তর্ভুক্ত। এই ডিপেন্ডেন্সিগুলোকে প্যাকেজিং থেকে বাদ দেওয়া হয় এবং APEX ম্যানিফেস্টে নথিভুক্ত করা হয়। ম্যানিফেস্টটি linkerconfig দ্বারা প্রক্রিয়াজাত করা হয়, যাতে এক্সটার্নাল নেটিভ ডিপেন্ডেন্সিগুলো রানটাইমে উপলব্ধ থাকে।

নিম্নলিখিত কোড অংশে, APEX-এ বাইনারি ( my_service ) এবং এর অস্থায়ী নির্ভরতাগুলো ( *.so ফাইল) উভয়ই রয়েছে।

apex {
  ..
  vendor: true,
  binaries: ["my_service"],
  ..
}

নিম্নলিখিত কোড অংশে, APEX-টিতে my_standalone_lib নামক শেয়ার্ড লাইব্রেরি এবং এর যেকোনো অস্থিতিশীল নির্ভরতা (যেমনটি উপরে বর্ণনা করা হয়েছে) অন্তর্ভুক্ত রয়েছে।

apex {
  ..
  vendor: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

APEX কে আরও ছোট করুন

APEX আকারে বড় হতে পারে কারণ এটি অস্থিতিশীল ডিপেন্ডেন্সিগুলো বান্ডল করে। আমরা স্ট্যাটিক লিঙ্কিং ব্যবহার করার পরামর্শ দিই। libc++.so এবং libbase.so এর মতো সাধারণ লাইব্রেরিগুলোকে HAL বাইনারিগুলোর সাথে স্ট্যাটিক্যালি লিঙ্ক করা যেতে পারে। একটি স্থিতিশীল ইন্টারফেস প্রদানের জন্য ডিপেন্ডেন্সি তৈরি করা আরেকটি বিকল্প হতে পারে। এই ডিপেন্ডেন্সিটি APEX-এর সাথে বান্ডল করা হবে না।

HAL বাস্তবায়ন

একটি HAL ইমপ্লিমেন্টেশন সংজ্ঞায়িত করতে, নিম্নলিখিত উদাহরণগুলির অনুরূপভাবে একটি ভেন্ডর APEX-এর ভিতরে সংশ্লিষ্ট বাইনারি এবং লাইব্রেরিগুলি সরবরাহ করুন:

HAL বাস্তবায়নকে সম্পূর্ণরূপে অন্তর্ভুক্ত করার জন্য, APEX-কে যেকোনো প্রাসঙ্গিক VINTF ফ্র্যাগমেন্ট এবং ইনিট স্ক্রিপ্টও নির্দিষ্ট করতে হবে।

VINTF খণ্ডগুলি

যখন ফ্র্যাগমেন্টগুলি কোনো ভেন্ডর APEX-এর etc/vintf ফাইলে অবস্থিত থাকে, তখন সেই APEX থেকে VINTF ফ্র্যাগমেন্টগুলি পরিবেশন করা যায়।

APEX-এ VINTF ফ্র্যাগমেন্টগুলো এম্বেড করতে prebuilts প্রপার্টি ব্যবহার করুন।

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

এপিআই অনুসন্ধান করুন

যখন APEX-এ VINTF ফ্র্যাগমেন্ট যোগ করা হয়, তখন HAL ইন্টারফেস এবং APEX নামের ম্যাপিং পেতে libbinder_ndk API ব্যবহার করুন।

  • AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default") : যদি HAL ইনস্ট্যান্সটি APEX-এ সংজ্ঞায়িত থাকে তবে true
  • AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...) : HAL ইনস্ট্যান্সকে সংজ্ঞায়িত করে এমন APEX নামটি গ্রহণ করে।
  • AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...) : একটি পাসথ্রু HAL খোলার জন্য এটি ব্যবহার করুন।

ইনিট স্ক্রিপ্ট

APEX-এ দুইভাবে ইনিট স্ক্রিপ্ট অন্তর্ভুক্ত করা যায়: (ক) APEX পেলোডের মধ্যে একটি পূর্ব-নির্মিত টেক্সট ফাইল হিসেবে, অথবা (খ) /vendor/etc তে একটি সাধারণ ইনিট স্ক্রিপ্ট হিসেবে। আপনি একই APEX-এর জন্য উভয়ই সেট করতে পারেন।

APEX-এ ইনিট স্ক্রিপ্ট:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

ভেন্ডর APEX-এর Init স্ক্রিপ্টগুলিতে service ডেফিনিশন এবং on <property or event> ডিরেক্টিভ থাকতে পারে।

নিশ্চিত করুন যে একটি service ডেফিনিশন একই APEX-এর একটি বাইনারিকে নির্দেশ করে। উদাহরণস্বরূপ, com.android.foo APEX-এ foo-service নামের একটি সার্ভিস সংজ্ঞায়িত করা থাকতে পারে।

on foo-service /apex/com.android.foo/bin/foo
  ...

on ' ডিরেক্টিভ ব্যবহার করার সময় সতর্ক থাকুন। যেহেতু APEX-এর init স্ক্রিপ্টগুলো APEX সক্রিয় হওয়ার পরে পার্স এবং এক্সিকিউট করা হয়, তাই কিছু ইভেন্ট বা প্রপার্টি ব্যবহার করা যায় না। যত তাড়াতাড়ি সম্ভব অ্যাকশনগুলো ফায়ার করতে apex.all.ready=true ব্যবহার করুন। বুটস্ট্র্যাপ APEX-গুলো on init ব্যবহার করতে পারে, কিন্তু on early-init ব্যবহার করতে পারে না।

ফার্মওয়্যার

উদাহরণ:

নিম্নলিখিতভাবে prebuilt_firmware মডিউল টাইপ ব্যবহার করে একটি ভেন্ডর APEX-এ ফার্মওয়্যার এম্বেড করুন।

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

prebuilt_firmware মডিউলগুলো APEX-এর <apex name>/etc/firmware ডিরেক্টরিতে ইনস্টল করা হয়। ueventd ফার্মওয়্যার মডিউলগুলো খুঁজে বের করার জন্য /apex/*/etc/firmware ডিরেক্টরিগুলো স্ক্যান করে।

APEX-এর file_contexts যেকোনো ফার্মওয়্যার পেলোড এন্ট্রিকে সঠিকভাবে লেবেল করা উচিত, যাতে রানটাইমে ueventd এই ফাইলগুলো অ্যাক্সেস করতে পারে; সাধারণত, vendor_file লেবেলটিই যথেষ্ট। উদাহরণস্বরূপ:

(/.*)? u:object_r:vendor_file:s0

কার্নেল মডিউল

নিম্নলিখিতভাবে ভেন্ডর APEX-এ কার্নেল মডিউলগুলিকে প্রি-বিল্ট মডিউল হিসাবে এম্বেড করুন।

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

APEX-এর file_contexts যেকোনো কার্নেল মডিউল পেলোড এন্ট্রিকে সঠিকভাবে লেবেল করা উচিত। উদাহরণস্বরূপ:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

কার্নেল মডিউলগুলো অবশ্যই সুস্পষ্টভাবে ইনস্টল করতে হবে। ভেন্ডর পার্টিশনে থাকা নিম্নলিখিত উদাহরণ init স্ক্রিপ্টটি insmod মাধ্যমে ইনস্টলেশন দেখাচ্ছে:

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

রানটাইম রিসোর্স ওভারলে

উদাহরণ:

rros প্রপার্টি ব্যবহার করে ভেন্ডর APEX-এ রানটাইম রিসোর্স ওভারলে এম্বেড করুন।

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

অন্যান্য কনফিগারেশন ফাইল

ভেন্ডর APEX-গুলো ভেন্ডর পার্টিশনে সাধারণত পাওয়া যায় এমন বিভিন্ন কনফিগারেশন ফাইলকে ভেন্ডর APEX-এর ভেতরে প্রি-বিল্ট হিসেবে সাপোর্ট করে এবং আরও ফাইল যুক্ত করা হচ্ছে।

উদাহরণ:

বুটস্ট্র্যাপ ভেন্ডর এপেক্স

কিছু HAL সার্ভিস, যেমন keymint APEX অ্যাক্টিভেট হওয়ার আগেই উপলব্ধ থাকা উচিত। এই ধরনের HAL সার্ভিসগুলো সাধারণত তাদের সার্ভিস ডেফিনিশনে init স্ক্রিপ্টে early_hal সেট করে। আরেকটি উদাহরণ হলো animation ক্লাস, যা সাধারণত post-fs-data ইভেন্টের আগে চালু হয়। যখন এই ধরনের কোনো আর্লি HAL সার্ভিস ভেন্ডর APEX-এ প্যাকেজ করা থাকে, তখন এর APEX Manifest-এ "vendorBootstrap": true সেট করুন, যাতে এটি আগে অ্যাক্টিভেট হতে পারে। মনে রাখবেন যে, বুটস্ট্র্যাপ APEX শুধুমাত্র /vendor/apex মতো প্রি-বিল্ট লোকেশন থেকে অ্যাক্টিভেট করা যায়, /data/apex থেকে নয়।

সিস্টেমের বৈশিষ্ট্য

ভেন্ডর APEX-গুলিকে সমর্থন করার জন্য ফ্রেমওয়ার্কটি এই সিস্টেম প্রোপার্টিগুলি পড়ে থাকে:

  • input_device.config_file.apex=<apex name> - এটি সেট করা থাকলে, APEX-এর /etc/usr ডিরেক্টরি থেকে ইনপুট কনফিগারেশন ফাইলগুলো ( *.idc , *.kl , এবং *.kcm ) খোঁজা হয়।
  • ro.vulkan.apex=<apex name> - এটি সেট করা থাকলে, APEX থেকে Vulkan ড্রাইভার লোড হয়। যেহেতু Vulkan ড্রাইভারটি পুরোনো HAL-গুলোতে ব্যবহৃত হয়, তাই APEX-টিকে Bootstrap APEX বানান এবং ওই লিঙ্কার নেমস্পেসটিকে দৃশ্যমান করার জন্য কনফিগার করুন।

init স্ক্রিপ্টে setprop কমান্ড ব্যবহার করে সিস্টেম প্রোপার্টিগুলো সেট করুন।

অতিরিক্ত বৈশিষ্ট্য

বুটআপের সময় APEX নির্বাচন

উদাহরণ:

ভেন্ডর APEX-গুলো বুট করার সময় ঐচ্ছিকভাবে সক্রিয় করা যেতে পারে। যদি আপনি সিস্টেম প্রপার্টি ro.vendor.apex.<apex name> ব্যবহার করে একটি ফাইলের নাম নির্দিষ্ট করেন, তবে শুধুমাত্র সেই ফাইলের নামের সাথে মিলে যাওয়া APEX-টিই নির্দিষ্ট <apex name> এর জন্য সক্রিয় করা হবে। যদি এই সিস্টেম প্রপার্টিটি ' none সেট করা থাকে, তাহলে <apex name> সহ APEX-টি উপেক্ষা করা হয় (সক্রিয় করা হয় না)। আপনি এই বৈশিষ্ট্যটি ব্যবহার করে একই নামের একটি APEX-এর একাধিক কপি ইনস্টল করতে পারেন। যদি একই APEX-এর একাধিক সংস্করণ থাকে, তবে সেগুলোর একই কী (key) ব্যবহার করা উচিত।

ব্যবহারের উদাহরণ:

  • ওয়াইফাই HAL ভেন্ডর APEX-এর ৩টি ভার্সন ইনস্টল করুন: QA টিমগুলো একটি ভার্সন ব্যবহার করে ম্যানুয়াল বা অটোমেটেড টেস্টিং চালাতে পারবে, তারপর অন্য ভার্সনে রিবুট করে টেস্টগুলো পুনরায় চালাতে পারবে এবং সবশেষে চূড়ান্ত ফলাফল তুলনা করতে পারবে।
  • ক্যামেরা HAL ভেন্ডর APEX-এর দুটি সংস্করণ ইনস্টল করুন: বর্তমান এবং পরীক্ষামূলক Dogfooders-রা কোনো অতিরিক্ত ফাইল ডাউনলোড ও ইনস্টল না করেই পরীক্ষামূলক সংস্করণটি ব্যবহার করতে পারেন, ফলে তারা সহজেই আগের সংস্করণে ফিরে যেতে পারবেন।

বুটআপের সময়, সঠিক APEX সংস্করণটি সক্রিয় করার জন্য apexd একটি নির্দিষ্ট বিন্যাস অনুসরণ করে sysprops খুঁজে থাকে।

প্রপার্টি কী-এর জন্য প্রত্যাশিত ফরম্যাটগুলো হলো:

  • বুটকনফিগ
    • BoardConfig.mk এ ডিফল্ট মান সেট করতে ব্যবহৃত হয়।
    • androidboot.vendor.apex.<apex name>
  • স্থায়ী সিস্টেম প্রপ
    • ইতিমধ্যে বুট করা ডিভাইসে সেট করা ডিফল্ট মান পরিবর্তন করতে ব্যবহৃত হয়।
    • যদি bootconfig-এর মান উপস্থিত থাকে, তবে তা বাতিল করে দেয়।
    • persist.vendor.apex.<apex name>

প্রপার্টির মানটি হবে সেই APEX-এর ফাইলের নাম যা সক্রিয় করতে হবে, অথবা APEX-টি নিষ্ক্রিয় করার জন্য none

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

BoardConfig.mk এ bootconfig ব্যবহার করে ডিফল্ট সংস্করণটিও কনফিগার করতে হবে:

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

ডিভাইসটি বুট হওয়ার পরে, স্থায়ী সিস্টেম প্রপার্টি (persistent sysprop) সেট করে সক্রিয় সংস্করণটি পরিবর্তন করুন:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

যদি ডিভাইসটি ফ্ল্যাশ করার পরে বুটকনফিগ আপডেট করা সমর্থন করে (যেমন fastboot oem কমান্ডের মাধ্যমে), তাহলে একাধিক ইনস্টল করা APEX-এর জন্য বুটকনফিগ প্রপার্টি পরিবর্তন করলে বুটআপের সময় সক্রিয় হওয়া সংস্করণটিও পরিবর্তিত হয়।

Cuttlefish- ভিত্তিক ভার্চুয়াল রেফারেন্স ডিভাইসগুলোর ক্ষেত্রে, লঞ্চ করার সময় সরাসরি bootconfig প্রপার্টি সেট করতে আপনি --extra_bootconfig_args কমান্ডটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";