1 /* 2 * Copyright (C) 2016 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_automotive_vehicle_V2_0_VehicleDebugUtils_H_ 18 #define android_hardware_automotive_vehicle_V2_0_VehicleDebugUtils_H_ 19 20 #include <android/hardware/automotive/vehicle/2.0/types.h> 21 #include <ios> 22 #include <sstream> 23 24 #include "vhal_v2_0/VehicleUtils.h" 25 26 namespace android { 27 namespace hardware { 28 namespace automotive { 29 namespace vehicle { 30 namespace V2_0 { 31 32 constexpr int32_t kCustomComplexProperty = 0xbeef 33 | VehiclePropertyGroup::VENDOR 34 | VehiclePropertyType::COMPLEX 35 | VehicleArea::GLOBAL; 36 37 const VehiclePropConfig kVehicleProperties[] = { 38 { 39 .prop = toInt(VehicleProperty::INFO_MAKE), 40 .access = VehiclePropertyAccess::READ, 41 .changeMode = VehiclePropertyChangeMode::STATIC, 42 .configString = "Some=config,options=if,you=have_any", 43 }, 44 45 { 46 .prop = toInt(VehicleProperty::HVAC_FAN_SPEED), 47 .access = VehiclePropertyAccess::READ_WRITE, 48 .changeMode = VehiclePropertyChangeMode::ON_CHANGE, 49 .supportedAreas = static_cast<int32_t>( 50 VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT), 51 .areaConfigs = { 52 VehicleAreaConfig { 53 .areaId = toInt(VehicleAreaZone::ROW_1_LEFT), 54 .minInt32Value = 1, 55 .maxInt32Value = 7}, 56 VehicleAreaConfig { 57 .areaId = toInt(VehicleAreaZone::ROW_1_RIGHT), 58 .minInt32Value = 1, 59 .maxInt32Value = 5, 60 } 61 } 62 }, 63 64 // Write-only property 65 { 66 .prop = toInt(VehicleProperty::HVAC_SEAT_TEMPERATURE), 67 .access = VehiclePropertyAccess::WRITE, 68 .changeMode = VehiclePropertyChangeMode::ON_SET, 69 .supportedAreas = static_cast<int32_t>( 70 VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT), 71 .areaConfigs = { 72 VehicleAreaConfig { 73 .areaId = toInt(VehicleAreaZone::ROW_1_LEFT), 74 .minInt32Value = 64, 75 .maxInt32Value = 80}, 76 VehicleAreaConfig { 77 .areaId = toInt(VehicleAreaZone::ROW_1_RIGHT), 78 .minInt32Value = 64, 79 .maxInt32Value = 80, 80 } 81 } 82 }, 83 84 { 85 .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY), 86 .access = VehiclePropertyAccess::READ, 87 .changeMode = VehiclePropertyChangeMode::ON_CHANGE, 88 .areaConfigs = { 89 VehicleAreaConfig { 90 .minFloatValue = 0, 91 .maxFloatValue = 1.0 92 } 93 } 94 }, 95 96 { 97 .prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS), 98 .access = VehiclePropertyAccess::READ_WRITE, 99 .changeMode = VehiclePropertyChangeMode::ON_CHANGE, 100 .areaConfigs = { 101 VehicleAreaConfig { 102 .minInt32Value = 0, 103 .maxInt32Value = 10 104 } 105 } 106 }, 107 108 { 109 .prop = toInt(VehicleProperty::MIRROR_FOLD), 110 .access = VehiclePropertyAccess::READ_WRITE, 111 .changeMode = VehiclePropertyChangeMode::ON_CHANGE, 112 113 }, 114 115 // Complex data type. 116 { 117 .prop = kCustomComplexProperty, 118 .access = VehiclePropertyAccess::READ_WRITE, 119 .changeMode = VehiclePropertyChangeMode::ON_CHANGE 120 } 121 }; 122 123 constexpr auto kTimeout = std::chrono::milliseconds(500); 124 125 class MockedVehicleCallback : public IVehicleCallback { 126 private: 127 using MuxGuard = std::lock_guard<std::mutex>; 128 using HidlVecOfValues = hidl_vec<VehiclePropValue>; 129 public: 130 // Methods from ::android::hardware::automotive::vehicle::V2_0::IVehicleCallback follow. 131 Return<void> onPropertyEvent( 132 const hidl_vec<VehiclePropValue>& values) override { 133 { 134 MuxGuard g(mLock); 135 mReceivedEvents.push_back(values); 136 } 137 mEventCond.notify_one(); 138 return Return<void>(); 139 } 140 Return<void> onPropertySet(const VehiclePropValue& /* value */) override { 141 return Return<void>(); 142 } 143 Return<void> onPropertySetError(StatusCode /* errorCode */, 144 int32_t /* propId */, 145 int32_t /* areaId */) override { 146 return Return<void>(); 147 } 148 149 bool waitForExpectedEvents(size_t expectedEvents) { 150 std::unique_lock<std::mutex> g(mLock); 151 152 if (expectedEvents == 0 && mReceivedEvents.size() == 0) { 153 // No events expected, let's sleep a little bit to make sure 154 // nothing will show up. 155 return mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout; 156 } 157 158 while (expectedEvents != mReceivedEvents.size()) { 159 if (mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout) { 160 return false; 161 } 162 } 163 return true; 164 } 165 166 void reset() { 167 mReceivedEvents.clear(); 168 } 169 170 const std::vector<HidlVecOfValues>& getReceivedEvents() { 171 return mReceivedEvents; 172 } 173 174 private: 175 std::mutex mLock; 176 std::condition_variable mEventCond; 177 std::vector<HidlVecOfValues> mReceivedEvents; 178 }; 179 180 template<typename T> 181 inline std::string hexString(T value) { 182 std::stringstream ss; 183 ss << std::showbase << std::hex << value; 184 return ss.str(); 185 } 186 187 template <typename T, typename Collection> 188 inline void assertAllExistsAnyOrder( 189 std::initializer_list<T> expected, 190 const Collection& actual, 191 const char* msg) { 192 std::set<T> expectedSet = expected; 193 194 for (auto a: actual) { 195 ASSERT_EQ(1u, expectedSet.erase(a)) 196 << msg << "\nContains not unexpected value.\n"; 197 } 198 199 ASSERT_EQ(0u, expectedSet.size()) 200 << msg 201 << "\nDoesn't contain expected value."; 202 } 203 204 #define ASSERT_ALL_EXISTS(...) \ 205 assertAllExistsAnyOrder(__VA_ARGS__, (std::string("Called from: ") + \ 206 std::string(__FILE__) + std::string(":") + \ 207 std::to_string(__LINE__)).c_str()); \ 208 209 template<typename T> 210 inline std::string enumToHexString(T value) { 211 return hexString(toInt(value)); 212 } 213 214 template <typename T> 215 inline std::string vecToString(const hidl_vec<T>& vec) { 216 std::stringstream ss("["); 217 for (size_t i = 0; i < vec.size(); i++) { 218 if (i != 0) ss << ","; 219 ss << vec[i]; 220 } 221 ss << "]"; 222 return ss.str(); 223 } 224 225 inline std::string toString(const VehiclePropValue &v) { 226 std::stringstream ss; 227 ss << "VehiclePropValue {n" 228 << " prop: " << hexString(v.prop) << ",\n" 229 << " areaId: " << hexString(v.areaId) << ",\n" 230 << " timestamp: " << v.timestamp << ",\n" 231 << " value {\n" 232 << " int32Values: " << vecToString(v.value.int32Values) << ",\n" 233 << " floatValues: " << vecToString(v.value.floatValues) << ",\n" 234 << " int64Values: " << vecToString(v.value.int64Values) << ",\n" 235 << " bytes: " << vecToString(v.value.bytes) << ",\n" 236 << " string: " << v.value.stringValue.c_str() << ",\n" 237 << " }\n" 238 << "}\n"; 239 240 return ss.str(); 241 } 242 243 inline std::string toString(const VehiclePropConfig &config) { 244 std::stringstream ss; 245 ss << "VehiclePropConfig {\n" 246 << " prop: " << hexString(config.prop) << ",\n" 247 << " supportedAreas: " << hexString(config.supportedAreas) << ",\n" 248 << " access: " << enumToHexString(config.access) << ",\n" 249 << " changeMode: " << enumToHexString(config.changeMode) << ",\n" 250 << " configFlags: " << hexString(config.configFlags) << ",\n" 251 << " minSampleRate: " << config.minSampleRate << ",\n" 252 << " maxSampleRate: " << config.maxSampleRate << ",\n" 253 << " configString: " << config.configString.c_str() << ",\n"; 254 255 ss << " areaConfigs {\n"; 256 for (size_t i = 0; i < config.areaConfigs.size(); i++) { 257 const auto &area = config.areaConfigs[i]; 258 ss << " areaId: " << hexString(area.areaId) << ",\n" 259 << " minFloatValue: " << area.minFloatValue << ",\n" 260 << " minFloatValue: " << area.maxFloatValue << ",\n" 261 << " minInt32Value: " << area.minInt32Value << ",\n" 262 << " minInt32Value: " << area.maxInt32Value << ",\n" 263 << " minInt64Value: " << area.minInt64Value << ",\n" 264 << " minInt64Value: " << area.maxInt64Value << ",\n"; 265 } 266 ss << " }\n" 267 << "}\n"; 268 269 return ss.str(); 270 } 271 272 273 } // namespace V2_0 274 } // namespace vehicle 275 } // namespace automotive 276 } // namespace hardware 277 } // namespace android 278 279 280 #endif //android_hardware_automotive_vehicle_V2_0_VehicleDebugUtils_H_ 281