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