1 //
2 // Copyright (C) 2017 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #ifndef ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
18 #define ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
19
20 #include <android/hardware/configstore/1.0/types.h>
21 #include <android/hardware/configstore/1.1/types.h>
22 #include <hidl/Status.h>
23
24 #include <sstream>
25
26 namespace android {
27 namespace hardware {
28
29 namespace details {
30 // Templated classes can use the below method
31 // to avoid creating dependencies on liblog.
32 bool wouldLogVerbose();
33 void logAlwaysVerbose(const std::string& message);
34 void logAlwaysError(const std::string& message);
35 } // namespace details
36
37 namespace configstore {
38 // import types from configstore
39 using ::android::hardware::configstore::V1_1::DisplayOrientation;
40 using ::android::hardware::configstore::V1_0::OptionalBool;
41 using ::android::hardware::configstore::V1_0::OptionalInt32;
42 using ::android::hardware::configstore::V1_0::OptionalUInt32;
43 using ::android::hardware::configstore::V1_0::OptionalInt64;
44 using ::android::hardware::configstore::V1_0::OptionalUInt64;
45 using ::android::hardware::configstore::V1_0::OptionalString;
46 using ::android::hardware::configstore::V1_1::OptionalDisplayOrientation;
47
48 static inline std::ostream& operator<<(std::ostream& os, DisplayOrientation orientation) {
49 os << ::android::hardware::configstore::V1_1::toString(orientation);
50 return os;
51 }
52
53 // a function to retrieve and cache the service handle
54 // for a particular interface
55 template <typename I>
getService()56 sp<I> getService() {
57 // static initializer used for synchronizations
58 static sp<I> configs = I::getService();
59 return configs;
60 }
61
62 // arguments V: type for the value (i.e., OptionalXXX)
63 // I: interface class name
64 // func: member function pointer
65 template<typename V, typename I, android::hardware::Return<void> (I::* func)
66 (std::function<void(const V&)>)>
decltype(V::value)67 decltype(V::value) get(const decltype(V::value) &defValue) {
68 using namespace android::hardware::details;
69 // static initializer used for synchronizations
70 auto getHelper = []()->V {
71 V ret;
72 sp<I> configs = getService<I>();
73
74 if (!configs.get()) {
75 // fallback to the default value
76 ret.specified = false;
77 } else {
78 auto status = (*configs.*func)([&ret](V v) {
79 ret = v;
80 });
81 if (!status.isOk()) {
82 std::ostringstream oss;
83 oss << "HIDL call failed for retrieving a config item from "
84 "configstore : "
85 << status.description().c_str();
86 logAlwaysError(oss.str());
87 ret.specified = false;
88 }
89 }
90
91 return ret;
92 };
93 static V cachedValue = getHelper();
94
95 if (wouldLogVerbose()) {
96 std::string iname = __PRETTY_FUNCTION__;
97 // func name starts with "func = " in __PRETTY_FUNCTION__
98 auto pos = iname.find("func = ");
99 if (pos != std::string::npos) {
100 iname = iname.substr(pos + sizeof("func = "));
101 iname.pop_back(); // remove trailing ']'
102 } else {
103 iname += " (unknown)";
104 }
105
106 std::ostringstream oss;
107 oss << iname << " retrieved: "
108 << (cachedValue.specified ? cachedValue.value : defValue)
109 << (cachedValue.specified ? "" : " (default)");
110 logAlwaysVerbose(oss.str());
111 }
112
113 return cachedValue.specified ? cachedValue.value : defValue;
114 }
115
116 template<typename I, android::hardware::Return<void> (I::* func)
117 (std::function<void(const OptionalBool&)>)>
getBool(const bool defValue)118 bool getBool(const bool defValue) {
119 return get<OptionalBool, I, func>(defValue);
120 }
121
122 template<typename I, android::hardware::Return<void> (I::* func)
123 (std::function<void(const OptionalInt32&)>)>
getInt32(const int32_t defValue)124 int32_t getInt32(const int32_t defValue) {
125 return get<OptionalInt32, I, func>(defValue);
126 }
127
128 template<typename I, android::hardware::Return<void> (I::* func)
129 (std::function<void(const OptionalUInt32&)>)>
getUInt32(const uint32_t defValue)130 uint32_t getUInt32(const uint32_t defValue) {
131 return get<OptionalUInt32, I, func>(defValue);
132 }
133
134 template<typename I, android::hardware::Return<void> (I::* func)
135 (std::function<void(const OptionalInt64&)>)>
getInt64(const int64_t defValue)136 int64_t getInt64(const int64_t defValue) {
137 return get<OptionalInt64, I, func>(defValue);
138 }
139
140 template<typename I, android::hardware::Return<void> (I::* func)
141 (std::function<void(const OptionalUInt64&)>)>
getUInt64(const uint64_t defValue)142 uint64_t getUInt64(const uint64_t defValue) {
143 return get<OptionalUInt64, I, func>(defValue);
144 }
145
146 template<typename I, android::hardware::Return<void> (I::* func)
147 (std::function<void(const OptionalString&)>)>
getString(const std::string & defValue)148 std::string getString(const std::string &defValue) {
149 return get<OptionalString, I, func>(defValue);
150 }
151
152 template <typename I, android::hardware::Return<void> (I::*func)(
153 std::function<void(const OptionalDisplayOrientation&)>)>
getDisplayOrientation(DisplayOrientation defValue)154 DisplayOrientation getDisplayOrientation(DisplayOrientation defValue) {
155 return get<OptionalDisplayOrientation, I, func>(defValue);
156 }
157
158 } // namespace configstore
159 } // namespace hardware
160 } // namespace android
161
162 #endif // ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
163