توفّر هذه الصفحة طريقة أساسية لإضافة خصائص النظام أو تحديدها في Android، مع إرشادات لإعادة تصميم خصائص النظام الحالية. احرص على استخدام الإرشادات عند إعادة تصميم الرمز، إلا إذا كانت لديك مشكلة كبيرة في التوافق تفرض عليك خلاف ذلك.
الخطوة 1: تحديد سمة النظام
عند إضافة سمة نظام، حدِّد اسمًا للسمة واربطها بسياق سمة SELinux. إذا لم يكن هناك سياق حالي مناسب، أنشئ سياقًا جديدًا. يُستخدم الاسم عند الوصول إلى السمة، ويُستخدم سياق السمة للتحكّم في إمكانية الوصول من حيث SELinux. يمكن أن تكون الأسماء أي سلسلة، ولكن تنصح AOSP باتّباع تنسيق منظَّم لجعلها واضحة.
اسم الموقع
استخدِم هذا التنسيق مع حالة snake_case:
[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]
استخدِم إما "" (تم الحذف)، أو ro
(للمواقع الإلكترونية التي يتم ضبطها مرة واحدة فقط)، أو persist
(للمواقع الإلكترونية التي تظل محفوظة بعد إعادة التشغيل) للعنصر prefix
.
المحاذير
استخدِم 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 |
sysprops من سطر أوامر النواة | boot |
سمات النظام التي تحدّد إصدارًا | build
|
ذات صلة بالاتصال الهاتفي | telephony |
محتوى صوتي ذو صلة | audio |
المحتوى المرتبط بالرسومات | graphics |
vold related | 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
: استخدِم هذه السمة إذا كانت سمة نظام لقيمة المهلة بوحدة الملّي ثانية.
أمثلة:
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
يُفضّل استخدام أسماء مثل vold_config_prop
بدلاً من exported_vold_prop
أو vold_vendor_writable_prop
.
النوع
يمكن أن يكون نوع الموقع واحدًا مما يلي كما هو موضّح في الجدول.
النوع | التعريف |
---|---|
قيمة منطقية | true أو 1 للإجابة الصحيحة، false أو 0 للإجابة الخاطئة |
عدد صحيح | عدد صحيح 64 بت موقّع |
عدد صحيح غير موقّع | عدد صحيح غير موقّع 64 بت |
مزدوجة | النقطة العائمة ذات الدقة المزدوجة |
سلسلة | أي سلسلة UTF-8 صالحة |
enum | يمكن أن تكون القيم أي سلسلة UTF-8 صالحة بدون مسافات بيضاء |
قائمة ما ورد أعلاه | يتم استخدام فاصلة (, ) كعنصر فاصليتم تخزين قائمة الأعداد الصحيحة [1, 2, 3] على النحو 1,2,3 |
يتم تخزين جميع السمات داخليًا كسلاسل. يمكنك فرض النوع من خلال تحديده كملف property_contexts
. لمزيد من المعلومات، يُرجى الاطّلاع على
property_contexts
في الخطوة 3.
الخطوة 2: تحديد مستويات الوصول المطلوبة
هناك أربعة وحدات ماكرو مساعدة تحدّد إحدى السمات.
نوع تسهيل الاستخدام | المعنى |
---|---|
system_internal_prop |
الخصائص المستخدَمة في /system فقط |
system_restricted_prop |
السمات التي تتم قراءتها خارج /system ، ولكن لا تتم كتابتها |
system_vendor_config_prop |
السمات التي تتم قراءتها خارج /system ، ولا يكتبها سوى vendor_init |
system_public_prop |
السمات التي تتم قراءتها وكتابتها خارج /system |
يجب أن يكون نطاق الوصول إلى خصائص النظام محدودًا قدر الإمكان. في السابق، كان الوصول الواسع النطاق يؤدي إلى حدوث مشاكل في التطبيقات وثغرات أمنية. ضَع في اعتبارك الأسئلة التالية عند تحديد النطاق:
- هل يجب أن تبقى قيمة سمة النظام هذه محفوظة؟ (إذا كان الأمر كذلك، ما السبب؟)
- ما هي العملية التي يجب أن يكون لديها إذن قراءة هذا الموقع؟
- ما هي العملية التي يجب أن يكون لديها إذن الكتابة إلى هذه السمة؟
استخدِم الأسئلة السابقة وشجرة القرارات التالية كأدوات لتحديد نطاق مناسب للوصول.
الشكل 1. شجرة القرار لتحديد نطاق الوصول إلى خصائص النظام
الخطوة 3: الإضافة إلى system/sepolicy
عند الوصول إلى sysprop، يتحكّم SELinux في إمكانية وصول العمليات. بعد تحديد مستوى إمكانية الوصول المطلوب، حدِّد سياقات الخصائص ضمن system/sepolicy
، بالإضافة إلى قواعد 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)
ثانيًا، امنح إذن الوصول للقراءة و (أو) الكتابة إلى سياق الموقع. استخدِم وحدتَي الماكرو 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;
ضَع قواعد neverallow في ملف system/sepolicy/private/{domain}.te
إذا كانت قاعدة neverallow مرتبطة بنطاق معيّن. بالنسبة إلى قواعد 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
".
أخيرًا، اربط سمة نظام بسياق السمة. ويضمن ذلك تطبيق أذونات الوصول وقواعد neverallow التي يتم تطبيقها على سياقات الخصائص على الخصائص الفعلية. لإجراء ذلك، أضِف إدخالاً إلى ملف 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
لسمات القوائم.)
تأكَّد من أنّ كل إدخال يتضمّن نوعه المحدّد كلما أمكن ذلك، لأنّ type
يتم فرضه عند ضبط property
. يوضّح المثال التالي كيفية كتابة عملية ربط:
# 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
.
الخطوة 4: تحديد متطلبات الثبات
الثبات هو جانب آخر من جوانب خصائص النظام، وهو يختلف عن إمكانية الوصول. تشير الثباتية إلى ما إذا كان يمكن تغيير إحدى خصائص النظام (على سبيل المثال، إعادة تسميتها أو حتى إزالتها) في المستقبل. ويكتسب ذلك أهمية خاصة مع تحوّل نظام التشغيل Android إلى نظام نموذجي. باستخدام Treble، يمكن تعديل أقسام النظام والمورّد والمنتج بشكل مستقل عن بعضها البعض. باستخدام Mainline، يتم تقسيم بعض أجزاء نظام التشغيل إلى وحدات قابلة للتحديث (في حِزم APEX أو ملفات APK).
إذا كانت إحدى خصائص النظام مخصّصة للاستخدام في جميع أجزاء البرنامج القابلة للتحديث، مثل الأقسام الخاصة بالنظام والمورّد، يجب أن تكون ثابتة. ومع ذلك، إذا تم استخدامها في نطاق معيّن، مثل وحدة Mainline معيّنة، يمكنك تغيير اسمها أو نوعها أو سياقات خصائصها، ويمكنك حتى إزالتها.
اطرح الأسئلة التالية لتحديد ثبات إحدى خصائص النظام:
- هل من المفترض أن يضبط الشركاء خاصية النظام هذه (أو أن يتم ضبطها بشكل مختلف لكل جهاز)؟ إذا كانت الإجابة "نعم"، يجب أن تكون ثابتة.
- هل من المفترض أن تتم كتابة سمة النظام المحدّدة في AOSP أو قراءتها من الرمز (وليس العملية) المتوفّر في الأقسام غير التابعة للنظام، مثل
vendor.img
أوproduct.img
؟ إذا كانت الإجابة "نعم"، يجب أن تكون ثابتة. - هل يتم الوصول إلى سمة النظام هذه في جميع وحدات Mainline أو في وحدة Mainline والجزء غير القابل للتحديث من النظام الأساسي؟ إذا كانت الإجابة "نعم"، يجب أن تكون ثابتة.
بالنسبة إلى خصائص النظام الثابتة، حدِّد كل خاصية رسميًا على أنّها واجهة برمجة تطبيقات، واستخدِم واجهة برمجة التطبيقات للوصول إلى خاصية النظام، كما هو موضّح في الخطوة 6.
الخطوة 5: ضبط السمات في وقت الإنشاء
ضبط الخصائص في وقت الإنشاء باستخدام متغيرات ملف makefile من الناحية الفنية، تكون القيم مضمّنة في {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
.
الخطوة 6: الوصول إلى السمات في وقت التشغيل
يمكن قراءة السمات وكتابتها في وقت التشغيل.
نصوص Init البرمجية
يمكن لملفات النصوص البرمجية الأولية (عادةً ملفات *.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}
أوامر shell الخاصة بـ getprop وsetprop
يمكنك استخدام أوامر shell getprop
أو setprop
، على التوالي، لقراءة الخصائص أو كتابتها. لمزيد من التفاصيل، استخدِم getprop --help
أو setprop --help
.
$ adb shell getprop ro.vndk.version
$
$ adb shell setprop security.perf_harden 0
Sysprop كواجهة برمجة تطبيقات للغة C++/Java/Rust
باستخدام 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
استخدِم Sysprop كواجهة برمجة تطبيقات كلما أمكن ذلك، حتى إذا كانت تتوفّر لك وظائف C/C++ أو Rust ذات المستوى المنخفض أو طرق Java ذات المستوى المنخفض.
توفّر libc
وlibbase
وlibcutils
دوال سمات نظام C++. libc
تحتوي على واجهة برمجة التطبيقات الأساسية، بينما الدالتان 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.
الملحق: إضافة سمات خاصة بالمورّد
يريد الشركاء (بما في ذلك موظفو Google الذين يعملون في سياق تطوير هواتف Pixel) تحديد خصائص نظام خاصة بالأجهزة (أو خاصة بالجهاز).
الخصائص الخاصة بالمورّد هي خصائص مملوكة للشركاء وتكون فريدة لأجهزتهم أو أجهزتهم فقط، وليس للمنصة. بما أنّ هذه الأذونات تعتمد على الأجهزة، من المفترض استخدامها ضمن القسمَين /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_red
persist.vendor.faceauth.use_disk_cache
ro.odm.hardware.platform
يجب أن تبدأ جميع سياقات سمات المورّد بالقيمة vendor_
. ويتم ذلك أيضًا لأغراض التوافق. في ما يلي بعض الأمثلة:
vendor_radio_prop
.vendor_faceauth_prop
.vendor_usb_prop
.
يتحمّل المورّد مسؤولية تسمية السمات والحفاظ عليها، لذا اتّبِع التنسيق المقترَح في الخطوة 2، بالإضافة إلى متطلبات مساحات الأسماء الخاصة بالمورّد.
قواعد SEPolicy وproperty_contexts الخاصة بالمورّد
يمكن تحديد خصائص المورّد باستخدام وحدة ماكرو vendor_internal_prop
. ضَع القواعد الخاصة بالمورّد والتي تحدّدها في الدليل BOARD_VENDOR_SEPOLICY_DIRS
.
على سبيل المثال، لنفترض أنّك تحدّد خاصية faceauth خاصة ببائع في Coral.
في الملف BoardConfig.mk
(أو في أي ملف BoardConfig.mk
مضمّن)، ضَع ما يلي:
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 كواجهات برمجة تطبيقات لإعادة تسمية السمات الحالية. ويحافظ ذلك على التوافق مع الإصدارات القديمة من خلال تحديد كلّ من الاسم القديم واسم السمة الجديدة. على وجه التحديد، يمكنك ضبط الاسم القديم باستخدام الحقل legacy_prop_name
في الملف .sysprop
. تحاول واجهة برمجة التطبيقات التي تم إنشاؤها قراءة prop_name
، وتستخدم legacy_prop_name
إذا لم يكن 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
، بل يمكنك تغيير الاسم فقط.ثانيًا، لا يتم الرجوع إلى الاسم القديم إلا في واجهة برمجة التطبيقات للقراءة. لا يمكن الرجوع إلى واجهة برمجة التطبيقات الخاصة بالكتابة. إذا كان sysprop قابلاً للكتابة، لا يمكنك إعادة تسميته.