אפשר לבצע רפקטורינג של קוד שעבר קומפילציה מותנית כדי לקרוא ערכים באופן דינמי מממשק HAL. לדוגמה:
#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS // some code fragment #endif
לאחר מכן, קוד המסגרת יכול לקרוא לפונקציית כלי עזר מתאימה שמוגדרת ב-<configstore/Utils.h>
, בהתאם לסוג שלה.
דוגמה ל-ConfigStore
בדוגמה הזו מוצגת קריאה של
TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
, שמוגדר ב-ConfigStore HAL
כ-forceHwcForVirtualDisplays()
עם סוג החזרה
OptionalBool
:
#include <configstore/Utils.h> using namespace android::hardware::configstore; using namespace android::hardware::configstore::V1_0; static bool vsyncPhaseOffsetNs = getBool<ISurfaceFlingerConfigs, ISurfaceFlingerConfigs::forceHwcForVirtualDisplays>(false);
פונקציית השירות (getBool
בדוגמה שלמעלה) יוצרת קשר עם שירות configstore
כדי לקבל את ה-handle של ה-proxy של פונקציית הממשק, ואז מאחזרת את הערך על ידי הפעלת ה-handle באמצעות HIDL/hwbinder.
פונקציות בסיסיות
<configstore/Utils.h>
(configstore/1.0/include/configstore/Utils.h
) מספק פונקציות עזר לכל סוג החזרה פרימיטיבי, כולל Optional[Bool|String|Int32|UInt32|Int64|UInt64]
, כמו שמופיע ברשימה הבאה:
סוג | פונקציה (הפרמטרים של התבנית הושמטו) |
---|---|
OptionalBool |
bool getBool(const bool defValue) |
OptionalInt32 |
int32_t getInt32(const int32_t defValue) |
OptionalUInt32 |
uint32_t getUInt32(const uint32_t defValue) |
OptionalInt64 |
int64_t getInt64(const int64_t defValue) |
OptionalUInt64 |
uint64_t getUInt64(const uint64_t defValue) |
OptionalString |
std::string getString(const std::string &defValue) |
defValue
הוא ערך ברירת מחדל שמוחזר כשיישום ה-HAL לא מציין ערך עבור פריט ההגדרה. כל פונקציה מקבלת שני פרמטרים של תבנית:
-
I
הוא שם מחלקת הממשק. -
Func
הוא מצביע לפונקציה חברה לקבלת פריט ההגדרה.
ערך ההגדרה הוא לקריאה בלבד ולא משתנה, ולכן פונקציית השירות שומרת את ערך ההגדרה במטמון באופן פנימי. הקריאות הבאות מטופלות בצורה יעילה יותר באמצעות הערך שנשמר במטמון באותה יחידת קישור.
שימוש ב-configstore-utils
ה-HAL של ConfigStore מתוכנן להיות תואם לגרסאות קדימות לשדרוגים של גרסאות משניות, כלומר, כשמתבצעת עדכון של ה-HAL וחלק מקוד המסגרת משתמש בפריטים החדשים, עדיין אפשר להשתמש בשירות ConfigStore עם גרסה משנית ישנה יותר ב-/vendor
.
כדי להבטיח תאימות לדורות הבאים, חשוב לוודא שההטמעה שלכם עומדת בהנחיות הבאות:
- פריטים חדשים משתמשים בערך ברירת המחדל כשזמין רק השירות של הגרסה הישנה. דוגמה:
service = V1_1::IConfig::getService(); // null if V1_0 is installed value = DEFAULT_VALUE; if(service) { value = service->v1_1API(DEFAULT_VALUE); }
- הלקוח משתמש בממשק הראשון שכולל את הפריט ConfigStore.
דוגמה:
V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED V1_0::IConfig::getService()->v1_0API(); // OK
- אפשר לאחזר את השירות של הגרסה החדשה לממשק של הגרסה הישנה. בדוגמה הבאה, אם הגרסה המותקנת היא v1_1, השירות v1_1 צריך להיות מוחזר עבור
getService()
:V1_0::IConfig::getService()->v1_0API();
כשמשתמשים בפונקציות הגישה בספרייה configstore-utils
כדי לגשת לפריט ConfigStore, ההטמעה מבטיחה את תנאי 1, ושגיאות קומפילציה מבטיחות את תנאי 2. מהסיבות האלה, מומלץ מאוד להשתמש ב-configstore-utils
בכל מקום שאפשר.