בדף הזה מפורטת שיטה קנונית להוספה או להגדרה של מאפייני מערכת ב-Android, עם הנחיות לשיפור מבנה של מאפייני מערכת קיימים. חשוב להשתמש בהנחיות כשמבצעים רפאקציה, אלא אם יש בעיה משמעותית של תאימות שמחייבת אחרת.
שלב 1: מגדירים את מאפיין המערכת
כשמוסיפים מאפיין מערכת, צריך לבחור שם למאפיין ולשייך אותו להקשר של מאפיין SELinux. אם אין הקשר קיים מתאים, צריך ליצור הקשר חדש. השם משמש לגישה לנכס, וההקשר של הנכס משמש לבקרת הנגישות מבחינת SELinux. השמות יכולים להיות כל מחרוזת, אבל מומלץ להשתמש בפורמט מובנה כדי שהם יהיו ברורים.
שם הנכס
צריך להשתמש בפורמט הזה עם אותיות רישיות ב-snake_case:
[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]
עבור האלמנט prefix
, אפשר להשתמש ב-"" (לא מצוין), ב-ro
(לנכסים שמוגדרים רק פעם אחת) או ב-persist
(לנכסים שנשמרים אחרי הפעלות מחדש).
נקודות שצריך לשים לב אליהן:
צריך להשתמש ב-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 | bluetooth |
sysprops מ-cmdline של הליבה | boot |
sysprops שמזהים build | build
|
קשור לטלפוניה | telephony |
קשור לאודיו | audio |
גרפיקה קשורה | graphics |
קשור ל-vold | vold |
בהמשך מוסבר איך משתמשים ב-name
וב-type
בדוגמה הקודמת לביטוי רגולרי.
[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]
name
מזהה מאפיין מערכת בתוך קבוצה.type
הוא רכיב אופציונלי שמבהיר את הסוג או את הכוונה של מאפיין המערכת. לדוגמה, במקום לתת למאפיין sysprop את השם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 ביט |
כפול | נקודה צפה (floating-point) בעלת דיוק כפול |
מחרוזת | כל מחרוזת 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: הוספה אל 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
'.
לבסוף, משייכים נכס מערכת להקשר של הנכס. כך מוודאים שהגישה שמוענקת וכללי 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: קביעת דרישות היציבות
יציבות היא היבט נוסף של מאפייני המערכת, והיא שונה מנגישוּת. היציבות מתייחסת לשאלה אם אפשר לשנות נכס מערכת בעתיד (למשל, לשנות את השם שלו או אפילו להסיר אותו). זה חשוב במיוחד כי מערכת ההפעלה Android הופכת למבוססת-מודולים. בעזרת Treble, אפשר לעדכן את המחיצות של המערכת, הספק והמוצר בנפרד. ב-Mainline, חלקים מסוימים במערכת ההפעלה מחולקים למודולים שניתן לעדכן (ב-APEX או ב-APK).
אם מאפיין מערכת מיועד לשימוש בחלקים שונים של תוכנה שניתן לעדכן, למשל במחיצות של מערכת ושל ספק, הוא חייב להיות יציב. עם זאת, אם הוא משמש רק בתוך, למשל, מודול Mainline ספציפי, אפשר לשנות את השם, הסוג או ההקשרים של הנכס שלו, ואפילו להסיר אותו.
כדי לקבוע את היציבות של מאפיין מערכת, כדאי לשאול את השאלות הבאות:
- האם שותפים אמורים להגדיר את מאפיין המערכת הזה (או להגדיר אותו באופן שונה לכל מכשיר)? אם כן, הוא חייב להיות יציב.
- האם מאפיין המערכת הזה שמוגדר ב-AOSP מיועד לכתיבה או לקריאה מקוד (לא מתהליך) שנמצא במחיצות שאינן של המערכת, כמו
vendor.img
אוproduct.img
? אם כן, הוא חייב להיות יציב. - האם יש גישה לנכס המערכת הזה במודולים של Mainline או במודול של Mainline ובחלק שלא ניתן לעדכון בפלטפורמה? אם כן, הוא חייב להיות יציב.
למאפייני המערכת היציבים, מגדירים כל אחד מהם באופן רשמי כ-API ומשתמשים ב-API כדי לגשת למאפיין המערכת, כפי שמוסבר בשלב 6.
שלב 5: הגדרת מאפיינים בזמן ה-build
הגדרת מאפיינים בזמן ה-build באמצעות משתני 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}
פקודות shell של 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++, 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);
מידע נוסף זמין במאמר הטמעת מאפייני מערכת כממשקי API.
פונקציות ושיטות של נכסים ברמה נמוכה ב-C/C++, Java ו-Rust
כשאפשר, כדאי להשתמש ב-Sysprop כ-API גם אם יש לכם גישה לפונקציות ברמה נמוכה של C/C++ או Rust, או לשיטות ברמה נמוכה של Java.
libc
, libbase
ו-libcutils
מציעים פונקציות של מאפייני מערכת ב-C++. ב-libc
נמצא ה-API הבסיסי, ואילו הפונקציות libbase
ו-libcutils
הן פונקציות עטיפה. אם אפשר, כדאי להשתמש בפונקציות sysprop של libbase
. הן הכי נוחות, וקבצים בינאריים של המארח יכולים להשתמש בפונקציות libbase
. למידע נוסף, אפשר לעיין במאמרים sys/system_properties.h
(libc
), android-base/properties.h
(libbase
) ו-cutils/properties.h
(libcutils
).
בכיתה android.os.SystemProperties
יש שיטות לנכסי מערכת של Java.
המודול rustutils::system_properties
מציע פונקציות וסוגים של מאפייני מערכת ב-Rust.
נספח: הוספת נכסים ספציפיים לספק
שותפים (כולל גוגלרים שעובדים בהקשר של פיתוח 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 ו-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 as APIs כדי לשנות את השם של הנכסים הקיימים. כך אפשר לשמור על תאימות לאחור, על ידי ציון השם הקודם וגם השם החדש של הנכס. באופן ספציפי, אפשר להגדיר את השם הקודם לפי השדה legacy_prop_name
בקובץ .sysprop
. ה-API שנוצר מנסה לקרוא את 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
. אפשר לשנות רק את השם.שנית, רק ה-API לקריאה חוזר לשם הקודם. ממשק ה-API לכתיבה לא עובר לחלופה. אם sysprop הוא פרמטר שאפשר לשנות, אי אפשר לשנות את השם שלו.