You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.3 KiB
105 lines
3.3 KiB
4 months ago
|
/*
|
||
|
* Copyright (c) 2021, The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#ifndef CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_
|
||
|
#define CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_
|
||
|
|
||
|
#include "LooperWrapper.h"
|
||
|
|
||
|
#include <algorithm>
|
||
|
#include <deque>
|
||
|
#include <map>
|
||
|
|
||
|
namespace android {
|
||
|
namespace automotive {
|
||
|
namespace telemetry {
|
||
|
|
||
|
// Fake `utils/Looper.h` implementation. Explicitly use `FakeLooperWrapper::poll()` method
|
||
|
// to process the messages.
|
||
|
//
|
||
|
// Not thread-safe.
|
||
|
class FakeLooperWrapper : public LooperWrapper {
|
||
|
public:
|
||
|
static inline constexpr int kNoScheduledMessage = -1;
|
||
|
|
||
|
FakeLooperWrapper() : LooperWrapper(nullptr) {}
|
||
|
|
||
|
int pollAll(int timeoutMillis) override { return 0; }
|
||
|
|
||
|
void sendMessageDelayed(nsecs_t uptime, const android::sp<MessageHandler>& handler,
|
||
|
const Message& message) override {
|
||
|
mUptimeEntries[::systemTime() + uptime].push_back(
|
||
|
{.mHandler = handler, .mMessage = message});
|
||
|
}
|
||
|
|
||
|
void removeMessages(const android::sp<MessageHandler>& handler, int what) override {
|
||
|
for (auto it = mUptimeEntries.begin(); it != mUptimeEntries.end();) {
|
||
|
auto [entryUptime, entries] = *it;
|
||
|
for (auto eit = entries.begin(); eit != entries.end();) {
|
||
|
if (eit->mMessage.what == what) {
|
||
|
eit = entries.erase(eit);
|
||
|
} else {
|
||
|
++eit;
|
||
|
}
|
||
|
}
|
||
|
if (entries.empty()) {
|
||
|
it = mUptimeEntries.erase(it);
|
||
|
} else {
|
||
|
++it;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Processes the next message.
|
||
|
void poll() {
|
||
|
auto it = mUptimeEntries.begin();
|
||
|
if (it == mUptimeEntries.end() || it->second.empty()) {
|
||
|
return;
|
||
|
}
|
||
|
auto entry = std::move(it->second.front());
|
||
|
it->second.pop_front();
|
||
|
if (it->second.empty()) {
|
||
|
// if entries is empty, erase the uptime from the map.
|
||
|
mUptimeEntries.erase(it);
|
||
|
}
|
||
|
entry.mHandler->handleMessage(entry.mMessage);
|
||
|
}
|
||
|
|
||
|
// Returns the next scheduled message uptime. kNoScheduledMessage if there is no message.
|
||
|
nsecs_t getNextMessageUptime() {
|
||
|
auto it = mUptimeEntries.begin();
|
||
|
return it == mUptimeEntries.end() ? kNoScheduledMessage : it->first;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
struct LooperEntry {
|
||
|
sp<MessageHandler> mHandler;
|
||
|
Message mMessage;
|
||
|
};
|
||
|
|
||
|
private:
|
||
|
using Entries = std::deque<LooperEntry>;
|
||
|
|
||
|
// <uptimeNanos, entries> - where uptimeNanos is time since boot.
|
||
|
std::map<nsecs_t, Entries> mUptimeEntries;
|
||
|
};
|
||
|
|
||
|
} // namespace telemetry
|
||
|
} // namespace automotive
|
||
|
} // namespace android
|
||
|
|
||
|
#endif // CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_
|