1 /* 2 * Copyright 2020 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_WATCHDOG_SERVER_TESTS_LOOPERSTUB_H_ 18 #define CPP_WATCHDOG_SERVER_TESTS_LOOPERSTUB_H_ 19 20 #include <android-base/chrono_utils.h> 21 #include <android-base/result.h> 22 #include <time.h> 23 #include <utils/Looper.h> 24 #include <utils/Mutex.h> 25 #include <utils/StrongPointer.h> 26 27 #include <functional> 28 #include <vector> 29 30 #include "LooperWrapper.h" 31 32 namespace android { 33 namespace automotive { 34 namespace watchdog { 35 namespace testing { 36 37 // LooperStub allows polling the underlying looper deterministically. 38 // NOTE: Current implementation only works for one handler. 39 class LooperStub final : public LooperWrapper { 40 public: LooperStub()41 LooperStub() : mHandler(nullptr), mShouldPoll(false), mTimer(0) {} 42 now()43 nsecs_t now() override { return mTimer.count(); } 44 // No-op when mShouldPoll is false. Otherwise, sends messages (in a non-empty CacheEntry from 45 // the front of |mCache|) to the underlying looper and polls the looper immediately. This 46 // method is called internally by the underlying looper. 47 int pollAll(int timeoutMillis) override; 48 49 // Updates the front of |mCache| with the given message so the next pollAll call to the 50 // underlying looper will poll this message. 51 void sendMessage(const android::sp<MessageHandler>& handler, const Message& message) override; 52 53 // Updates the seconds(uptimeDelay) position in |mCache| with the given message. 54 // Thus |uptimeDelay| should be convertible to seconds without any fractions. uptimeDelay is 55 // computed from (uptime - now). 56 void sendMessageAtTime(nsecs_t uptime, const android::sp<MessageHandler>& handler, 57 const Message& message) override; 58 59 // Removes all the messages from the cache and looper for |mHandler|. 60 void removeMessages(const android::sp<MessageHandler>& handler) override; 61 62 // Removes the |what| message from the cache and looper for |mHandler|. 63 void removeMessages(const android::sp<MessageHandler>& handler, int what) override; 64 65 // Sets |mShouldPoll| so that the subsequent |pollAll| call processes the next non-empty 66 // CacheEntry in |mCache|. Before returning, waits for the pollAll call sent to the underlying 67 // looper to complete. Thus the caller can be certain this message was processed. 68 android::base::Result<void> pollCache(); 69 70 // Number of seconds elapsed since the last pollAll call to the underlying looper. numSecondsElapsed()71 nsecs_t numSecondsElapsed() { 72 return std::chrono::duration_cast<std::chrono::seconds>(mElapsedTime).count(); 73 } 74 75 // Increment time by a specific duration. incrementTime(std::chrono::nanoseconds duration)76 void incrementTime(std::chrono::nanoseconds duration) { mTimer += duration; } 77 78 private: 79 Mutex mMutex; 80 android::sp<MessageHandler> mHandler; 81 using CacheEntry = std::vector<Message>; // Messages to process on a given second. 82 std::vector<CacheEntry> mCache; // Messages pending to be processed. 83 bool mShouldPoll; 84 std::chrono::nanoseconds mTimer; 85 std::chrono::nanoseconds mElapsedTime; 86 }; 87 88 } // namespace testing 89 } // namespace watchdog 90 } // namespace automotive 91 } // namespace android 92 93 #endif // CPP_WATCHDOG_SERVER_TESTS_LOOPERSTUB_H_ 94