این صفحه یک روش متعارف برای افزودن یا تعریف ویژگیهای سیستم در اندروید، همراه با دستورالعملهایی برای بازسازی ویژگیهای سیستم موجود ارائه میدهد. اطمینان حاصل کنید که از دستورالعملها هنگام بازسازی استفاده میکنید، مگر اینکه مشکل سازگاری قوی داشته باشید که خلاف آن را دیکته کند.
مرحله 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 خوانده و نوشته می شوند |
دامنه دسترسی به ویژگی های سیستم را تا حد امکان محدود کنید. در گذشته، دسترسی گسترده منجر به شکستن برنامه و آسیبپذیریهای امنیتی شده است. هنگام تعیین محدوده به سؤالات زیر توجه کنید:
- آیا این ویژگی سیستم باید حفظ شود؟ (اگر چنین است، چرا؟)
- کدام فرآیند باید دسترسی خواندن به این ویژگی داشته باشد؟
- کدام فرآیند باید دسترسی نوشتن به این ویژگی داشته باشد؟
از سوالات قبلی و درخت تصمیم زیر به عنوان ابزاری برای تعیین محدوده مناسب برای دسترسی استفاده کنید.
شکل 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
( libc
)، android-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
را به یک propstring
تبدیل کنید. شما فقط می توانید نام را تغییر دهید.دوم، فقط API خوانده شده به نام قدیمی باز می گردد. نوشتن API به عقب نمی افتد. اگر sysprop قابل نوشتن باشد، نمی توانید نام آن را تغییر دهید.