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