شما میتوانید کد کامپایل شده به صورت شرطی را طوری تغییر دهید که مقادیر را به صورت پویا از رابط 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) مربوط به پروکسی تابع رابط را دریافت کند، سپس با فراخوانی شناسه از طریق 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 استفاده کنید
ConfigStore HAL به گونهای طراحی شده است که برای ارتقاء نسخههای جزئی سازگار باشد، به این معنی که وقتی 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 استفاده میشود، مورد اول توسط پیادهسازی و مورد دوم توسط خطاهای کامپایلر تضمین میشود. به همین دلایل، اکیداً توصیه میکنیم در هر کجا که ممکن است configstore-utils استفاده کنید.