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 26namespace android { 27namespace hardware { 28namespace automotive { 29namespace vehicle { 30namespace V2_0 { 31 32constexpr int32_t kCustomComplexProperty = 0xbeef 33 | VehiclePropertyGroup::VENDOR 34 | VehiclePropertyType::COMPLEX 35 | VehicleArea::GLOBAL; 36 37const 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 123constexpr auto kTimeout = std::chrono::milliseconds(500); 124 125class MockedVehicleCallback : public IVehicleCallback { 126private: 127 using MuxGuard = std::lock_guard<std::mutex>; 128 using HidlVecOfValues = hidl_vec<VehiclePropValue>; 129public: 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 174private: 175 std::mutex mLock; 176 std::condition_variable mEventCond; 177 std::vector<HidlVecOfValues> mReceivedEvents; 178}; 179 180template<typename T> 181inline std::string hexString(T value) { 182 std::stringstream ss; 183 ss << std::showbase << std::hex << value; 184 return ss.str(); 185} 186 187template <typename T, typename Collection> 188inline 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 209template<typename T> 210inline std::string enumToHexString(T value) { 211 return hexString(toInt(value)); 212} 213 214template <typename T> 215inline 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} // namespace V2_0 226} // namespace vehicle 227} // namespace automotive 228} // namespace hardware 229} // namespace android 230 231 232#endif //android_hardware_automotive_vehicle_V2_0_VehicleDebugUtils_H_ 233