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

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

שלב 1: הגדרת מאפיין המערכת

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

שם הנכס

השתמש בפורמט הזה עם מעטפת הנחש:

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

השתמש ב-"" (השמטה), ro (עבור מאפיינים שהוגדרו פעם אחת בלבד), או persist (עבור מאפיינים שנמשכים לאורך אתחול מחדש) עבור prefix הרכיב .

אזהרות

השתמש 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
sysprops מ-cmdline של הקרנל boot
sysprops המזהים מבנה build
קשור לטלפוניה telephony
קשור לאודיו audio
קשור לגרפיקה graphics
קשור לוולד 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 : השתמש אם זה מאפיין מערכת עבור ערך זמן קצוב ביחידות של ms.

דוגמאות:

  • 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 עבור נכון, 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: הוספתו ל-system/sepolicy

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

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

יציבות היא היבט נוסף של מאפייני המערכת, והיא שונה מנגישות. יציבות עוסקת בשאלה האם ניתן לשנות מאפיין מערכת או לא (לדוגמה לשנות את שמו, או אפילו להסיר) בעתיד. זה חשוב במיוחד מכיוון שמערכת ההפעלה של אנדרואיד הופכת למודולרית. עם Treble, ניתן לעדכן את מחיצות המערכת, הספק והמוצר ללא תלות זו בזו. עם Mainline, חלקים מסוימים של מערכת ההפעלה מודולריים כמודולים הניתנים לעדכון (ב-APEXs או APKs).

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

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

בקובץ 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 ומשתמש 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 prop לאביזר string . אתה יכול רק לשנות את השם.

  • שנית, רק ה-API לקריאה נופל בחזרה לשם הישן. ממשק ה-API לכתיבה לא נופל אחורה. אם ה-sysprop הוא אחד שניתן לכתיבה, לא ניתן לשנות את שמו.