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

אפשר לארגן מחדש קוד שעבר הידור מותנה כדי לקרוא ערכים באופן דינמי מממשק HAL. לדוגמה:

#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
// some code fragment
#endif

לאחר מכן, קוד מסגרת יכול לקרוא לפונקציית שירות מתאימה שמוגדרת ב-<configstore/Utils.h>, בהתאם לסוג שלו.

דוגמה ל-ConfigStore

בדוגמה הזו מוצגת קריאה של TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS, שמוגדרת ב-HAL של ConfigStore בתור 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, הדרישה הראשונה מובטחת על ידי ההטמעה והדרישה השנייה מובטחת על ידי שגיאות של המהדר. לכן מומלץ מאוד להשתמש ב-configstore-utils בכל מקום אפשרי.