VehicleHalTestUtils.h revision c525408c60373cb86fa5ffaa8dabb0945ab41716
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