إضافة خصائص النظام

توفّر هذه الصفحة طريقة أساسية لإضافة خصائص النظام أو تحديدها في 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
syspros من kernel cmdline boot
لعناصر النظام التي تحدد أي إصدار build
مرتبط بالاتصال الهاتفي telephony
مرتبط بالصوت audio
ذو صلة بالرسومات graphics
ذات صلة بـ vold vold

يوضّح ما يلي استخدام name وtype في مثال التعبير العادي السابق.

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

  • يحدِّد name خاصية نظام داخل مجموعة.

  • type هي عنصر اختياري يوضّح نوع سمة النظام أو الغرض منها. على سبيل المثال، بدلاً من تسمية syssys بـ 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.

Type

يمكن أن يكون نوع الموقع واحدًا مما يلي كما هو موضّح في الجدول.

Type التعريف
قيمة منطقية true أو 1 للتعبير عن القيمة true أو السمة false أو القيمة 0 للتعبير عن القيمة false
عدد صحيح عدد صحيح 64 بت بعلامة
عدد صحيح غير موقَّع عدد صحيح 64 بت غير موقَّع
مزدوجة نقطة عائمة ذات دقة مزدوجة
سلسلة أي سلسلة UTF-8 صالحة
تعداد يمكن أن تكون القيم أي سلسلة 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

عند الوصول إلى sysbro، يتحكّم 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;

عليك وضع قواعد NOTallow في ملف 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.

أخيرًا، اربط خاصية النظام بسياق الموقع. ويضمن ذلك أنّ إذن الوصول الممنوح والقواعد NOTallow التي يتم تطبيقها على سياقات المواقع يتم تطبيقها على المواقع الفعلية. لإجراء ذلك، أضِف إدخالاً إلى ملف 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}

أوامر getPro وsetPro Shell

يمكنك استخدام أمر واجهة الأوامر getprop أو setprop على التوالي لقراءة الخصائص أو كتابتها. لمزيد من التفاصيل، يمكنك استدعاء getprop --help أو setprop --help.

$ adb shell getprop ro.vndk.version
$
$ adb shell setprop security.perf_harden 0

Sysbro كواجهة برمجة تطبيقات لـ C++/Java/Rust

ويمكنك عند استخدام sys أنشطة واجهة برمجة التطبيقات تحديد خصائص النظام واستخدام واجهة برمجة تطبيقات ملموسة ومكتوبة. يؤدي ضبط 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

عند الإمكان، استخدِم Sysbro كواجهة برمجة تطبيقات، على الرغم من توفر دوال C/C++ أو Rust منخفضة المستوى أو طرق Java منخفضة المستوى.

يوفّر libc وlibbase وlibcutils وظائف خصائص نظام C++. تتضمن الدالة libc واجهة برمجة التطبيقات الأساسية، بينما تُعتبر الدالتان libbase وlibcutils برامج تضمين. استخدِم دوال libbase sysتناسب على مستوى المجال، إذا أمكن، لأنّها الأكثر ملاءمة، ويمكن للبرامج الثنائية المضيفة استخدام دوال 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.

منذ مشروع 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 للمورّد باللغة المرجانية.

في ملف 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.

الملحق: إعادة تسمية المواقع الحالية

عندما يكون عليك إيقاف أحد المواقع نهائيًا والانتقال إلى موقع جديد، استخدِم Sysbro كواجهات برمجة تطبيقات لإعادة تسمية مواقعك الحالية. يحافظ ذلك على التوافق مع الأنظمة القديمة من خلال تحديد كل من الاسم القديم واسم الموقع الجديد. ويمكنك تحديدًا ضبط الاسم القديم من خلال الحقل 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);

لاحظ المحاذير التالية:

  • أولاً، لا يمكنك تغيير نوع sysrep. على سبيل المثال، لا يمكنك تحويل إحدى لوازم "int" إلى لوازم string، بل يمكنك فقط تغيير الاسم.

  • ثانيًا، تعود واجهة برمجة التطبيقات read فقط إلى الاسم القديم. لا تتراجع واجهة برمجة تطبيقات الكتابة. إذا كان sysrep قابل للكتابة، لا يمكنك إعادة تسميته.