1e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev/*
2e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * Copyright (C) 2016 The Android Open Source Project
3e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev *
4e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * Licensed under the Apache License, Version 2.0 (the "License");
5e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * you may not use this file except in compliance with the License.
6e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * You may obtain a copy of the License at
7e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev *
8e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev *      http://www.apache.org/licenses/LICENSE-2.0
9e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev *
10e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * Unless required by applicable law or agreed to in writing, software
11e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * distributed under the License is distributed on an "AS IS" BASIS,
12e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * See the License for the specific language governing permissions and
14e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * limitations under the License.
15e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev */
16e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
172579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev#ifndef android_hardware_automotive_vehicle_V2_0_VehicleDebugUtils_H_
182579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev#define android_hardware_automotive_vehicle_V2_0_VehicleDebugUtils_H_
19e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
202579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev#include <android/hardware/automotive/vehicle/2.0/types.h>
21e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev#include <ios>
22e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev#include <sstream>
23e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
24c5344ac04c430486633521098fdb63887546a32aPavel Maltsev#include "vhal_v2_0/VehicleUtils.h"
25c5344ac04c430486633521098fdb63887546a32aPavel Maltsev
26e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace android {
27e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace hardware {
282579fb792b4d47555515459f372f63c4305ee2caPavel Maltsevnamespace automotive {
29e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace vehicle {
30e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace V2_0 {
31e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
321ae977d6e87a88e1689d406636982e8296d68175Steve Paikconstexpr int32_t kCustomComplexProperty =
331ae977d6e87a88e1689d406636982e8296d68175Steve Paik    0xbeef | VehiclePropertyGroup::VENDOR | VehiclePropertyType::MIXED | VehicleArea::GLOBAL;
34dd1b9d395d7a91a8dd766fe4559696ae152035c0Antonio Cortes
35e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevconst VehiclePropConfig kVehicleProperties[] = {
36e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    {
378e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsev        .prop = toInt(VehicleProperty::INFO_MAKE),
38e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        .access = VehiclePropertyAccess::READ,
39e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        .changeMode = VehiclePropertyChangeMode::STATIC,
40e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        .configString = "Some=config,options=if,you=have_any",
41e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    },
42e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
4328b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik    {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
4428b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .access = VehiclePropertyAccess::READ_WRITE,
4528b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
4628b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .areaConfigs =
4728b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik         {VehicleAreaConfig{
4828b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik              .areaId = toInt(VehicleAreaSeat::ROW_1_LEFT), .minInt32Value = 1, .maxInt32Value = 7},
4928b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik          VehicleAreaConfig{
5028b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik              .areaId = toInt(VehicleAreaSeat::ROW_1_RIGHT), .minInt32Value = 1, .maxInt32Value = 5,
5128b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik          }}},
52db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev
53db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev    // Write-only property
5428b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik    {.prop = toInt(VehicleProperty::HVAC_SEAT_TEMPERATURE),
5528b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .access = VehiclePropertyAccess::WRITE,
5628b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
5728b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .areaConfigs = {VehicleAreaConfig{.areaId = toInt(VehicleAreaSeat::ROW_1_LEFT),
5828b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik                                       .minInt32Value = 64,
5928b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik                                       .maxInt32Value = 80},
6028b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik                     VehicleAreaConfig{
6128b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik                         .areaId = toInt(VehicleAreaSeat::ROW_1_RIGHT),
6228b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik                         .minInt32Value = 64,
6328b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik                         .maxInt32Value = 80,
6428b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik                     }}},
65e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
6628b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik    {.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
6728b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .access = VehiclePropertyAccess::READ,
6828b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
6928b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .areaConfigs = {VehicleAreaConfig{.minFloatValue = 0, .maxFloatValue = 1.0}}},
70e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
7128b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik    {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
7228b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .access = VehiclePropertyAccess::READ_WRITE,
7328b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
7428b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .areaConfigs = {VehicleAreaConfig{.minInt32Value = 0, .maxInt32Value = 10}}},
75db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev
76db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev    {
778e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsev        .prop = toInt(VehicleProperty::MIRROR_FOLD),
78db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev        .access = VehiclePropertyAccess::READ_WRITE,
79db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
80db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev
81f21639f6e391c45c13345eee6cbf1df6579817d2Pavel Maltsev    },
82f21639f6e391c45c13345eee6cbf1df6579817d2Pavel Maltsev
83f21639f6e391c45c13345eee6cbf1df6579817d2Pavel Maltsev    // Complex data type.
8428b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik    {.prop = kCustomComplexProperty,
8528b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .access = VehiclePropertyAccess::READ_WRITE,
8628b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik     .changeMode = VehiclePropertyChangeMode::ON_CHANGE}};
87e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
88e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevconstexpr auto kTimeout = std::chrono::milliseconds(500);
89e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
90e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevclass MockedVehicleCallback : public IVehicleCallback {
91db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsevprivate:
92db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev    using MuxGuard = std::lock_guard<std::mutex>;
93db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev    using HidlVecOfValues = hidl_vec<VehiclePropValue>;
94e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevpublic:
952579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev    // Methods from ::android::hardware::automotive::vehicle::V2_0::IVehicleCallback follow.
96e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    Return<void> onPropertyEvent(
97e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            const hidl_vec<VehiclePropValue>& values) override {
98e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        {
99e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            MuxGuard  g(mLock);
100e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            mReceivedEvents.push_back(values);
101e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        }
102e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        mEventCond.notify_one();
103e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        return Return<void>();
104e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
105308515f65fcbc0592b3b7053dfbf7de6fbb9a806Pavel Maltsev    Return<void> onPropertySet(const VehiclePropValue& /* value */) override {
106e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        return Return<void>();
107e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
108308515f65fcbc0592b3b7053dfbf7de6fbb9a806Pavel Maltsev    Return<void> onPropertySetError(StatusCode /* errorCode */,
109308515f65fcbc0592b3b7053dfbf7de6fbb9a806Pavel Maltsev                                    int32_t /* propId */,
110308515f65fcbc0592b3b7053dfbf7de6fbb9a806Pavel Maltsev                                    int32_t /* areaId */) override {
111e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        return Return<void>();
112e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
113e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
114e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    bool waitForExpectedEvents(size_t expectedEvents) {
115e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        std::unique_lock<std::mutex> g(mLock);
116e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
117e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        if (expectedEvents == 0 && mReceivedEvents.size() == 0) {
118e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            // No events expected, let's sleep a little bit to make sure
119e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            // nothing will show up.
120e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            return mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout;
121e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        }
122e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
123e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        while (expectedEvents != mReceivedEvents.size()) {
124e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            if (mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout) {
125e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev                return false;
126e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            }
127e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        }
128e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        return true;
129e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
130e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
131e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    void reset() {
132e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        mReceivedEvents.clear();
133e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
134e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
135db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev    const std::vector<HidlVecOfValues>& getReceivedEvents() {
136e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        return mReceivedEvents;
137e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
138e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
139e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevprivate:
140e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    std::mutex mLock;
141e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    std::condition_variable mEventCond;
142db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev    std::vector<HidlVecOfValues> mReceivedEvents;
143e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev};
144e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
145e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevtemplate<typename T>
146e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevinline std::string hexString(T value) {
147e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    std::stringstream ss;
148e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    ss << std::showbase << std::hex << value;
149e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    return ss.str();
150e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}
151e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
152e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevtemplate <typename T, typename Collection>
153e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevinline void assertAllExistsAnyOrder(
154e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        std::initializer_list<T> expected,
155e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        const Collection& actual,
156e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        const char* msg) {
157e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    std::set<T> expectedSet = expected;
158e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
159e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    for (auto a: actual) {
160e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        ASSERT_EQ(1u, expectedSet.erase(a))
161e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev                << msg << "\nContains not unexpected value.\n";
162e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
163e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
164e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    ASSERT_EQ(0u, expectedSet.size())
165e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            << msg
166e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            << "\nDoesn't contain expected value.";
167e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}
168e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
169e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev#define ASSERT_ALL_EXISTS(...) \
170e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    assertAllExistsAnyOrder(__VA_ARGS__, (std::string("Called from: ") + \
171e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            std::string(__FILE__) + std::string(":") + \
172e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev            std::to_string(__LINE__)).c_str()); \
173e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
174e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevtemplate<typename T>
175e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevinline std::string enumToHexString(T value) {
176db179c5ec470269e1c88d8da5fafdff40a539bc6Pavel Maltsev    return hexString(toInt(value));
177e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}
178e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
179e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevtemplate <typename T>
180668fed79ad2e7a1dc3fa244efe56b17c12173233Yifan Honginline std::string vecToString(const hidl_vec<T>& vec) {
181e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    std::stringstream ss("[");
182e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    for (size_t i = 0; i < vec.size(); i++) {
183e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        if (i != 0) ss << ",";
184e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev        ss << vec[i];
185e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    }
186e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    ss << "]";
187e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev    return ss.str();
188e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}
189e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
190e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}  // namespace V2_0
191e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}  // namespace vehicle
1922579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev}  // namespace automotive
193e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}  // namespace hardware
194e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev}  // namespace android
195e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
196e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev
1972579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev#endif //android_hardware_automotive_vehicle_V2_0_VehicleDebugUtils_H_
198