1 /* 2 * Copyright (c) 2021, 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 CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_ 18 #define CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_ 19 20 #include "LooperWrapper.h" 21 22 #include <algorithm> 23 #include <deque> 24 #include <map> 25 26 namespace android { 27 namespace automotive { 28 namespace telemetry { 29 30 // Fake `utils/Looper.h` implementation. Explicitly use `FakeLooperWrapper::poll()` method 31 // to process the messages. 32 // 33 // Not thread-safe. 34 class FakeLooperWrapper : public LooperWrapper { 35 public: 36 static inline constexpr int kNoScheduledMessage = -1; 37 FakeLooperWrapper()38 FakeLooperWrapper() : LooperWrapper(nullptr) {} 39 pollAll(int timeoutMillis)40 int pollAll(int timeoutMillis) override { return 0; } 41 sendMessageDelayed(nsecs_t uptime,const android::sp<MessageHandler> & handler,const Message & message)42 void sendMessageDelayed(nsecs_t uptime, const android::sp<MessageHandler>& handler, 43 const Message& message) override { 44 mUptimeEntries[::systemTime() + uptime].push_back( 45 {.mHandler = handler, .mMessage = message}); 46 } 47 removeMessages(const android::sp<MessageHandler> & handler,int what)48 void removeMessages(const android::sp<MessageHandler>& handler, int what) override { 49 for (auto it = mUptimeEntries.begin(); it != mUptimeEntries.end();) { 50 auto [entryUptime, entries] = *it; 51 for (auto eit = entries.begin(); eit != entries.end();) { 52 if (eit->mMessage.what == what) { 53 eit = entries.erase(eit); 54 } else { 55 ++eit; 56 } 57 } 58 if (entries.empty()) { 59 it = mUptimeEntries.erase(it); 60 } else { 61 ++it; 62 } 63 } 64 } 65 66 // Processes the next message. poll()67 void poll() { 68 auto it = mUptimeEntries.begin(); 69 if (it == mUptimeEntries.end() || it->second.empty()) { 70 return; 71 } 72 auto entry = std::move(it->second.front()); 73 it->second.pop_front(); 74 if (it->second.empty()) { 75 // if entries is empty, erase the uptime from the map. 76 mUptimeEntries.erase(it); 77 } 78 entry.mHandler->handleMessage(entry.mMessage); 79 } 80 81 // Returns the next scheduled message uptime. kNoScheduledMessage if there is no message. getNextMessageUptime()82 nsecs_t getNextMessageUptime() { 83 auto it = mUptimeEntries.begin(); 84 return it == mUptimeEntries.end() ? kNoScheduledMessage : it->first; 85 } 86 87 private: 88 struct LooperEntry { 89 sp<MessageHandler> mHandler; 90 Message mMessage; 91 }; 92 93 private: 94 using Entries = std::deque<LooperEntry>; 95 96 // <uptimeNanos, entries> - where uptimeNanos is time since boot. 97 std::map<nsecs_t, Entries> mUptimeEntries; 98 }; 99 100 } // namespace telemetry 101 } // namespace automotive 102 } // namespace android 103 104 #endif // CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_ 105