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

تقدّم هذه الصفحة طريقة أساسية لإضافة سمات النظام أو تحديدها في Android، مع إرشادات لإعادة صياغة سمات النظام الحالية. احرص على استخدام الإرشادات عند إعادة التشكيل، ما لم تكن لديك مشكلة توافق قوية تفرض خلاف ذلك.

الخطوة 1: تعريف خاصية النظام

عند إضافة موقع إلكتروني على النظام، حدِّد اسمًا للموقع واربطه باستخدام سياق خاصية SELinux. إذا لم يكن هناك سياق حالي مناسب، أنشئ سياقًا جديدًا. يُستخدَم الاسم عند الوصول إلى الموقع. العقار يستخدم السياق للتحكم في إمكانية الوصول من حيث SELinux. يمكن أن تكون الأسماء أي سلسلة، ولكن تقترح AOSP اتباع تنسيق منظم لتوضيحها.

اسم الموقع

استخدِم هذا التنسيق مع حالة snake_case:

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

استخدِم "" (تم حذفها) أو ro (للخصائص التي يتم ضبطها مرة واحدة فقط) أو persist (للخصائص التي تظل محفوظة بعد عمليات إعادة التشغيل) للعنصر prefix.

المحاذير

لا تستخدِم ro إلا عندما تكون متأكدًا من أنّك لن تحتاج إلى prefix ليكون قابلاً للكتابة في المستقبل. ** لا تحدّد البادئة ro.** بدلاً من ذلك، يمكنك الاعتماد على سياسة الأمان لجعل 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 من سطر أوامر kernel boot
سمات sysprops التي تحدِّد إصدارًا build
مرتبط بالاتصال الهاتفي telephony
محتوى صوتي audio
ذو صلة بالرسومات graphics
محتوى متعلّق بـ vold vold

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

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

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

  • type هو عنصر اختياري يوضّح نوع سمة النظام أو الغرض منها. على سبيل المثال، بدلاً من تسمية sysrep 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 للتعبير عن القيمة true أو السمة false أو القيمة 0 للتعبير عن القيمة false
عدد صحيح عدد صحيح 64 بت بعلامة
عدد صحيح غير موقَّع عدد صحيح 64 بت غير موقَّع
مزدوجة نقطة عائمة ذات دقة مزدوجة
سلسلة أي سلسلة UTF-8 صالحة
تعداد يمكن أن تكون قيمها أي سلسلة UTF-8 صالحة بدون مسافات بيضاء.
قائمة بالعناصر المذكورة أعلاه يتم استخدام الفاصلة (,) كمحدِّد
تم تخزين قائمة الأعداد الصحيحة [1, 2, 3] على أنّها 1,2,3.

يتم تخزين جميع المواقع كسلسلة من الأحرف. يمكنك فرض النوع من خلال تحديده كملف property_contexts. لمزيد من المعلومات، يُرجى الاطّلاع على property_contextsproperty_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".

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

بالنسبة إلى خصائص النظام الثابتة، يجب تحديد كل منها بشكل رسمي كواجهة برمجة تطبيقات واستخدام واجهة برمجة التطبيقات. للوصول إلى خاصية النظام، كما هو موضح في الخطوة السادسة:

الخطوة 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 هما دالتَا ملف ملتف. استخدِم دوال syssys لنظام التشغيل libbase، إذا كان ذلك ممكنًا. إنّه أكثر ملاءمة، ويمكن للثنائيات المضيفة استخدام دوال 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 الخاصة بالبائع في 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" يمكنك تغيير الاسم فقط.

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