הוספת מאפייני מערכת

הדף הזה מספק שיטה קנונית להוספה או להגדרה של מאפייני מערכת ב-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 bluetooth
syspros מ-kernel של cmdline boot
מערכות build שמזהים גרסת build build
קשור לטלפוניה telephony
קשורים לאודיו audio
קשורים לגרפיקה graphics
קשור ל-vold vold

בהמשך מוגדר השימוש ב-name וב-type בביטוי הרגולרי הקודם דוגמה.

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

  • name מזהה נכס מערכת בקבוצה.

  • type הוא רכיב אופציונלי שמבהיר את הסוג או הכוונה של ההמרה מאפיין מערכת. לדוגמה, במקום לתת ל-syspro את השם audio.awesome_feature_enabled או רק audio.awesome_feature, משנים את השם ל- audio.awesome_feature.enabled כדי לשקף את הסוג ואת ה-Intent של מאפיין המערכת.

אין כלל ספציפי לגבי הסוג חייב להיות; אלה השימושים המלצות:

  • enabled: יש להשתמש באפשרות הזו אם הסוג הוא מאפיין מערכת בוליאני שמשמש להפעיל או להשבית את התכונה.
  • config: משתמשים באפשרות הזו אם הכוונה היא להבהיר שמאפיין המערכת לא מייצג מצב דינמי של המערכת. הוא מייצג ערך מוגדר מראש (לדוגמה, ערך לקריאה בלבד).
  • List: יש להשתמש באפשרות הזו אם מדובר בנכס מערכת שהערך שלו הוא רשימה.
  • Timeoutmillis: יש להשתמש במאפיין אם זהו מאפיין מערכת של ערך של זמן קצוב לתפוגה ביחידות של אלפיות שנייה

לדוגמה:

  • 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 לציון True, false או 0 ל-False
מספר שלם מספר שלם חתום של 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: הוספה למערכת/למדיניות

בעת גישה ל-syspro, 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)

שלישית, להוסיף כמה כללים אף פעם כדי לצמצם עוד יותר את הנגישות בהיקף של המאקרו. לדוגמה, נניח שהשתמשתם ב- system_restricted_prop כי הספק צריך לקרוא את מאפייני המערכת תהליכים. אם גישת הקריאה לא נדרשת על ידי כל התהליכים של הספק נדרש רק על ידי קבוצה מסוימת של תהליכים (כמו vendor_init), אסור את התהליכים לספק שלא זקוקים להרשאת קריאה.

צריך להשתמש בתחביר הבא כדי להגביל גישת כתיבה וקריאה:

כדי להגביל את גישת הכתיבה:

neverallow [domain] [context]:property_service set;

כדי להגביל את גישת הקריאה:

neverallow [domain] [context]:file no_rw_file_perms;

יש לכלול כללים של אף פעם בקובץ system/sepolicy/private/{domain}.te אם אף פעם לא קשור לדומיין ספציפי. לכללים רחבים יותר של מתן הרשאה, משתמשים דומיינים כלליים, כמו אלה, היכן שהדבר רלוונטי:

  • 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 הופכת למודולרית. בעזרת טרבל, המערכת מספק ומחיצות מוצרים יכולים להתעדכן בנפרד. ב- ראשי תיבות, חלקים מסוימים במערכת ההפעלה עוברים מודולציה כמודולים שניתנים לעדכון (ב-APEX או חבילות APK).

אם מאפיין מערכת משמש לשימוש בחלקי תוכנה שניתנים לעדכון, לדוגמה בין מחיצות המערכת והספק, היא חייבת להיות יציבה. עם זאת, אם משתמשים רק במודול ראשי ספציפי, לדוגמה, אפשר לשנות את השם שלו, או הקשרים של מאפיין, ואפילו להסיר אותו.

כדי לקבוע את היציבות של נכס מערכת, צריך לשאול את השאלות הבאות:

  • האם מאפיין המערכת הזה מיועד להגדרה על ידי שותפים (או להיות מוגדר? (בכל מכשיר בנפרד)? אם כן, המכשיר צריך להיות יציב.
  • האם מאפיין המערכת הזה בהגדרת 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 (בדרך כלל קובצי *.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}

פקודות מעטפת מסוג getpromo ו-setpro

אפשר להשתמש בפקודות המעטפת getprop או setprop, בהתאמה, כדי לקרוא או כותבים את המאפיינים. לקבלת פרטים נוספים, אפשר להפעיל את getprop --help או setprop --help.

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

Syspro כ-API עבור C++/Java/Rust

באמצעות syspro כ-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.

פונקציות ו-methods של נכסים ברמה נמוכה של C/C++ , Java ו-Rust

כשאפשר, כדאי להשתמש ב-Syspr כ-API, אפילו בפונקציות C/C++ או Rust ברמה נמוכה או שיטות Java ברמה נמוכה זמינות עבורך.

libc, libbase ו-libcutils מציעים פונקציות של מאפייני מערכת C++. libc כולל את ה-API הבסיסי, והפונקציות libbase ו-libcutils פריטי wrapper. אם זה אפשרי, השתמש בפונקציות syspro של 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, בנוסף דרישות לגבי מרחבי שמות של ספקים.

כללים ו-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 מחיצות.

נספח: שינוי השם של נכסים קיימים

כשצריך להוציא משימוש נכס ולעבור לנכס חדש, משתמשים ב-Syspr בתור ממשקי API כדי לשנות את השם של הנכסים הקיימים. כך אפשר לשמור על תאימות לאחור שמציין גם את השם הקודם וגם את שם הנכס החדש. וליתר דיוק, אפשר הגדרת השם מהדור הקודם באמצעות השדה 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);

שימו לב לאזהרות הבאות:

  • ראשית, לא ניתן לשנות את סוג ה-syspro. לדוגמה, לא ניתן ליצור דחף של int לאובייקט string. אפשר לשנות רק את השם.

  • שנית, רק ה-API של Read Along חוזר לשם הקודם. ממשק ה-API לכתיבה לא להיעלם. אם ה-syspro ניתן לכתיבה, לא ניתן לשנות את שמו.