क्लाइंट-साइड इस्तेमाल

एचएएल इंटरफ़ेस से, वैल्यू को डाइनैमिक तौर पर पढ़ने के लिए, शर्तों के साथ कंपाइल किए गए कोड को रीफ़ैक्टर किया जा सकता है. उदाहरण के लिए:

#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 सेवा से संपर्क करता है. इसके बाद, 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 एक डिफ़ॉल्ट वैल्यू है, जो तब दिखती है, जब एचएएल लागू करने पर कॉन्फ़िगरेशन आइटम के लिए कोई वैल्यू तय नहीं की जाती. हर फ़ंक्शन में दो टेंप्लेट पैरामीटर होते हैं:

  • I, इंटरफ़ेस क्लास का नाम है.
  • Func, कॉन्फ़िगरेशन आइटम पाने के लिए सदस्य फ़ंक्शन पॉइंटर है.

कॉन्फ़िगरेशन वैल्यू सिर्फ़ पढ़ने के लिए होती है और इसमें बदलाव नहीं होता. इसलिए, यूटिलिटी फ़ंक्शन, कॉन्फ़िगरेशन वैल्यू को अंदरूनी तौर पर कैश मेमोरी में सेव करता है. बाद के कॉल को, उसी लिंकिंग यूनिट में कैश मेमोरी में सेव की गई वैल्यू का इस्तेमाल करके ज़्यादा बेहतर तरीके से सेवा दी जाती है.

configstore-utils का इस्तेमाल करना

ConfigStore एचएएल को, छोटे वर्शन के अपग्रेड के लिए फ़ॉरवर्ड कम्पैटिबल बनाया गया है. इसका मतलब है कि जब एचएएल में बदलाव किया जाता है और फ़्रेमवर्क कोड में नए आइटम का इस्तेमाल किया जाता है, तब भी /vendor में छोटे वर्शन वाली ConfigStore सेवा का इस्तेमाल किया जा सकता है.

आगे भी इसके साथ काम करने के लिए, पक्का करें कि लागू किया गया तरीका यहां दिए गए दिशा-निर्देशों के मुताबिक हो:

  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 है, तो getService() के लिए v1_1 सेवा को लौटाना ज़रूरी है:
    V1_0::IConfig::getService()->v1_0API();
    

जब ConfigStore आइटम को ऐक्सेस करने के लिए, configstore-utils लाइब्रेरी में मौजूद ऐक्सेस फ़ंक्शन का इस्तेमाल किया जाता है, तो #1 की पुष्टि लागू करने से होती है और #2 की पुष्टि कंपाइलर गड़बड़ियों से होती है. इन वजहों से, हमारा सुझाव है कि जहां भी हो सके वहां configstore-utils का इस्तेमाल करें.