1/*
2 * Copyright (C) 2015 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_VEHICLENETWORK_TEST_LISTER_H
18#define ANDROID_VEHICLENETWORK_TEST_LISTER_H
19
20#include <IVehicleNetworkListener.h>
21#include <VehicleNetworkDataTypes.h>
22
23namespace android {
24
25class VehicleNetworkTestListener : public VehicleNetworkListener {
26public:
27    VehicleNetworkTestListener()
28    : mEvents(new VehiclePropValueListHolder(new List<vehicle_prop_value_t* >())) {
29        String8 msg;
30        msg.appendFormat("Creating VehicleNetworkTestListener 0x%p\n", this);
31        std::cout<<msg.string();
32    }
33
34    virtual ~VehicleNetworkTestListener() {
35        std::cout<<"destroying VehicleNetworkTestListener\n";
36        for (auto& e : mEvents->getList()) {
37            VehiclePropValueUtil::deleteMembers(e);
38            delete e;
39        }
40    }
41
42    virtual void onEvents(sp<VehiclePropValueListHolder>& events) {
43        String8 msg("events ");
44        Mutex::Autolock autolock(mLock);
45        for (auto& e : events->getList()) {
46            ssize_t index = mEventCounts.indexOfKey(e->prop);
47            if (index < 0) {
48                mEventCounts.add(e->prop, 1); // 1st event
49                msg.appendFormat("0x%x:%d ", e->prop, 1);
50            } else {
51                int count = mEventCounts.valueAt(index);
52                count++;
53                mEventCounts.replaceValueAt(index, count);
54                msg.appendFormat("0x%x:%d ", e->prop, count);
55            }
56            vehicle_prop_value_t* copy = VehiclePropValueUtil::allocVehicleProp(*e);
57            mEvents->getList().push_back(copy);
58        }
59        msg.append("\n");
60        std::cout<<msg.string();
61        mCondition.signal();
62    }
63
64    virtual void onHalError(int32_t /*errorCode*/, int32_t /*property*/, int32_t /*operation*/) {
65        //TODO
66    }
67
68    virtual void onHalRestart(bool /*inMocking*/) {
69        //TODO cannot test this in native world without plumbing mocking
70    }
71
72    void waitForEvents(nsecs_t reltime) {
73        Mutex::Autolock autolock(mLock);
74        mCondition.waitRelative(mLock, reltime);
75    }
76
77    bool waitForEvent(int32_t property, int initialEventCount, nsecs_t reltime) {
78        Mutex::Autolock autolock(mLock);
79        int currentCount = initialEventCount;
80        int64_t now = android::elapsedRealtimeNano();
81        int64_t endTime = now + reltime;
82        while ((initialEventCount == currentCount) && (now < endTime)) {
83            mCondition.waitRelative(mLock, endTime - now);
84            currentCount = getEventCountLocked(property);
85            now = android::elapsedRealtimeNano();
86        }
87        return (initialEventCount != currentCount);
88    }
89
90    int getEventCount(int32_t property) {
91        Mutex::Autolock autolock(mLock);
92        return getEventCountLocked(property);
93    }
94
95    sp<VehiclePropValueListHolder>& getEvents() {
96        // this is nothing more than memory barrier. Just for testing.
97        Mutex::Autolock autolock(mLock);
98        return mEvents;
99    }
100
101    const vehicle_prop_value& getLastValue() {
102        auto itr = getEvents()->getList().end();
103        itr--;
104        return **itr;
105    }
106
107private:
108    int getEventCountLocked(int32_t property) {
109        ssize_t index = mEventCounts.indexOfKey(property);
110        if (index < 0) {
111            return 0;
112        } else {
113            return mEventCounts.valueAt(index);
114        }
115    }
116private:
117    Mutex mLock;
118    Condition mCondition;
119    KeyedVector<int32_t, int> mEventCounts;
120    sp<VehiclePropValueListHolder> mEvents;
121};
122
123}; // namespace android
124#endif // ANDROID_VEHICLENETWORK_TEST_LISTER_H
125