নিম্ন-লেভেলের Android OS মডিউল প্যাকেজ করতে ও ইনস্টল করতে আপনি APEX ফাইল ফর্ম্যাট ব্যবহার করতে পারবেন। এটি নেটিভ পরিষেবা ও লাইব্রেরি, HAL ইমপ্লিমেন্টেশন, ফার্মওয়্যার, কনফিগার ফাইল ইত্যাদির মতো কম্পোনেন্টকে স্বাধীনভাবে তৈরি ও ইনস্টল করতে দেয়।
বিল্ড সিস্টেম অটোমেটিক /vendor
পার্টিশনে ভেন্ডর APEX ইনস্টল করে এবং apexd রানটাইমে তা অ্যাক্টিভেট করে, ঠিক অন্যান্য
পার্টিশনের APEX-এর মতো।
উদাহরণ
ভেন্ডর ছবির মডিউলারাইজেশন
APEX, ভেন্ডর ইমেজে ফিচার ইমপ্লিমেন্টেশনের স্বাভাবিক বান্ডেলিং ও মডুলারাইজেশন সহজ করে।
ভেন্ডর ইমেজ যখন আলাদাভাবে তৈরি করা ভেন্ডর APEX-এর কম্বিনেশন হিসেবে তৈরি করা হয়, তখন ডিভাইস প্রস্তুতকারকরা সহজেই তাদের ডিভাইসে কাঙ্ক্ষিত নির্দিষ্ট ভেন্ডর ইমপ্লিমেন্টেশন বেছে নিতে পারেন। প্রদান করা কোনও APEX যদি প্রস্তুতকারকের প্রয়োজন অনুসারে না হয়, অথবা তাদের কাছে সম্পূর্ণ নতুন কাস্টম হার্ডওয়্যার থাকে, তাহলে প্রস্তুতকারক একটি নতুন ভেন্ডর APEX তৈরি করতে পারেন।
যেমন, কোনও OEM তার ডিভাইসকে AOSP ওয়াই-ফাই ইমপ্লিমেন্টেশন APEX, SoC ব্লুটুথ ইমপ্লিমেন্টেশন APEX এবং কাস্টম OEM টেলিফোনি ইমপ্লিমেন্টেশন APEX দিয়ে কম্পোজ করার বিকল্প বেছে নিতে পারে।
ভেন্ডর APEX না থাকলে, ভেন্ডর কম্পোনেন্টগুলির মধ্যে এত বেশি নির্ভরতা সহ কোনও প্রয়োগের জন্য সতর্কতার সাথে কোঅর্ডিনেশন ও ট্র্যাকিং প্রয়োজন। ক্রস-ফিচার কমিউনিকেশনের যেকোনও পয়েন্টে APEX-এ স্পষ্টভাবে সংজ্ঞায়িত ইন্টারফেসের সাথে সমস্ত কম্পোনেন্ট (কনফিগারেশন ফাইল ও অতিরিক্ত লাইব্রেরি সহ) র্যাপ করার মাধ্যমে, বিভিন্ন কম্পোনেন্ট ইন্টারচেঞ্জেবল হয়ে যায়।
ডেভেলপার ইটারেশন
ভেন্ডর APEX, ভেন্ডর মডিউল ডেভেলপ করার সময় ডেভেলপারদের দ্রুত ইটারেট করতে সাহায্য করে। এটি ভেন্ডর APEX-এর মধ্যে ওয়াই-ফাই HAL-এর মতো সম্পূর্ণ ফিচার ইমপ্লিমেন্টেশনকে বান্ডেল করে। এর পরে, ডেভেলপাররা সম্পূর্ণ ভেন্ডর ইমেজ আবার তৈরি না করে, পরিবর্তনগুলি পরীক্ষা করার জন্য ভেন্ডর APEX তৈরি করতে এবং আলাদা আলাদাভাবে পুশ করতে পারবেন।
এটি সেইসব ডেভেলপারদের জন্য ডেভেলপার ইটারেশন চক্রকে সহজ এবং দ্রুত করে তোলে যারা প্রাথমিকভাবে একটি ফিচার এরিয়াতে কাজ করেন এবং শুধুমাত্র সেই ফিচার এরিয়াতে ইটারেট করতে চান।
APEX-এ ফিচার এরিয়াকে স্বাভাবিকভাবে বান্ডেল করার ফলে সেই ফিচার এরিয়ার জন্য পরিবর্তন তৈরি, পুশ ও পরীক্ষা করার প্রসেসও সহজ হয়ে যায়। যেমন, কোনও 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 পেলোডের মধ্যে অন্তর্ভুক্ত করা হয়, যদি না সেগুলির ইন্টারফেস স্থিতিশীল হয়।
ভেন্ডর APEX নির্ভরতার জন্য স্থিতিশীল নেটিভ ইন্টারফেসে cc_library with
stubs এবং 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 ফ্র্যাগমেন্ট
VINTF ফ্র্যাগমেন্ট, ভেন্ডর APEX থেকে পরিবেশন করা যেতে পারে, যদি ফ্র্যাগমেন্টগুলি APEX-এর
etc/vintf-এ থাকে।
APEX-এ VINTF ফ্র্যাগমেন্ট এম্বেড করতে prebuilts প্রপার্টি ব্যবহার করুন।
apex {
..
vendor: true,
prebuilts: ["fragment.xml"],
..
}
prebuilt_etc {
name: "fragment.xml",
src: "fragment.xml",
sub_dir: "vintf",
}
কোয়েরি API
APEX-এ VINTF ফ্র্যাগমেন্ট যোগ করা হলে, HAL ইন্টারফেস ও APEX নামের
ম্যাপিং পেতে libbinder_ndk API ব্যবহার করুন।
AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default"):trueHAL ইনস্ট্যান্স APEX-এ সংজ্ঞায়িত করা থাকলে।AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...): HAL ইনস্ট্যান্সকে সংজ্ঞায়িত করে এমন APEX নাম পায়।AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...): পাসথ্রু HAL খুলতে এটি ব্যবহার করুন।
ইনিট স্ক্রিপ্ট
APEX-এ দুটি উপায়ে init স্ক্রিপ্ট অন্তর্ভুক্ত করা যেতে পারে: (A) APEX পেলোডের মধ্যে আগে থেকে তৈরি করা টেক্সট ফাইল, অথবা (B) /vendor/etc-এ একটি সাধারণ init স্ক্রিপ্ট। আপনি একই APEX-এর জন্য
দুটিই সেট করতে পারবেন।
APEX-এ ইনিট স্ক্রিপ্ট:
prebuilt_etc {
name: "myinit.rc",
src: "myinit.rc"
}
apex {
..
vendor: true,
prebuilts: ["myinit.rc"],
..
}
ভেন্ডর APEX-এ থাকা ইনিট স্ক্রিপ্টে 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 ব্যবহার করুন।
Bootstrap 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-এর মধ্যে প্রি-বিল্ট হিসেবে পাওয়া যায় এবং আরও অনেক কিছু যোগ করা হচ্ছে।
উদাহরণ:
- ফিচার ঘোষণা XML
- সেন্সর ফিচার XML-কে সেন্সর HAL ভেন্ডর APEX-এ প্রি-বিল্ট হিসেবে ব্যবহার করা হয়
- ইনপুট কনফিগারেশন ফাইল
- টাচস্ক্রিন কনফিগারেশন হিসেবে কনফিগার-অনলি ভেন্ডর APEX-এ প্রি-বিল্ট
বুটস্ট্র্যাপ ভেন্ডর APEX
APEX অ্যাক্টিভেট করার আগে keymint-এর মতো কিছু HAL পরিষেবা উপলভ্য থাকতে হবে।
সেইসব HAL সাধারণত early_hal-কে তাদের পরিষেবা সংক্রান্ত সংজ্ঞায়
ইনিট স্ক্রিপ্টে সেট করে। আরেকটি উদাহরণ হল animation ক্লাস যা সাধারণত post-fs-data ইভেন্টের
আগে শুরু হয়। এই ধরনের কোনও আর্লি HAL পরিষেবা ভেন্ডর APEX-এ
প্যাকেজ করা হলে, APEX "vendorBootstrap": true-কে এর APEX
মেনিফেস্টে রাখুন যাতে এটি আগে অ্যাক্টিভেট করা যায়। মনে রাখবেন, বুটস্ট্র্যাপ APEX শুধুমাত্র /vendor/apex-এর মতো আগে থেকে তৈরি লোকেশন থেকেই অ্যাক্টিভেট করা যায়, /data/apex থেকে নয়।
সিস্টেম প্রপার্টি
ভেন্ডর APEX-এ কাজ করার জন্য ফ্রেমওয়ার্ক যেসব সিস্টেম প্রপার্টি পড়ে সেগুলি হল:
input_device.config_file.apex=<apex name>- সেট করা থাকলে, ইনপুট কনফিগারেশন ফাইল (*.idc,*.klএবং*.kcm) APEX-এর/etc/usrডিরেক্টরি থেকে খোঁজা হয়।ro.vulkan.apex=<apex name>- সেট করা থাকলে, Vulkan ড্রাইভারকে APEX থেকে লোড করা হয়। যেহেতু Vulkan ড্রাইভারটি প্রাথমিক HAL দ্বারা ব্যবহৃত হয়, তাই APEX Bootstrap APEX তৈরি করুন এবং সেই লিঙ্কার নেমস্পেস দৃশ্যমান কনফিগার করুন।
setprop
কমান্ড ব্যবহার করে ইনিট স্ক্রিপ্টে সিস্টেম প্রপার্টি সেট করুন।
অতিরিক্ত ফিচার
বুট-আপের সময় APEX বেছে নেওয়া
উদাহরণ:
বুট করার সময় ভেন্ডর APEX ঐচ্ছিকভাবে অ্যাক্টিভেট করা যেতে পারে।
আপনি যদি সিস্টেম প্রপার্টি ব্যবহার করে কোনও ফাইলের নাম নির্দিষ্ট করেন
ro.vendor.apex.<apex name>, তাহলে শুধুমাত্র ফাইলের নামের সাথে ম্যাচ করা APEX-টি নির্দিষ্ট <apex name>-এর জন্য
অ্যাক্টিভেট করা হবে।
এই সিস্টেম প্রপার্টি
none হিসেবে সেট করা থাকলে, <apex name> সহ APEX উপেক্ষা করা হয় (অ্যাক্টিভেট করা হয় না)। আপনি এই ফিচার ব্যবহার করে একই নামের APEX-এর একাধিক কপি ইনস্টল করতে পারবেন। একই APEX-এর একাধিক ভার্সন থাকলে, সেগুলির একই কী শেয়ার করা উচিত।
ব্যবহারের উদাহরণ:
- ওয়াই-ফাই HAL ভেন্ডর APEX-এর ৩টি ভার্সন ইনস্টল করুন: QA টিম একটি ভার্সন ব্যবহার করে ম্যানুয়াল বা অটোমেটেড টেস্টিং চালাতে পারে, তারপর অন্য ভার্সনে রিবুট করে টেস্ট আবার চালাতে পারে, তারপর চূড়ান্ত ফলাফল তুলনা করতে পারে।
- ক্যামেরা HAL ভেন্ডর APEX-এর ২টি ভার্সন ইনস্টল করুন, বর্তমান এবং এক্সপেরিমেন্টাল: ডগফুডাররা অতিরিক্ত ফাইল ডাউনলোড এবং ইনস্টল না করেই এক্সপেরিমেন্টাল ভার্সন ব্যবহার করতে পারবেন, যাতে তারা সহজেই আগের ভার্সনে ফিরে যেতে পারেন।
বুট-আপের সময়, apexd সঠিক APEX ভার্সন অ্যাক্টিভেট করার জন্য
নির্দিষ্ট ফর্ম্যাট মেনে sysprops খোঁজে।
প্রপার্টি কীয়ের প্রত্যাশিত ফর্ম্যাট হল:
- Bootconfig:
BoardConfig.mk-এ ডিফল্ট ভ্যালু সেট করতে ব্যবহার করা হয়।androidboot.vendor.apex.<apex name>(ro.boot.vendor.apex.<apex name>হিসেবে এক্সপোর্ট করা হয়েছে)।
- ডায়নামিক আর্লি-বুট কনফিগারেশন (
init_dev_config):- প্রতিটি SKU-এর জন্য APEX অ্যাক্টিভেশন ও বন্ধ করার (Android 17 ও এর পরের যেকোনও ভার্সনে উপলভ্য) জন্য সাজেস্ট করা প্রোডাকশন মেকানিজম।
apexd-bootstrapরান করার আগে বুট করার সময়ro.boot.vendor.apex.<apex name>ডায়নামিক সেট করে। প্রপার্টির ভ্যালুnoneহিসেবে সেট করলে APEX অ্যাক্টিভেট করা স্পষ্টভাবে বন্ধ হয়ে যায়।- আর্কিটেকচার সংক্রান্ত বিবরণের জন্য আর্লি বুট ডিভাইস কনফিগারেশন (
init_dev_config) দেখুন।
- পারসিস্টেন্ট sysprop (বন্ধ করে দেওয়া হয়েছে):
persist.vendor.apex.<apex name>- শুধুমাত্র ডেভেলপমেন্টের জন্য ফিচার।
/dataপার্টিশন মাউন্ট করার আগেapexdপ্রি-ইনস্টল করা APEX অ্যাক্টিভেট করে বলে,/data-এ স্টোর করা স্থায়ী sysprops প্রোডাকশন বিল্ডে প্রাথমিক APEX বেছে নেওয়ার জন্য ব্যবহার করা যাবে না।
প্রপার্টির ভ্যালু 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,
..
}
APEX বেছে নেওয়ার জন্য bootconfig ব্যবহার করা
বিল্ড টাইমে কোন APEX ব্যবহার করতে হবে তা ঘোষণা করতে, 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
ফ্ল্যাশ করার পরে ডিভাইসটি যদি বুটকনফিগার আপডেট করার সুবিধা দেয় (যেমন,
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";
APEX বেছে নেওয়ার জন্য init_dev_config ব্যবহার করুন
Android 17 ও তার পরের যেকোনও ভার্সনে, রানটাইমে ভেন্ডর APEX ডাইনামিক বেছে নিতে বা বন্ধ করতে, init_dev_config পরিষেবা দ্বারা এক্সিকিউট করা ভেন্ডর টুল প্রয়োগ করুন।
টুলটি apexd-bootstrap-এর আগে early-init চলাকালীন রান করে এবং rustutils::system_properties ব্যবহার করে
ro.boot.vendor.apex.* প্রপার্টি সেট করে।
কোনও APEX-এর ফাইলের নামে প্রপার্টি সেট করলে, অ্যাক্টিভেশনের জন্য সেই নির্দিষ্ট ভার্সনটি বেছে নেওয়া হয়
এবং none-এ ভ্যালু সেট করলে, কোনও APEX অ্যাক্টিভেট করা স্পষ্টভাবে
বন্ধ করা যায়, যেমন, যে SKU-তে হার্ডওয়্যার পেরিফেরাল
নেই।
use rustutils::system_properties;
fn main() {
// Select an APEX version based on detected SKU, or disable it altogether:
let hal_apex = match sku_type {
1 => "com.oem.camera.hal.my_apex_default",
2 => "com.oem.camera.hal.my_apex_experimental",
_ => "none",
};
system_properties::write(
"ro.boot.vendor.apex.com.oem.camera.hal",
hal_apex,
).expect("Failed to set vendor APEX selection property");
}
ডেভেলপমেন্টের জন্য পারসিস্ট্যান্ট sysprops ব্যবহার করা (সঞ্চালনের অনুপযুক্ত)
ডেভেলপমেন্ট ও ডিবাগিংয়ের উদ্দেশ্যে, ডিভাইস বুট করার পরে, আপনি স্থায়ী sysprop সেট করে অ্যাক্টিভেট করা ভার্সন পরিবর্তন করতে পারবেন:
$ adb root;
$ adb shell setprop \
persist.vendor.apex.com.oem.camera.hal \
com.oem.camera.hal.my_apex_experimental;
$ adb reboot;