ویژگی های سیستم را اضافه کنید

این صفحه یک روش متعارف برای افزودن یا تعریف ویژگی‌های سیستم در اندروید، همراه با دستورالعمل‌هایی برای بازسازی ویژگی‌های سیستم موجود ارائه می‌دهد. اطمینان حاصل کنید که از دستورالعمل‌ها هنگام بازسازی استفاده می‌کنید، مگر اینکه مشکل سازگاری قوی داشته باشید که خلاف آن را دیکته کند.

مرحله 1: ویژگی سیستم را تعریف کنید

هنگامی که یک ویژگی سیستم را اضافه می کنید، نامی را برای ویژگی تعیین کنید و آن را با زمینه ویژگی 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 از هسته cmdline boot
sysprops که یک ساخت را شناسایی می کنند build
مربوط به تلفن telephony
مربوط به صوتی audio
مربوط به گرافیک graphics
مربوط به جلد vold

موارد زیر استفاده از name و type را در مثال regex قبلی تعریف می‌کند.

[{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 همان معنایی دارند که برای نمونه regex قبلی تعریف شده است. به عنوان مثال، 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 خوانده و نوشته می شوند

دامنه دسترسی به ویژگی های سیستم را تا حد امکان محدود کنید. در گذشته، دسترسی گسترده منجر به شکستن برنامه و آسیب‌پذیری‌های امنیتی شده است. هنگام تعیین محدوده به سؤالات زیر توجه کنید:

  • آیا این ویژگی سیستم باید حفظ شود؟ (اگر چنین است، چرا؟)
  • کدام فرآیند باید دسترسی خواندن به این ویژگی داشته باشد؟
  • کدام فرآیند باید دسترسی نوشتن به این ویژگی داشته باشد؟

از سوالات قبلی و درخت تصمیم زیر به عنوان ابزاری برای تعیین محدوده مناسب برای دسترسی استفاده کنید.

Decision tree for determining the scope of access

شکل 1. درخت تصمیم برای تعیین دامنه دسترسی به خصوصیات سیستم

مرحله 3: اضافه کردن به سیستم/سیستم سیاست

هنگام دسترسی به sysprop، SELinux دسترسی فرآیندها را کنترل می کند. بعد از اینکه تعیین کردید چه سطحی از دسترسی لازم است، زمینه‌های ویژگی را تحت system/sepolicy ، به همراه قوانین اضافی اجازه و هرگز اجازه نمی‌دهید در مورد آنچه که فرآیندها مجاز به خواندن یا نوشتن هستند (و نمی‌شوند) تعریف کنید.

ابتدا زمینه ویژگی را در فایل 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 به یک دامنه خاص محدود شده است، قوانین 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 ."

در نهایت، یک ویژگی سیستم را با زمینه ویژگی مرتبط کنید. این تضمین می‌کند که دسترسی اعطا شده و قوانین 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: الزامات پایداری را تعیین کنید

پایداری جنبه دیگری از ویژگی های سیستم است و با دسترسی متفاوت است. ثبات در مورد این است که آیا می توان یک ویژگی سیستم را در آینده تغییر داد (مثلاً تغییر نام داد یا حتی حذف کرد). این امر به ویژه با ماژولار شدن سیستم عامل اندروید بسیار مهم است. با Treble، سیستم، فروشنده و پارتیشن های محصول را می توان مستقل از یکدیگر به روز کرد. با Mainline، برخی از بخش‌های سیستم عامل به عنوان ماژول‌های قابل به‌روزرسانی (در APEX یا APK) مدولار می‌شوند.

اگر یک ویژگی سیستم برای استفاده در بخش‌های نرم‌افزاری قابل به‌روزرسانی باشد، برای مثال در پارتیشن‌های سیستم و فروشنده، باید پایدار باشد. با این حال، اگر فقط در مثلاً یک ماژول Mainline خاص استفاده می‌شود، می‌توانید نام، نوع یا زمینه‌های ویژگی آن را تغییر دهید و حتی آن را حذف کنید.

برای تعیین پایداری ویژگی سیستم سوالات زیر را بپرسید:

  • آیا این ویژگی سیستم برای پیکربندی توسط شرکا در نظر گرفته شده است (یا پیکربندی متفاوتی برای هر دستگاه)؟ اگر بله، باید پایدار باشد.
  • آیا این ویژگی سیستم تعریف شده توسط AOSP برای نوشتن یا خواندن از روی کد (نه فرآیند) که در پارتیشن های غیر سیستمی مانند vendor.img یا product.img وجود دارد، در نظر گرفته شده است؟ اگر بله، باید پایدار باشد.
  • آیا این ویژگی سیستم از طریق ماژول های Mainline قابل دسترسی است یا از طریق یک ماژول Mainline و بخش غیرقابل به روز رسانی پلت فرم؟ اگر بله، باید پایدار باشد.

برای ویژگی های سیستم پایدار، هر کدام را به طور رسمی به عنوان یک API تعریف کنید و از API برای دسترسی به ویژگی سیستم استفاده کنید، همانطور که در مرحله 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

فایل‌های اسکریپت 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}

دستورات پوسته getprop و setprop

شما می توانید به ترتیب از دستورات پوسته getprop یا setprop برای خواندن یا نوشتن خواص استفاده کنید. برای جزئیات بیشتر، getprop --help یا setprop --help را فراخوانی کنید.

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

Sysprop به عنوان API برای C++/Java/Rust

با sysprop به عنوان API، می توانید ویژگی های سیستم را تعریف کنید و از API تولید شده خودکار استفاده کنید که عینی و تایپ شده است. تنظیم scope با Public همچنین APIهای تولید شده را برای ماژول ها در سراسر مرزها در دسترس قرار می دهد و پایداری API را تضمین می کند. در اینجا نمونه ای از یک فایل .sysprop ، یک ماژول Android.bp و کدهای C++، جاوا و 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);

برای اطلاعات بیشتر، به پیاده سازی ویژگی های سیستم به عنوان API مراجعه کنید.

توابع و روش های ویژگی های سطح پایین C/C++، جاوا و Rust

در صورت امکان، از Sysprop به عنوان API استفاده کنید، حتی اگر توابع سطح پایین C/C++ یا Rust یا روش‌های سطح پایین جاوا در دسترس شما هستند.

libc ، libbase و libcutils توابع ویژگی سیستم C++ را ارائه می دهند. libc دارای API اساسی است، در حالی که توابع libbase و libcutils wrapper هستند. در صورت امکان، از توابع libbase sysprop استفاده کنید. آنها راحت ترین هستند و باینری های میزبان می توانند از توابع libbase استفاده کنند. برای جزئیات بیشتر، sys/system_properties.h ( libcandroid-base/properties.h ( libbase ) و cutils/properties.h ( libcutils ) را ببینید.

کلاس android.os.SystemProperties متدهای ویژگی سیستم جاوا را ارائه می دهد.

ماژول rustutils::system_properties توابع و انواع ویژگی های Rust system را ارائه می دهد.

پیوست: ویژگی های خاص فروشنده را اضافه کنید

شرکا (از جمله کارمندان 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 و ویژگی_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 دسترسی داشته باشند.

ضمیمه: تغییر نام ویژگی های موجود

هنگامی که باید یک ویژگی را منسوخ کنید و به یک ویژگی جدید بروید، از Sysprop به عنوان API برای تغییر نام ویژگی های موجود خود استفاده کنید. این کار با تعیین نام قدیمی و نام ویژگی جدید سازگاری با عقب را حفظ می کند. به طور خاص، می‌توانید نام قدیمی را با فیلد legacy_prop_name در فایل .sysprop . تنظیم کنید. 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 را تغییر دهید. به عنوان مثال، شما نمی توانید یک prop int را به یک prop string تبدیل کنید. شما فقط می توانید نام را تغییر دهید.

  • دوم، فقط API خوانده شده به نام قدیمی باز می گردد. نوشتن API به عقب نمی افتد. اگر sysprop قابل نوشتن باشد، نمی توانید نام آن را تغییر دهید.