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

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

#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
// some code fragment
#endif

לאחר מכן, קוד ה-framework יכול לקרוא לפונקציית שירות מתאימה שמוגדרת ב-<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 כדי לקבל את הכינוי לשרת ה-proxy של פונקציית הממשק, ואז מאחזרת את הערך על ידי הפעלת הכינוי דרך HIDL/hwbinder.

פונקציות עזר

<configstore/Utils.h> (configstore/1.0/include/configstore/Utils.h) מספק פונקציות מועילות לכל סוג החזרה פרימיטיבי, כולל Optional[Bool|String|Int32|UInt32|Int64|UInt64], כפי שמפורט בהמשך:

Type פונקציה (template parameters הושמטו)
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

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