সিস্টেম বৈশিষ্ট্য যোগ করুন

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

ধাপ ১: সিস্টেম প্রপার্টিটি সংজ্ঞায়িত করুন।

যখন আপনি একটি সিস্টেম প্রপার্টি যোগ করবেন, তখন প্রপার্টিটির জন্য একটি নাম ঠিক করুন এবং এটিকে একটি SELinux প্রপার্টি কনটেক্সটের সাথে যুক্ত করুন। যদি কোনো উপযুক্ত বিদ্যমান কনটেক্সট না থাকে, তবে একটি নতুন তৈরি করুন। প্রপার্টিটি অ্যাক্সেস করার সময় নামটি ব্যবহৃত হয়; SELinux-এর পরিপ্রেক্ষিতে অ্যাক্সেসযোগ্যতা নিয়ন্ত্রণ করতে প্রপার্টি কনটেক্সট ব্যবহৃত হয়। নাম যেকোনো স্ট্রিং হতে পারে, কিন্তু AOSP সেগুলোকে স্পষ্ট করার জন্য একটি কাঠামোগত বিন্যাস অনুসরণ করার পরামর্শ দেয়।

সম্পত্তির নাম

snake_case কেসিং সহ এই ফর্ম্যাটটি ব্যবহার করুন:

[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]

এলিমেন্ট prefix জন্য হয় "" (বাদ দেওয়া), ro (শুধুমাত্র একবার সেট করা প্রোপার্টির জন্য), অথবা persist (যে প্রোপার্টিগুলো রিবুটের পরেও থেকে যায়) ব্যবহার করুন।

সতর্কতা

শুধুমাত্র তখনই ro ব্যবহার করুন যখন আপনি নিশ্চিত যে ভবিষ্যতে আপনার prefix রাইটেবল করার প্রয়োজন হবে না। ** ro প্রিফিক্সটি নির্দিষ্ট করবেন না।** এর পরিবর্তে, prefix রিড-অনলি (অন্য কথায়, শুধুমাত্র init দ্বারা রাইটেবল) করতে sepolicy-এর উপর নির্ভর করুন।

persist শুধুমাত্র তখনই ব্যবহার করুন, যখন আপনি নিশ্চিত হন যে মানটি রিবুটের পরেও সংরক্ষিত রাখতে হবে এবং সিস্টেম প্রোপার্টি ব্যবহার করাই আপনার একমাত্র উপায়।

যেসব সিস্টেম প্রপার্টিতে ro বা persist প্রপার্টি থাকে, গুগল সেগুলো কঠোরভাবে পর্যালোচনা করে।

' group শব্দটি সম্পর্কিত প্রোপার্টিগুলোকে একত্রিত করতে ব্যবহৃত হয়। এটি audio বা telephony মতো একটি সাবসিস্টেমের নাম হিসেবে ব্যবহৃত হওয়ার উদ্দেশ্যে তৈরি। sys , system , dev , default , বা config মতো দ্ব্যর্থক বা অতিরিক্ত অর্থবোধক শব্দ ব্যবহার করবেন না

সিস্টেম প্রোপার্টিজে এক্সক্লুসিভ রিড বা রাইট অ্যাক্সেস আছে এমন কোনো প্রসেসের ডোমেইন টাইপের নামটি ব্যবহার করা একটি প্রচলিত রীতি। উদাহরণস্বরূপ, vold প্রসেসটির যে সিস্টেম প্রোপার্টিজে রাইট অ্যাক্সেস আছে, তার গ্রুপ নেম হিসেবে vold (প্রসেসটির ডোমেইন টাইপের নাম) ব্যবহার করা হয়ে থাকে।

প্রয়োজনে, প্রোপার্টিগুলোকে আরও শ্রেণিবদ্ধ করার জন্য subgroup যোগ করুন, কিন্তু এই এলিমেন্টটি বর্ণনা করার জন্য দ্ব্যর্থক বা অতিরিক্ত অর্থবোধক শব্দ পরিহার করুন। (আপনি একাধিক subgroup রাখতে পারেন।)

অনেক গ্রুপের নাম ইতিমধ্যেই সংজ্ঞায়িত করা হয়েছে। system/sepolicy/private/property_contexts ফাইলটি দেখুন এবং নতুন নাম তৈরি করার পরিবর্তে, যেখানে সম্ভব বিদ্যমান গ্রুপের নাম ব্যবহার করুন। নিচের সারণিতে প্রায়শই ব্যবহৃত গ্রুপের নামের উদাহরণ দেওয়া হলো।

ডোমেইন গোষ্ঠী (এবং উপগোষ্ঠী)
ব্লুটুথ সম্পর্কিত bluetooth
কার্নেল কমান্ডলাইন থেকে sysprops boot
বিল্ড শনাক্তকারী সিস্টেম প্রপার্টি build
টেলিফোনি সম্পর্কিত telephony
অডিও সম্পর্কিত audio
গ্রাফিক্স সম্পর্কিত graphics
ভোল্ড সম্পর্কিত vold

পূর্ববর্তী রেজেক্স উদাহরণে 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 : যদি এটি একটি সিস্টেম প্রপার্টি হয় এবং টাইমআউটের মান মিলিসেকেন্ড (ms) এককে প্রকাশ করা হয়, তবে এটি ব্যবহার করুন।

উদাহরণ:

  • persist.radio.multisim.config
  • drm.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

exported_vold_prop বা vold_vendor_writable_prop এর পরিবর্তে vold_config_prop এর মতো নাম ব্যবহার করা শ্রেয়।

প্রকার

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

প্রকার সংজ্ঞা
বুলিয়ান সত্য হলে true বা 1 , মিথ্যা হলে false বা 0
পূর্ণসংখ্যা স্বাক্ষরিত ৬৪-বিট পূর্ণসংখ্যা
স্বাক্ষরবিহীন পূর্ণসংখ্যা স্বাক্ষরবিহীন ৬৪-বিট পূর্ণসংখ্যা
দ্বিগুণ ডাবল-প্রিসিশন ফ্লোটিং পয়েন্ট
স্ট্রিং যেকোনো বৈধ UTF-8 স্ট্রিং
এনাম মানগুলো স্পেস ছাড়া যেকোনো বৈধ 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 বাইরে পড়া এবং লেখা হয়

সিস্টেম প্রোপার্টিতে অ্যাক্সেসের পরিধি যতটা সম্ভব সীমিত রাখুন। অতীতে, ব্যাপক অ্যাক্সেসের ফলে অ্যাপ বিকল হয়েছে এবং নিরাপত্তা ঝুঁকি তৈরি হয়েছে। অ্যাক্সেসের পরিধি নির্ধারণ করার সময় নিম্নলিখিত প্রশ্নগুলো বিবেচনা করুন:

  • এই সিস্টেম প্রপার্টিটি কি সংরক্ষণ করার প্রয়োজন আছে? (যদি থাকে, তবে কেন?)
  • কোন প্রসেসের এই প্রপার্টিটি পড়ার অ্যাক্সেস থাকা উচিত?
  • কোন প্রসেসের এই প্রপার্টিতে লেখার অ্যাক্সেস থাকা উচিত?

অ্যাক্সেসের উপযুক্ত পরিধি নির্ধারণের জন্য পূর্ববর্তী প্রশ্নাবলী এবং নিম্নলিখিত ডিসিশন ট্রি-কে সরঞ্জাম হিসেবে ব্যবহার করুন।

Decision tree for determining the scope of access

চিত্র ১. সিস্টেম প্রোপার্টিতে অ্যাক্সেসের পরিধি নির্ধারণের জন্য ডিসিশন ট্রি।

ধাপ ৩: system/sepolicy-তে যোগ করুন

sysprop অ্যাক্সেস করার সময়, SELinux প্রসেসগুলোর অ্যাক্সেসযোগ্যতা নিয়ন্ত্রণ করে। কী স্তরের অ্যাক্সেসযোগ্যতা প্রয়োজন তা নির্ধারণ করার পর, system/sepolicy অধীনে প্রপার্টি context সংজ্ঞায়িত করুন। এর সাথে, প্রসেসগুলো কী পড়তে বা লিখতে পারবে (এবং পারবে না) সে সম্পর্কে অতিরিক্ত allow এবং neverallow নিয়মও নির্ধারণ করুন।

প্রথমে, 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)

দ্বিতীয়ত, প্রপার্টি কনটেক্সটে রিড এবং (অথবা) রাইট অ্যাক্সেস দিন। অ্যাক্সেস দেওয়ার জন্য system/sepolicy/public/{domain}.te অথবা system/sepolicy/private/{domain}.te ফাইলে set_prop এবং get_prop ম্যাক্রো ব্যবহার করুন। যখনই সম্ভব 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;

যদি neverallow নিয়মটি কোনো নির্দিষ্ট ডোমেনের সাথে আবদ্ধ থাকে, তবে নিয়মটি system/sepolicy/private/{domain}.te ফাইলে রাখুন। ব্যাপকতর neverallow নিয়মের জন্য, যেখানে যেখানে উপযুক্ত, সেখানে এই ধরনের সাধারণ ডোমেন ব্যবহার করুন:

  • system/sepolicy/private/property.te
  • system/sepolicy/private/coredomain.te
  • system/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 ছাড়া বাকি সমস্ত ভেন্ডর প্রসেস"।

অবশেষে, একটি সিস্টেম প্রপার্টিকে প্রপার্টি কনটেক্সটের সাথে যুক্ত করুন। এটি নিশ্চিত করে যে, প্রপার্টি কনটেক্সটের জন্য প্রদত্ত অ্যাক্সেস এবং প্রযোজ্য ‘নেভারঅ্যালাউ’ নিয়মগুলো প্রকৃত প্রপার্টিগুলোর উপরেও প্রয়োগ করা হয়। এটি করার জন্য, property_contexts ফাইলে একটি এন্ট্রি যোগ করুন; এই ফাইলটি সিস্টেম প্রপার্টি এবং প্রপার্টি কনটেক্সটের মধ্যেকার ম্যাপিং বর্ণনা করে। এই ফাইলে, আপনি একটি একক প্রপার্টি অথবা কনটেক্সটে ম্যাপ করার জন্য প্রপার্টিগুলোর একটি প্রিফিক্স নির্দিষ্ট করে দিতে পারেন।

একটিমাত্র প্রপার্টি ম্যাপ করার সিনট্যাক্সটি হলো:

[property_name] u:object_r:[context_name]:s0 exact [type]

প্রিফিক্স ম্যাপ করার সিনট্যাক্সটি হলো:

[property_name_prefix] u:object_r:[context_name]:s0 prefix [type]

আপনি ঐচ্ছিকভাবে প্রপার্টির ধরণ নির্দিষ্ট করতে পারেন, যা নিম্নলিখিতগুলির মধ্যে একটি হতে পারে:

  • bool
  • int
  • uint
  • double
  • enum [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 দেখুন।

ধাপ ৪: স্থিতিশীলতার প্রয়োজনীয়তা নির্ধারণ করুন

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

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

কোনো সিস্টেম বৈশিষ্ট্যের স্থিতিশীলতা নির্ধারণ করতে নিম্নলিখিত প্রশ্নগুলো জিজ্ঞাসা করুন:

  • এই সিস্টেম প্রপার্টিটি কি পার্টনারদের দ্বারা কনফিগার করার জন্য (অথবা ডিভাইস অনুযায়ী ভিন্নভাবে কনফিগার করার জন্য) উদ্দিষ্ট? যদি উত্তর হ্যাঁ হয়, তবে এটি অবশ্যই স্থিতিশীল হতে হবে।
  • এই AOSP-দ্বারা সংজ্ঞায়িত সিস্টেম প্রপার্টিটি কি vendor.img বা product.img মতো নন-সিস্টেম পার্টিশনে থাকা কোনো কোডে (প্রসেস নয়) লেখা বা পড়ার জন্য উদ্দিষ্ট? যদি উত্তর হ্যাঁ হয়, তবে এটিকে অবশ্যই স্থিতিশীল হতে হবে।
  • এই সিস্টেম প্রপার্টিটি কি মেইনলাইন মডিউলগুলোর মধ্যে, অথবা একটি মেইনলাইন মডিউল এবং প্ল্যাটফর্মের অ-আপডেটযোগ্য অংশের মধ্যে অ্যাক্সেস করা হয়? যদি উত্তর হ্যাঁ হয়, তবে এটি অবশ্যই স্থিতিশীল হতে হবে।

স্থিতিশীল সিস্টেম প্রোপার্টিগুলোর জন্য, প্রত্যেকটিকে আনুষ্ঠানিকভাবে একটি API হিসেবে সংজ্ঞায়িত করুন এবং ধাপ ৬- এ ব্যাখ্যা করা অনুযায়ী সিস্টেম প্রোপার্টিটি অ্যাক্সেস করতে API ব্যবহার করুন।

ধাপ ৫: বিল্ড টাইমে প্রোপার্টি সেট করুন

মেকফাইল ভেরিয়েবল ব্যবহার করে বিল্ড টাইমে প্রোপার্টিগুলো সেট করুন। টেকনিক্যালি, ভ্যালুগুলো {partition}/build.prop ফাইলে বিল্ড করা থাকে। এরপর init প্রোপার্টিগুলো সেট করার জন্য {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

এপিআই হিসেবে sysprop ব্যবহার করে, আপনি সিস্টেম প্রোপার্টি সংজ্ঞায়িত করতে পারেন এবং স্বয়ংক্রিয়ভাবে তৈরি হওয়া সুনির্দিষ্ট ও টাইপযুক্ত এপিআই ব্যবহার করতে পারেন। scope Public হিসেবে সেট করলে তৈরি হওয়া এপিআইগুলো বিভিন্ন মডিউলের সীমানা পেরিয়েও উপলব্ধ হয় এবং এপিআই-এর স্থিতিশীলতা নিশ্চিত করে। এখানে একটি .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);

আরও তথ্যের জন্য, ‘সিস্টেম প্রোপার্টিগুলোকে এপিআই হিসেবে প্রয়োগ করুন’ দেখুন।

C/C++, Java, এবং Rust-এর নিম্ন-স্তরের প্রপার্টি ফাংশন এবং মেথড

সম্ভব হলে, নিম্ন-স্তরের C/C++ বা Rust ফাংশন অথবা নিম্ন-স্তরের Java মেথড উপলব্ধ থাকলেও API হিসেবে Sysprop ব্যবহার করুন।

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 ক্লাসটি জাভা সিস্টেম প্রপার্টি মেথড প্রদান করে।

rustutils::system_properties মডিউলটি রাস্ট সিস্টেম প্রপার্টি ফাংশন এবং টাইপ প্রদান করে।

পরিশিষ্ট: বিক্রেতা-নির্দিষ্ট বৈশিষ্ট্য যোগ করুন

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

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

প্রপার্টি এবং কনটেক্সট নামের উপর নেমস্পেস

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

  • 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_red
  • persist.vendor.faceauth.use_disk_cache
  • ro.odm.hardware.platform

সকল ভেন্ডর প্রপার্টি কনটেক্সট অবশ্যই vendor_ দিয়ে শুরু হতে হবে। এটি সামঞ্জস্য রক্ষার জন্যও করা হয়। নিচে কিছু উদাহরণ দেওয়া হলো:

  • vendor_radio_prop .
  • vendor_faceauth_prop .
  • vendor_usb_prop .

প্রপার্টিগুলোর নামকরণ ও রক্ষণাবেক্ষণ করা ভেন্ডরের দায়িত্ব, তাই ভেন্ডর নেমস্পেসের আবশ্যকতাগুলোর পাশাপাশি ধাপ ২- এ প্রস্তাবিত ফরম্যাটটিও অনুসরণ করুন।

বিক্রেতা-নির্দিষ্ট SEPolicy নিয়ম এবং property_context

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

BoardConfig.mk ফাইলে (অথবা যেকোনো BoardConfig.mk include-এর মধ্যে) নিম্নলিখিতটি রাখুন:

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 prop-কে string prop-এ রূপান্তর করতে পারবেন না। আপনি শুধুমাত্র এর নাম পরিবর্তন করতে পারবেন।

  • দ্বিতীয়ত, শুধুমাত্র রিড এপিআই পুরোনো নামে ফিরে যায়। রাইট এপিআই ফিরে যায় না। যদি সিস্টেম প্রপার্টিটি রাইটেবল হয়, তবে আপনি এটির নাম পরিবর্তন করতে পারবেন না।