• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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_SENSORS_VTS_ENVIRONMENT_BASE_H
18 #define ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H
19 
20 #include <gtest/gtest.h>
21 
22 #include <atomic>
23 #include <functional>
24 #include <memory>
25 #include <mutex>
26 #include <thread>
27 #include <vector>
28 
29 #include <log/log.h>
30 
31 template <class Event>
32 class IEventCallback {
33   public:
34     virtual ~IEventCallback() = default;
35     virtual void onEvent(const Event& event) = 0;
36 };
37 
38 template <class Event>
39 class SensorsVtsEnvironmentBase {
40   public:
SetUp()41     virtual void SetUp() {
42         ASSERT_TRUE(resetHal()) << "could not get hidl service";
43 
44         mCollectionEnabled = false;
45         startPollingThread();
46 
47         // In case framework just stopped for test and there is sensor events in the pipe,
48         // wait some time for those events to be cleared to avoid them messing up the test.
49         std::this_thread::sleep_for(std::chrono::seconds(3));
50     }
51 
52     virtual void TearDown() = 0;
53 
54     // Get and clear all events collected so far (like "cat" shell command).
55     // If output is nullptr, it clears all collected events.
catEvents(std::vector<Event> * output)56     void catEvents(std::vector<Event>* output) {
57         std::lock_guard<std::mutex> lock(mEventsMutex);
58         if (output) {
59             output->insert(output->end(), mEvents.begin(), mEvents.end());
60         }
61         mEvents.clear();
62     }
63 
64     // set sensor event collection status
65     void setCollection(bool enable, const std::optional<std::function<bool(const Event&)>>& filter =
66                                             std::nullopt) {
67         std::lock_guard<std::mutex> lock(mEventsMutex);
68         mCollectionEnabled = enable;
69 
70         if (enable && filter.has_value()) {
71             mEventFilter = *filter;
72         } else {
73             mEventFilter.reset();
74         }
75     }
76 
registerCallback(IEventCallback<Event> * callback)77     void registerCallback(IEventCallback<Event>* callback) {
78         std::lock_guard<std::mutex> lock(mEventsMutex);
79         mCallback = callback;
80     }
81 
unregisterCallback()82     void unregisterCallback() {
83         std::lock_guard<std::mutex> lock(mEventsMutex);
84         mCallback = nullptr;
85     }
86 
87     std::vector<Event> collectEvents(
88             useconds_t timeLimitUs, size_t nEventLimit, bool clearBeforeStart = true,
89             bool changeCollection = true,
90             const std::optional<std::function<bool(const Event&)>>& filter = std::nullopt) {
91         std::vector<Event> events;
92         constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000;  // granularity 100 ms
93 
94         ALOGI("collect max of %zu events for %d us, clearBeforeStart %d", nEventLimit, timeLimitUs,
95               clearBeforeStart);
96 
97         if (changeCollection) {
98             setCollection(true, filter);
99         }
100         if (clearBeforeStart) {
101             catEvents(nullptr);
102         }
103 
104         while (timeLimitUs > 0) {
105             useconds_t duration = std::min(SLEEP_GRANULARITY, timeLimitUs);
106             usleep(duration);
107             timeLimitUs -= duration;
108 
109             catEvents(&events);
110             if (events.size() >= nEventLimit) {
111                 break;
112             }
113             ALOGV("time to go = %d, events to go = %d", (int)timeLimitUs,
114                   (int)(nEventLimit - events.size()));
115         }
116 
117         if (changeCollection) {
118             setCollection(false);
119         }
120         return events;
121     }
122 
123   protected:
SensorsVtsEnvironmentBase(const std::string & service_name)124     SensorsVtsEnvironmentBase(const std::string& service_name)
125         : mCollectionEnabled(false), mCallback(nullptr) {
126         mServiceName = service_name;
127     }
128     SensorsVtsEnvironmentBase(const SensorsVtsEnvironmentBase&) = delete;
129     SensorsVtsEnvironmentBase& operator=(const SensorsVtsEnvironmentBase&) = delete;
~SensorsVtsEnvironmentBase()130     virtual ~SensorsVtsEnvironmentBase(){};
131 
addEvent(const Event & ev)132     void addEvent(const Event& ev) {
133         std::lock_guard<std::mutex> lock(mEventsMutex);
134         if (mCollectionEnabled && (!mEventFilter.has_value() || (*mEventFilter)(ev))) {
135             mEvents.push_back(ev);
136         }
137 
138         if (mCallback != nullptr) {
139             mCallback->onEvent(ev);
140         }
141     }
142 
143     virtual void startPollingThread() = 0;
144     virtual bool resetHal() = 0;
145 
146     std::string mServiceName;
147     bool mCollectionEnabled;
148     std::atomic_bool mStopThread;
149     std::thread mPollThread;
150     std::vector<Event> mEvents;
151     std::optional<std::function<bool(const Event&)>> mEventFilter;
152     std::mutex mEventsMutex;
153 
154     IEventCallback<Event>* mCallback;
155 };
156 
157 #endif  // ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H