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

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

وضَع قواعد "عدم السماح مطلقًا" في ملف 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 للمواقع الإلكترونية المدرَجة في القائمة).

تأكَّد من أنّ كل إدخال له النوع المخصّص له كلما أمكن ذلك، لأنّ السمة 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، يعمل النظام والمورد، ويمكن تحديث أقسام المنتج بشكل مستقل عن بعضها البعض. مع في ما يلي إصدار رئيسي، يتم تقسيم بعض أجزاء نظام التشغيل إلى وحدات كوحدات قابلة للتحديث (في APEXes) أو 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}

أوامر 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

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

يوفّر libc وlibbase وlibcutils وظائف خصائص نظام C++. libc واجهة برمجة التطبيقات الأساسية، في حين تستخدم الدالتان libbase وlibcutils والبرامج الأخرى. استخدِم دوال syssys لنظام التشغيل libbase، إذا كان ذلك ممكنًا. إنّه أكثر ملاءمة، ويمكن للثنائيات المضيفة استخدام دوال libbase. لمزيد من المعلومات، التفاصيل، يُرجى الاطّلاع على sys/system_properties.h (libcandroid-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 فقط إلى الاسم القديم. لا تقوم واجهة برمجة التطبيقات write التراجع. إذا كان sysrep قابل للكتابة، لا يمكنك إعادة تسميته.