שימוש בצד הלקוח

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

כדי להבטיח תאימות לדורות הבאים, חשוב לוודא שההטמעה שלכם עומדת בהנחיות הבאות:

  1. פריטים חדשים משתמשים בערך ברירת המחדל כשזמין רק השירות של הגרסה הישנה. דוגמה:
    service = V1_1::IConfig::getService(); // null if V1_0 is installed
    value = DEFAULT_VALUE;
      if(service) {
        value = service->v1_1API(DEFAULT_VALUE);
      }
    
  2. הלקוח משתמש בממשק הראשון שכולל את הפריט ConfigStore. דוגמה:
    V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED
    
    V1_0::IConfig::getService()->v1_0API(); // OK
    
  3. אפשר לאחזר את השירות של הגרסה החדשה לממשק של הגרסה הישנה. בדוגמה הבאה, אם הגרסה המותקנת היא v1_1, השירות v1_1 צריך להיות מוחזר עבור getService():
    V1_0::IConfig::getService()->v1_0API();
    

כשמשתמשים בפונקציות הגישה בספרייה configstore-utils כדי לגשת לפריט ConfigStore, ההטמעה מבטיחה את תנאי 1, ושגיאות קומפילציה מבטיחות את תנאי 2. מהסיבות האלה, מומלץ מאוד להשתמש ב-configstore-utils בכל מקום שאפשר.