এই পৃষ্ঠাটি Android-এ সিস্টেম প্রপার্টি যোগ বা সংজ্ঞায়িত করার জন্য একটি ক্যানোনিকাল পদ্ধতি প্রদান করে, যার সাথে বিদ্যমান সিস্টেম প্রপার্টি রিফ্যাক্টর করার জন্য নির্দেশিকা রয়েছে। রিফ্যাক্টর করার সময় নির্দেশিকা মেনে চলুন, যদি না আপনার কোনও গুরুতর মানানসই সংক্রান্ত সমস্যা থাকে যা অন্যভাবে নির্দেশ করে।
ধাপ ১: সিস্টেম প্রপার্টি নির্ধারণ করুন
আপনি কোনও সিস্টেম প্রপার্টি যোগ করলে, প্রপার্টির জন্য একটি নাম ঠিক করুন এবং সেটিকে SELinux প্রপার্টি কনটেক্সটের সাথে অ্যাসোসিয়েট করুন। আগে থেকে কোনও উপযুক্ত প্রসঙ্গ না থাকলে, নতুন প্রসঙ্গ তৈরি করো। প্রপার্টি অ্যাক্সেস করার সময় নাম ব্যবহার করা হয়; SELinux-এর ক্ষেত্রে অ্যাক্সেসিবিলিটি কন্ট্রোল করার জন্য প্রপার্টি কনটেক্সট ব্যবহার করা হয়। নাম যেকোনও স্ট্রিং হতে পারে, তবে AOSP সাজানো ফর্ম্যাট অনুসরণ করার পরামর্শ দেয় যাতে সেগুলি স্পষ্ট হয়।
প্রপার্টির নাম
snake_case কেসিং সহ এই ফর্ম্যাট ব্যবহার করুন:
[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]
prefix এলিমেন্টের জন্য "" (বাদ দেওয়া হয়েছে), ro (শুধুমাত্র একবার সেট করা প্রপার্টির জন্য) অথবা persist
(রিবুট করার পরেও থেকে যাওয়া প্রপার্টির জন্য) ব্যবহার করুন।
Caveats
ro শুধুমাত্র তখনই ব্যবহার করুন যখন আপনি নিশ্চিত যে ভবিষ্যতে prefix-এ লেখার প্রয়োজন হবে না। ** ro প্রিফিক্স উল্লেখ করবেন না।** এর পরিবর্তে, sepolicy-এর উপর নির্ভর করে prefix-কে
শুধু-পঠনযোগ্য করুন (অন্য কথায়, শুধুমাত্র init-এর মাধ্যমে লেখা যাবে)।
persist তখনই ব্যবহার করুন যখন আপনি নিশ্চিত যে রিবুট করার পরেও ভ্যালু অবশ্যই
সেভ করে রাখতে হবে এবং সিস্টেম প্রপার্টি ব্যবহার করা ছাড়া আপনার আর কোনও বিকল্প নেই।
Google সেইসব সিস্টেম প্রপার্টি কঠোরভাবে পর্যালোচনা করে যেগুলিতে ro বা persist
প্রপার্টি আছে।
group শব্দটি সম্পর্কিত প্রপার্টি একত্রিত করতে ব্যবহার করা হয়। এটি audio বা telephony-এর মতো
ব্যবহারের জন্য সাবসিস্টেমের নাম হিসেবে তৈরি করা হয়েছে। ব্যবহার করবেন না
sys, system, dev, default অথবা
config-এর মতো দ্ব্যর্থবোধক বা একাধিক অর্থযুক্ত শব্দ।
সিস্টেম প্রপার্টিতে এক্সক্লুসিভ রিড বা রাইট অ্যাক্সেস আছে এমন প্রসেসের ডোমেন টাইপের নাম ব্যবহার করা
সাধারণত হয়ে থাকে। যেমন, vold প্রসেসের যে সিস্টেম প্রপার্টিতে লেখার অ্যাক্সেস আছে,
সেখানে vold (প্রসেসের ডোমেন টাইপের নাম) কে
গ্রুপের নাম হিসেবে ব্যবহার করা হয়।
প্রয়োজন হলে, প্রপার্টি আরও শ্রেণীবদ্ধ করতে subgroup যোগ করুন, তবে এই এলিমেন্ট বর্ণনা করার জন্য
অস্পষ্ট বা ওভারলোড করা শব্দ এড়িয়ে চলুন। (এছাড়াও, আপনার একাধিক
subgroup থাকতে পারে।)
অনেক গ্রুপের নাম আগেই নির্ধারণ করা হয়েছে। system/sepolicy/private/property_contexts ফাইল চেক করুন এবং
সম্ভব হলে, নতুন নাম তৈরি করার পরিবর্তে আগে থেকে থাকা গ্রুপের নাম
ব্যবহার করুন। নিচে দেওয়া সারণীতে প্রায়শই ব্যবহৃত গ্রুপের নামের
উদাহরণ দেওয়া হল।
| ডোমেন | গ্রুপ (ও সাবগ্রুপ) |
|---|---|
| ব্লুটুথ সম্পর্কিত | bluetooth |
| কার্নেল cmdline থেকে sysprops | boot |
| বিল্ড শনাক্তকারী sysprops | build
|
| টেলিফোনি সম্পর্কিত | telephony |
| অডিও সম্পর্কিত | audio |
| গ্রাফিক্স সম্পর্কিত | graphics |
| vold সম্পর্কিত | vold |
নিম্নলিখিত বিষয়গুলি পূর্ববর্তী regex
উদাহরণে name ও type-এর ব্যবহারকে ব্যাখ্যা করে।
[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]
nameকোনও গ্রুপের মধ্যে সিস্টেম প্রপার্টি শনাক্ত করে।typeহল একটি ঐচ্ছিক এলিমেন্ট যা সিস্টেম প্রপার্টির ধরন বা উদ্দেশ্য স্পষ্ট করে। যেমন, কোনও sysprop-কেaudio.awesome_feature_enabledবা শুধুaudio.awesome_featureনাম না দিয়ে, সিস্টেম প্রপার্টির ধরন ও উদ্দেশ্য বোঝাতে, এটিকেaudio.awesome_feature.enabledহিসেবে রিনেম করুন।
টাইপ কী হতে হবে সেই সম্পর্কে কোনও নির্দিষ্ট নিয়ম নেই; এগুলি হল ব্যবহারের সুপারিশ:
enabled: কোনও ফিচার চালু বা বন্ধ করার জন্য ব্যবহৃত বুলিয়ান সিস্টেম প্রপার্টি হলে এটি ব্যবহার করুন।config: সিস্টেম প্রপার্টি যে সিস্টেমের ডায়নামিক স্টেটকে প্রতিনিধিত্ব করে না তা স্পষ্ট করার উদ্দেশ্যে ব্যবহার করুন; এটি একটি আগে থেকে কনফিগার করা ভ্যালুকে (যেমন, রিড-অনলি থিং) প্রতিনিধিত্ব করে।List: এটি এমন সিস্টেম প্রপার্টি হলে ব্যবহার করুন যার ভ্যালু একটি তালিকা।Timeoutmillis: এটি মিলিসেকেন্ডে টাইম-আউট ভ্যালুর জন্য সিস্টেম প্রপার্টি হলে ব্যবহার করুন।
উদাহরণ:
persist.radio.multisim.configdrm.service.enabled
প্রপার্টি কনটেক্সট
নতুন SELinux প্রপার্টি কন্টেক্সট স্কিম আরও সূক্ষ্ম গ্র্যানুলারিটি এবং আরও বর্ণনামূলক নামের অনুমতি দেয়। প্রপার্টির নামের জন্য যা ব্যবহার করা হয়, তার মতো, AOSP নিম্নলিখিত ফর্ম্যাট সাজেস্ট করে:
{group}[_{subgroup}]*_prop
এইসব শর্তাবলী এইভাবে সংজ্ঞায়িত করা হয়েছে:
group এবং subgroup-এর অর্থ আগের
স্যাম্পেল রেজেক্স-এর জন্য যেভাবে নির্ধারণ করা হয়েছে, ঠিক সেইভাবেই নির্ধারিত হয়। যেমন, vold_config_prop বলতে
এমন প্রপার্টি বোঝায় যা কোনও ভেন্ডরের কনফিগারেশন এবং যা vendor_init-এর
দ্বারা সেট করা হয়, অন্যদিকে vold_status_prop বা শুধু vold_prop বলতে এমন প্রপার্টি বোঝায়
যা vold-এর বর্তমান স্ট্যাটাস প্রকাশ করে।
প্রপার্টি কনটেক্সটের নাম দেওয়ার সময়, এমন নাম বেছে নিন যা প্রপার্টির সাধারণ ব্যবহারকে প্রতিফলিত করে। বিশেষ করে, নিম্নলিখিত ধরনের শব্দ ব্যবহার করা এড়িয়ে চলুন:
- যেসব শব্দ খুব সাধারণ এবং অস্পষ্ট, যেমন
sys,system,default। - অ্যাক্সেসিবিলিটি সরাসরি এনকোড করে এমন শব্দ: যেমন
exported,apponly,ro,public,private.
vold_config_prop-এর মতো নামের ব্যবহারকে exported_vold_prop-এর চেয়ে বেশি পছন্দ করি,
অথবা vold_vendor_writable_prop।
ধরন
টেবিলে তালিকাভুক্ত প্রপার্টির ধরন নিম্নলিখিতগুলির মধ্যে একটি হতে পারে।
| ধরন | সংজ্ঞা |
|---|---|
| বুলিয়ান | true বা 1 সত্যের জন্য, false বা 0 মিথ্যার জন্য |
| পূর্ণসংখ্যা | স্বাক্ষরিত ৬৪-বিট পূর্ণসংখ্যা |
| আনসাইনড পূর্ণসংখ্যা | আনসাইনড ৬৪-বিট পূর্ণসংখ্যা |
| ডবল | ডবল-প্রিসিশন ফ্লোটিং পয়েন্ট |
| স্ট্রিং | যেকোনও সঠিক UTF-8 স্ট্রিং |
| enum | ভ্যালু হল কোনও সঠিক UTF-8 স্ট্রিং যাতে কোনও হোয়াইটস্পেস নেই |
| উপরের তালিকা | কমা (,) হল ডিলিমিটারপূর্ণসংখ্যা তালিকা [1, 2, 3] 1,2,3 হিসেবে স্টোর করা হয় |
ইন্টার্নালি, সব প্রপার্টি স্ট্রিং হিসেবে সেভ করা হয়। আপনি এটিকে property_contexts ফাইল হিসেবে উল্লেখ করে
টাইপ প্রয়োগ করতে পারবেন। আরও তথ্যের জন্য, ধাপ ৩-এ
property_contexts দেখুন।
ধাপ ২: প্রয়োজনীয় অ্যাক্সেসিবিলিটি লেভেল নির্ধারণ করা
প্রপার্টিকে সংজ্ঞায়িত করে এমন চারটি হেল্পার ম্যাক্রো আছে।
| অ্যাক্সেসিবিলিটির ধরন | অর্থ |
|---|---|
system_internal_prop |
শুধুমাত্র /system-এ ব্যবহার করা প্রপার্টি |
system_restricted_prop |
/system-এর বাইরে পড়া হয়, কিন্তু লেখা হয় না এমন প্রপার্টি |
system_vendor_config_prop |
প্রপার্টি যা /system-এর বাইরে পড়া হয় এবং শুধুমাত্র vendor_init-এর মাধ্যমে লেখা হয় |
system_public_prop |
/system-এর বাইরে থেকে পড়া ও লেখা প্রপার্টি |
সিস্টেম প্রপার্টির অ্যাক্সেস যতটা সম্ভব সীমিত রাখুন। অতীতে, ব্রড অ্যাক্সেসের ফলে অ্যাপ ব্রেকডাউন ও নিরাপত্তা সংক্রান্ত দুর্বলতা দেখা গেছে। স্কোপিং করার সময় নিচের প্রশ্নগুলি বিবেচনা করুন:
- এই সিস্টেম প্রপার্টি কি সেভ করে রাখতে হবে? (যদি তাই হয়, তাহলে কেন?)
- কোন প্রসেসের এই প্রপার্টিতে রিড অ্যাক্সেস থাকা উচিত?
- কোন প্রসেসের এই প্রপার্টিতে লেখার অ্যাক্সেস থাকা উচিত?
অ্যাক্সেসের জন্য উপযুক্ত স্কোপ নির্ধারণ করতে, টুল হিসেবে পূর্ববর্তী প্রশ্ন এবং নিম্নলিখিত ডিসিশন ট্রি ব্যবহার করুন।
ছবি ১. সিস্টেম প্রপার্টিতে অ্যাক্সেসের স্কোপ নির্ধারণ করার জন্য ডিসিশন ট্রি
ধাপ ৩: সিস্টেম/sepolicy-তে যোগ করুন
sysprop অ্যাক্সেস করার সময়, SELinux প্রসেসের অ্যাক্সেসিবিলিটি কন্ট্রোল করে। কোন লেভেলের অ্যাক্সেসিবিলিটি প্রয়োজন তা নির্ধারণ করার পরে, system/sepolicy-এর অধীনে প্রপার্টি কনটেক্সট
সংজ্ঞায়িত করুন, সাথে প্রসেস কী কী পড়তে বা লিখতে পারবে (এবং পারবে না) সেই সম্পর্কে অতিরিক্ত অনুমতি দিন ও কখনও অনুমতি দেবেন না সংক্রান্ত নিয়ম
সংজ্ঞায়িত করুন।
প্রথমে, system/sepolicy/public/property.te
ফাইলে প্রপার্টি কনটেক্সট নির্ধারণ করুন। প্রপার্টি সিস্টেম-ইন্টার্নাল হলে, system/sepolicy/private/property.te ফাইলে তা সংজ্ঞায়িত করুন। আপনার সিস্টেম প্রপার্টির জন্য প্রয়োজনীয়
অ্যাক্সেসিবিলিটি প্রদান করে এমন
system_[accessibility]_prop([context])ম্যাক্রোগুলির মধ্যে একটি ব্যবহার করুন। এটি হল
system/sepolicy/public/property.te ফাইলের উদাহরণ:
system_public_prop(audio_foo_prop)
system_vendor_config_prop(audio_bar_prop)
system/sepolicy/private/property.te ফাইলে যোগ করার উদাহরণ:
system_internal_prop(audio_baz_prop)
দ্বিতীয়ত, প্রপার্টি কনটেক্সটে পড়ার ও (বা) লেখার অ্যাক্সেস দিন। set_prop
এবং get_prop ম্যাক্রো ব্যবহার করে অ্যাক্সেস দিন, এটি
system/sepolicy/public/{domain}.te অথবা system/sepolicy/private/{domain}.te
ফাইলে করতে হবে। সম্ভব হলে private ব্যবহার করুন; public শুধুমাত্র তখনই উপযুক্ত যখন
set_prop বা get_prop ম্যাক্রো মূল ডোমেনের বাইরের কোনও ডোমেনকে প্রভাবিত করে।
যেমন, system/sepolicy/private/audio.te ফাইলে:
set_prop(audio, audio_foo_prop)
set_prop(audio, audio_bar_prop)
যেমন, system/sepolicy/public/domain.te ফাইলে:
get_prop(domain, audio_bar_prop)
তৃতীয়ত, ম্যাক্রো দ্বারা স্কোপ করা অ্যাক্সেসিবিলিটি আরও কমাতে, কিছু neverallow নিয়ম যোগ করুন। যেমন, ধরুন আপনি
system_restricted_prop ব্যবহার করেছেন কারণ আপনার সিস্টেম প্রপার্টি অবশ্যই ভেন্ডর
প্রসেস দ্বারা পড়তে হবে। সব ভেন্ডর প্রসেসের যদি রিড অ্যাক্সেস না লাগে এবং এটি যদি
শুধুমাত্র নির্দিষ্ট কিছু প্রসেসের (যেমন vendor_init) প্রয়োজন হয়, তাহলে রিড অ্যাক্সেসের প্রয়োজন নেই
এমন ভেন্ডর প্রসেসকে নিষিদ্ধ করুন।
রাইট ও রিড অ্যাক্সেস সীমিত করার জন্য নিম্নলিখিত সিনট্যাক্স ব্যবহার করুন:
লেখার অ্যাক্সেস সীমাবদ্ধ করতে:
neverallow [domain] [context]:property_service set;
পড়ার অ্যাক্সেস সীমিত করতে:
neverallow [domain] [context]:file no_rw_file_perms;
system/sepolicy/private/{domain}.te ফাইলে neverallow নিয়ম রাখুন, যদি
neverallow নিয়মটি কোনও নির্দিষ্ট ডোমেনের সাথে আবদ্ধ থাকে। আরও বিস্তৃত neverallow নিয়মের জন্য, যেখানে উপযুক্ত সেখানে এগুলির মতো
সাধারণ ডোমেন ব্যবহার করুন:
system/sepolicy/private/property.tesystem/sepolicy/private/coredomain.tesystem/sepolicy/private/domain.te
system/sepolicy/private/audio.te ফাইলে, নিম্নলিখিতগুলি লিখুন:
neverallow {
domain -init -audio
} {audio_foo_prop audio_bar_prop}:property_service set;
system/sepolicy/private/property.te ফাইলে, নিম্নলিখিতগুলি রাখুন:
neverallow {
domain -coredomain -vendor_init
} audio_prop:file no_rw_file_perms;
মনে রাখবেন, {domain -coredomain} সব ভেন্ডর প্রসেস ক্যাপচার করে। তাই
{domain -coredomain -vendor_init} মানে "vendor_init ব্যতীত
সব ভেন্ডর প্রসেস।"
সবশেষে, প্রপার্টি কনটেক্সটের সাথে সিস্টেম প্রপার্টি অ্যাসোসিয়েট করুন। এটি নিশ্চিত করে
যে অ্যাক্সেস মঞ্জুর করা হয়েছে এবং neverallow নিয়মগুলি যা
প্রপার্টি প্রসঙ্গে প্রয়োগ করা হয়েছে তা প্রকৃত প্রপার্টিতে প্রয়োগ করা হয়েছে। এটি করতে, property_contexts ফাইলে একটি এন্ট্রি যোগ করুন। এই ফাইলটি সিস্টেম
প্রপার্টি এবং প্রপার্টি কনটেক্সটের মধ্যে ম্যাপিং বর্ণনা করে। এই ফাইলে, আপনি কোনও কনটেক্সটে ম্যাপ করার জন্য একটি
প্রপার্টি বা প্রপার্টির প্রিফিক্স নির্দিষ্ট করতে পারবেন।
সিঙ্গেল প্রপার্টি ম্যাপ করার সিনট্যাক্স হল:
[property_name] u:object_r:[context_name]:s0 exact [type]
প্রিফিক্স ম্যাপ করার সিনট্যাক্স এটি:
[property_name_prefix] u:object_r:[context_name]:s0 prefix [type]
আপনি ঐচ্ছিকভাবে প্রপার্টির ধরন নির্দিষ্ট করতে পারেন, যা নিম্নলিখিতগুলির মধ্যে একটি হতে পারে:
boolintuintdoubleenum [list of possible values...]string(তালিকার প্রপার্টির জন্যstringব্যবহার করুন।)
সম্ভব হলে, প্রতিটি এন্ট্রির জন্য নির্ধারিত ধরন আছে কিনা তা নিশ্চিত করুন, কারণ property সেট করার সময় type
এনফোর্স করা হয়। নিম্নলিখিত উদাহরণ থেকে কীভাবে
ম্যাপিং লিখতে হয় তা জানুন:
# binds a boolean property "ro.audio.status.enabled"
# to the context "audio_foo_prop"
ro.audio.status.enabled u:object_r:audio_foo_prop:s0 exact bool
# binds a boolean property "vold.decrypt.status"
# to the context "vold_foo_prop"
# The property can only be set to one of these: on, off, unknown
vold.decrypt.status u:object_r:vold_foo_prop:s0 exact enum on off unknown
# binds any properties starting with "ro.audio.status."
# to the context "audio_bar_prop", such as
# "ro.audio.status.foo", or "ro.audio.status.bar.baz", and so on.
ro.audio.status. u:object_r:audio_bar_prop:s0 prefix
একটি যথাযথ এন্ট্রি ও একটি প্রিফিক্স এন্ট্রি একে অপরের সাথে সাংঘর্ষিক হলে, যথাযথ এন্ট্রিটি
অগ্রাধিকার পায়। আরও উদাহরণের জন্য, system/sepolicy/private/property_contexts দেখুন।
ধাপ ৪: স্থিতিশীলতা সংক্রান্ত প্রয়োজনীয়তা নির্ধারণ করা
স্থিতিশীলতা হল সিস্টেম প্রপার্টির আরেকটি দিক এবং এটি অ্যাক্সেসিবিলিটি থেকে আলাদা। স্থিতিশীলতা বলতে বোঝায় যে ভবিষ্যতে কোনও সিস্টেম প্রপার্টি পরিবর্তন করা যাবে কিনা (যেমন, নাম পরিবর্তন করা বা এমনকি সরিয়ে দেওয়া)। Android OS মডিউলার হয়ে ওঠার কারণে এটি বিশেষভাবে গুরুত্বপূর্ণ। Treble-এর মাধ্যমে, সিস্টেম, ভেন্ডর ও প্রোডাক্ট পার্টিশন একে অপরের থেকে স্বাধীনভাবে আপডেট করা যায়। Mainline-এর মাধ্যমে, OS-এর কিছু অংশ আপডেট করা যাবে এমন মডিউল (APEXes বা APK-তে) হিসেবে মডিউলারাইজ করা হয়।
যদি কোনও সিস্টেম প্রপার্টি আপডেট করা যাবে এমন সফ্টওয়্যার জুড়ে ব্যবহার করার জন্য হয়, যেমন সিস্টেম ও ভেন্ডর পার্টিশন জুড়ে, তাহলে এটি অবশ্যই স্টেবল হতে হবে। তবে, এটি যদি শুধুমাত্র নির্দিষ্ট Mainline মডিউলের মধ্যে ব্যবহার করা হয়, তাহলে আপনি এর নাম, টাইপ বা প্রপার্টি প্রসঙ্গ পরিবর্তন করতে এবং এমনকি এটি সরিয়ে দিতে পারেন।
সিস্টেম প্রপার্টির স্থিতিশীলতা নির্ধারণ করতে নিম্নলিখিত প্রশ্নগুলি জিজ্ঞাসা করুন:
- এই সিস্টেম প্রপার্টি কি পার্টনারদের দ্বারা কনফিগার করার জন্য (অথবা ডিভাইস প্রতি আলাদাভাবে কনফিগার করা) উদ্দেশ্য করা হয়েছে? হ্যাঁ হলে, সেটি অবশ্যই স্থিতিশীল হতে হবে।
- এই AOSP-নির্ধারিত সিস্টেম প্রপার্টি কি
vendor.imgবাproduct.img-এর মতো নন-সিস্টেম পার্টিশনে থাকা কোড (প্রসেস নয়) থেকে লেখা বা পড়ার জন্য তৈরি করা হয়েছে? হ্যাঁ হলে, সেটি অবশ্যই স্থিতিশীল হতে হবে। - এই সিস্টেম প্রপার্টি কি মেইনলাইন মডিউল জুড়ে বা মেইনলাইন মডিউল এবং প্ল্যাটফর্মের আপডেট করা যায় না এমন অংশ জুড়ে অ্যাক্সেস করা হয়? হ্যাঁ হলে, এটি অবশ্যই স্থিতিশীল হতে হবে।
স্থিতিশীল সিস্টেম প্রপার্টির জন্য, প্রতিটি API হিসেবে আনুষ্ঠানিকভাবে সংজ্ঞায়িত করুন এবং সিস্টেম প্রপার্টি অ্যাক্সেস করতে API ব্যবহার করুন, যেমনটি ধাপ ৬-এ ব্যাখ্যা করা হয়েছে।
ধাপ ৫: বিল্ড করার সময় প্রপার্টি সেট করা
makefile ভেরিয়েবল ব্যবহার করে বিল্ড টাইমে প্রপার্টি সেট করুন। টেকনিক্যালি, ভ্যালুগুলি
{partition}/build.prop-এ বিল্ট-ইন থাকে। তারপরে, প্রপার্টি সেট করতে init reads
{partition}/build.prop। এই ধরনের ভেরিয়েবলের দুটি সেট আছে: PRODUCT_{PARTITION}_PROPERTIES ও TARGET_{PARTITION}_PROP।
PRODUCT_{PARTITION}_PROPERTIES-এ প্রপার্টি ভ্যালুর তালিকা থাকে। সিনট্যাক্স
হল {prop}={value} বা {prop}?={value}।
{prop}={value} হল একটি সাধারণ অ্যাসাইনমেন্ট যা নিশ্চিত করে যে {prop}-এর মান
{value}-এ সেট করা আছে; একটি প্রপার্টির জন্য শুধুমাত্র একটিই এই ধরনের অ্যাসাইনমেন্ট সম্ভব।
{prop}?={value} হল একটি ঐচ্ছিক অ্যাসাইনমেন্ট; {prop} শুধুমাত্র তখনই {value} হিসেবে সেট করা হয়, যখন
কোনও {prop}={value} অ্যাসাইনমেন্ট থাকে না। একাধিক ঐচ্ছিক অ্যাসাইনমেন্ট
থাকলে, প্রথমটিই বিবেচিত হবে।
# sets persist.traced.enable to 1 with system/build.prop
PRODUCT_SYSTEM_PROPERTIES += persist.traced.enable=1
# sets ro.zygote to zygote32 with system/build.prop
# but only when there are no other assignments to ro.zygote
# optional are useful when giving a default value to a property
PRODUCT_SYSTEM_PROPERTIES += ro.zygote?=zygote32
# sets ro.config.low_ram to true with vendor/build.prop
PRODUCT_VENDOR_PROPERTIES += ro.config.low_ram=true
TARGET_{PARTITION}_PROP-এ ফাইলের একটি তালিকা থাকে, যা সরাসরি
{partition}/build.prop-এ পাঠানো হয়। প্রতিটি ফাইলে {prop}={value} জোড়ার তালিকা থাকে।
# example.prop
ro.cp_system_other_odex=0
ro.adb.secure=0
ro.control_privapp_permissions=disable
# emits example.prop to system/build.prop
TARGET_SYSTEM_PROP += example.prop
আরও বিবরণের জন্য, build/make/core/sysprop.mk দেখুন।
ধাপ ৬: রানটাইমে প্রপার্টি অ্যাক্সেস করা
রানটাইমে প্রপার্টি পড়া ও লেখা যেতে পারে।
ইনিট স্ক্রিপ্ট
ইনিট স্ক্রিপ্ট ফাইল (সাধারণত *.rc ফাইল) ${prop} বা
${prop:-default} ব্যবহার করে কোনও প্রপার্টি পড়তে পারে, কোনও অ্যাকশন সেট করতে পারে যা কোনও প্রপার্টি
নির্দিষ্ট ভ্যালু হয়ে গেলে রান করে এবং setprop কমান্ড ব্যবহার করে প্রপার্টি লিখতে পারে।
# when persist.device_config.global_settings.sys_traced becomes 1,
# set persist.traced.enable to 1
on property:persist.device_config.global_settings.sys_traced=1
setprop persist.traced.enable 1
# when security.perf_harden becomes 0,
# write /proc/sys/kernel/sample_rate to the value of
# debug.sample_rate. If it's empty, write -100000 instead
on property:security.perf_harden=0
write /proc/sys/kernel/sample_rate ${debug.sample_rate:-100000}
getprop এবং setprop শেল কমান্ড
প্রপার্টি পড়তে বা লিখতে, আপনি যথাক্রমে getprop বা setprop শেল কমান্ড ব্যবহার করতে পারেন।
আরও বিবরণের জন্য, getprop --help বা
setprop --help চালু করুন।
$ adb shell getprop ro.vndk.version
$
$ adb shell setprop security.perf_harden 0
C++/Java/Rust-এর জন্য API হিসেবে Sysprop
API হিসেবে sysprop-এর মাধ্যমে, আপনি সিস্টেম প্রপার্টি সংজ্ঞায়িত করতে এবং অটোমেটিক জেনারেট করা API ব্যবহার করতে পারবেন
যা কংক্রিট এবং টাইপ করা। Public-এর সাথে scope সেট করলে, জেনারেট করা API-কে
বাউন্ডারি জুড়ে মডিউলের জন্য উপলভ্য করে এবং API-এর স্থায়িত্ব নিশ্চিত করে। এখানে একটি
.sysprop ফাইলের, একটি Android.bp মডিউলের এবং C++, Java ও Rust কোডের
নমুনা দেওয়া হল যেগুলি ব্যবহার করা হয়েছে।
# AudioProps.sysprop
# module becomes static class (Java) / namespace (C++) for serving API
module: "android.sysprop.AudioProps"
# owner can be Platform or Vendor or Odm
owner: Platform
# one prop defines one property
prop {
prop_name: "ro.audio.volume.level"
type: Integer
scope: Public
access: ReadWrite
api_name: "volume_level"
}
…
// Android.bp
sysprop_library {
name: "AudioProps",
srcs: ["android/sysprop/AudioProps.sysprop"],
property_owner: "Platform",
}
// Rust, Java and C++ modules can link against the sysprop_library
rust_binary {
rustlibs: ["libaudioprops_rust"],
…
}
java_library {
static_libs: ["AudioProps"],
…
}
cc_binary {
static_libs: ["libAudioProps"],
…
}
// Rust code accessing generated API.
// Get volume. Use 50 as the default value.
let vol = audioprops::volume_level()?.unwrap_or_else(50);
// Java codes accessing generated API
// get volume. use 50 as the default value.
int vol = android.sysprop.AudioProps.volume_level().orElse(50);
// add 10 to the volume level.
android.sysprop.AudioProps.volume_level(vol + 10);
// C++ codes accessing generated API
// get volume. use 50 as the default value.
int vol = android::sysprop::AudioProps::volume_level().value_or(50);
// add 10 to the volume level.
android::sysprop::AudioProps::volume_level(vol + 10);
আরও তথ্যের জন্য, API হিসেবে সিস্টেম প্রপার্টি প্রয়োগ করা দেখুন।
C/C++, Java ও Rust-এর লো-লেভেল প্রপার্টি ফাংশন ও পদ্ধতি
সম্ভব হলে, API হিসেবে Sysprop ব্যবহার করুন, যদিও আপনার কাছে লো-লেভেল C/C++ বা Rust ফাংশন বা লো-লেভেল Java মেথড উপলভ্য।
libc, libbase ও libcutils C++ সিস্টেম প্রপার্টি ফাংশন অফার করে। libc-এর মধ্যে অন্তর্নিহিত API আছে, যেখানে libbase ও libcutils ফাংশন হল
র্যাপার। সম্ভব হলে, libbase sysprop ফাংশন ব্যবহার করুন; এগুলি সবচেয়ে
সুবিধাজনক এবং হোস্ট বাইনারি libbase ফাংশন ব্যবহার করতে পারে। আরও
বিবরণের জন্য, sys/system_properties.h (libc), android-base/properties.h
(libbase) এবং cutils/properties.h (libcutils) দেখুন।
android.os.SystemProperties ক্লাস Java সিস্টেম প্রপার্টি মেথড অফার করে।
rustutils::system_properties মডিউল, Rust সিস্টেম প্রপার্টি ফাংশন
ও ধরন অফার করে।
পরিশিষ্ট: ভেন্ডর-নির্দিষ্ট প্রপার্টি যোগ করা
পার্টনাররা (Pixel ডেভেলপমেন্টের প্রসঙ্গে কাজ করা Googler সহ) হার্ডওয়্যার-ভিত্তিক (বা ডিভাইস-ভিত্তিক) সিস্টেম প্রপার্টি
নির্ধারণ করতে চান।
ভেন্ডর-নির্দিষ্ট প্রপার্টি হল পার্টনারের মালিকানাধীন প্রপার্টি যা তাদের
নিজস্ব হার্ডওয়্যার বা ডিভাইসের জন্য অনন্য, প্ল্যাটফর্মের জন্য নয়। এগুলি হার্ডওয়্যার বা ডিভাইস
নির্ভর হওয়ায়, /vendor বা /odm পার্টিশনের মধ্যে ব্যবহার করার জন্য তৈরি করা হয়েছে।
Project Treble-এর পর থেকে, প্ল্যাটফর্ম প্রপার্টি ও ভেন্ডর প্রপার্টি সম্পূর্ণভাবে আলাদা করা হয়েছে যাতে তাদের মধ্যে কোনও বিরোধ না হয়। নিম্নলিখিত বিবরণ থেকে কীভাবে ভেন্ডর প্রপার্টি নির্ধারণ করতে হয় তা জানা যায় এবং কোন ভেন্ডর প্রপার্টি সবসময় ব্যবহার করতে হবে তাও জানা যায়।
প্রপার্টি ও প্রসঙ্গ নামের নেমস্পেস
অন্যান্য পার্টিশনের প্রপার্টি ও ভেন্ডর প্রপার্টির মধ্যে সংঘর্ষ এড়াতে, সব ভেন্ডর প্রপার্টি নিম্নলিখিত প্রিফিক্সের মধ্যে কোনও একটি দিয়ে শুরু হতে হবে।
ctl.odm.ctl.vendor.ctl.start$odm.ctl.start$vendor.ctl.stop$odm.ctl.stop$vendor.init.svc.odm.init.svc.vendor.ro.odm.ro.vendor.odm.persist.odm.persist.vendor.vendor.
মনে রাখবেন, ro.hardware.-কে প্রিফিক্স হিসেবে ব্যবহার করার অনুমতি দেওয়া হয়েছে, তবে এটি শুধুমাত্র কম্প্যাটিবিলিটির জন্য।
সাধারণ প্রপার্টির জন্য এটি ব্যবহার করবেন না।
নিচে দেওয়া উদাহরণগুলিতে আগে উল্লেখ করা উপসর্গগুলির মধ্যে একটি ব্যবহার করা হয়েছে:
vendor.display.primary_redpersist.vendor.faceauth.use_disk_cachero.odm.hardware.platform
সব ভেন্ডর প্রপার্টি কনটেক্সট vendor_ দিয়ে শুরু হতে হবে। এটিও
মানানসই হওয়ার জন্য। নিচে কয়েকটি উদাহরণ দেওয়া হল:
vendor_radio_prop।vendor_faceauth_prop।vendor_usb_prop।
প্রপার্টির নাম দেওয়া ও তা বজায় রাখার দায়িত্ব হল ভেন্ডরের, তাই ভেন্ডর নেমস্পেস সংক্রান্ত প্রয়োজনীয়তা ছাড়াও, ধাপ ২-এ সাজেস্ট করা ফর্ম্যাট অনুসরণ করুন।
ভেন্ডর-নির্দিষ্ট SEPolicy নিয়ম ও property_contexts
vendor_internal_prop ম্যাক্রোর মাধ্যমে ভেন্ডর প্রপার্টি নির্ধারণ করা যায়। BOARD_VENDOR_SEPOLICY_DIRS ডিরেক্টরিতে আপনার নির্ধারণ করা
ভেন্ডর-নির্দিষ্ট নিয়মগুলি রাখুন।
যেমন, ধরুন আপনি কোরালে কোনও ভেন্ডর ফেসঅথ প্রপার্টি নির্ধারণ করছেন।
BoardConfig.mk ফাইলে (বা যেকোনও BoardConfig.mk includes-এ), নিম্নলিখিত
বিষয়গুলি লিখুন:
BOARD_VENDOR_SEPOLICY_DIRS := device/google/coral-sepolicy
device/google/coral-sepolicy/private/property.te ফাইলে, নিম্নলিখিত
বিষয়গুলি লিখুন:
vendor_internal_prop(vendor_faceauth_prop)
device/google/coral-sepolicy/private/property_contexts ফাইলে, নিম্নলিখিত
বিষয়গুলি লিখুন:
vendor.faceauth.trace u:object_r:vendor_faceauth_prop:s0 exact bool
ভেন্ডর প্রপার্টির সীমাবদ্ধতা
সিস্টেম ও প্রোডাক্ট পার্টিশন ভেন্ডরের উপর নির্ভর করতে পারে না, তাই কখনও
ভেন্ডর প্রপার্টিকে system, system-ext বা
product পার্টিশন থেকে অ্যাক্সেস করার অনুমতি দেবেন না।
পরিশিষ্ট: আগে থেকে থাকা প্রপার্টির নাম পরিবর্তন করা
আপনাকে কোনও প্রপার্টি বন্ধ করে নতুন প্রপার্টিতে যেতে হলে, আপনার বর্তমান প্রপার্টির নাম পরিবর্তন করতে Sysprop as APIs
ব্যবহার করুন। পুরনো নাম ও নতুন প্রপার্টির নাম উল্লেখ করার মাধ্যমে এটি
ব্যাকওয়ার্ড কম্প্যাটিবিলিটি বজায় রাখে। বিশেষ করে, আপনি
.sysprop ফাইলের legacy_prop_name ফিল্ডের মাধ্যমে লিগ্যাসি নাম সেট করতে পারবেন। জেনারেট করা API, prop_name পড়ার চেষ্টা করে এবং prop_name না থাকলে legacy_prop_name ব্যবহার করে।
যেমন, নিম্নলিখিত ধাপগুলি awesome_feature_foo_enabled
থেকে foo.awesome_feature.enabled-এ নাম পরিবর্তন করে।
foo.sysprop ফাইলে
module: "android.sysprop.foo"
owner: Platform
prop {
api_name: "is_awesome_feature_enabled"
type: Boolean
scope: Public
access: Readonly
prop_name: "foo.awesome_feature.enabled"
legacy_prop_name: "awesome_feature_foo_enabled"
}
C++ কোডে
// is_awesome_feature_enabled() reads "foo.awesome_feature.enabled".
// If it doesn't exist, reads "awesome_feature_foo_enabled" instead
using android::sysprop::foo;
bool enabled = foo::is_awesome_feature_enabled().value_or(false);
নিম্নলিখিত সতর্কতাগুলি মনে রাখবেন:
প্রথমত, আপনি sysprop-এর ধরন পরিবর্তন করতে পারবেন না। যেমন, আপনি কোনও
intপ্রপকেstringপ্রপে পরিবর্তন করতে পারবেন না। আপনি শুধু নাম পরিবর্তন করতে পারবেন।দ্বিতীয়ত, শুধুমাত্র রিড API-এর ক্ষেত্রে পুরনো নাম ব্যবহার করা হয়। রাইট API ফলব্যাক হয় না। sysprop যদি লেখার উপযুক্ত হয়, তাহলে আপনি এটির নাম পরিবর্তন করতে পারবেন না।