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

בדף הזה מפורטת שיטה קנונית להוספה או להגדרה של מאפייני מערכת ב-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
sysprops מ-cmdline של הליבה boot
sysprops שמזהים 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 ביט
כפול נקודה צפה (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

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

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

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

אפשר להשתמש בפקודות המעטפת 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.

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

כשאפשר, כדאי להשתמש ב-Sysprop כ-API גם אם יש לכם גישה לפונקציות ברמה נמוכה של C/C++‎ או Rust, או לשיטות ברמה נמוכה של Java.

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

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

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

כשצריך להוציא משימוש נכס ולעבור לנכס חדש, משתמשים ב-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 לכתיבה לא עובר לחלופה. אם sysprop הוא פרמטר שאפשר לשנות, אי אפשר לשנות את השם שלו.