1 //
2 // Copyright 2010 The Android Open Source Project
3 //
4 
5 #include <gtest/gtest.h>
6 #include <time.h>
7 #include <unistd.h>
8 #include <utils/Looper.h>
9 #include <utils/StopWatch.h>
10 #include <utils/Timers.h>
11 #include <thread>
12 #include <unordered_map>
13 #include <utility>
14 #include "Looper_test_pipe.h"
15 
16 #include <utils/threads.h>
17 
18 // b/141212746 - increased for virtual platforms with higher volatility
19 // # of milliseconds to fudge stopwatch measurements
20 #define TIMING_TOLERANCE_MS 100
21 
22 namespace android {
23 
24 enum {
25     MSG_TEST1 = 1,
26     MSG_TEST2 = 2,
27     MSG_TEST3 = 3,
28     MSG_TEST4 = 4,
29 };
30 
31 class DelayedTask : public Thread {
32     int mDelayMillis;
33 
34 public:
DelayedTask(int delayMillis)35     explicit DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
36 
37 protected:
~DelayedTask()38     virtual ~DelayedTask() { }
39 
40     virtual void doTask() = 0;
41 
threadLoop()42     virtual bool threadLoop() {
43         usleep(mDelayMillis * 1000);
44         doTask();
45         return false;
46     }
47 };
48 
49 class DelayedWake : public DelayedTask {
50     sp<Looper> mLooper;
51 
52 public:
DelayedWake(int delayMillis,const sp<Looper> looper)53     DelayedWake(int delayMillis, const sp<Looper> looper) :
54         DelayedTask(delayMillis), mLooper(looper) {
55     }
56 
57 protected:
doTask()58     virtual void doTask() {
59         mLooper->wake();
60     }
61 };
62 
63 class DelayedWriteSignal : public DelayedTask {
64     Pipe* mPipe;
65 
66 public:
DelayedWriteSignal(int delayMillis,Pipe * pipe)67     DelayedWriteSignal(int delayMillis, Pipe* pipe) :
68         DelayedTask(delayMillis), mPipe(pipe) {
69     }
70 
71 protected:
doTask()72     virtual void doTask() {
73         mPipe->writeSignal();
74     }
75 };
76 
77 class CallbackHandler {
78 public:
setCallback(const sp<Looper> & looper,int fd,int events)79     void setCallback(const sp<Looper>& looper, int fd, int events) {
80         looper->addFd(fd, 0, events, staticHandler, this);
81     }
82 
83 protected:
~CallbackHandler()84     virtual ~CallbackHandler() { }
85 
86     virtual int handler(int fd, int events) = 0;
87 
88 private:
staticHandler(int fd,int events,void * data)89     static int staticHandler(int fd, int events, void* data) {
90         return static_cast<CallbackHandler*>(data)->handler(fd, events);
91     }
92 };
93 
94 class StubCallbackHandler : public CallbackHandler {
95 public:
96     int nextResult;
97     int callbackCount;
98 
99     int fd;
100     int events;
101 
StubCallbackHandler(int nextResult)102     explicit StubCallbackHandler(int nextResult) : nextResult(nextResult),
103             callbackCount(0), fd(-1), events(-1) {
104     }
105 
106 protected:
handler(int fd,int events)107     virtual int handler(int fd, int events) {
108         callbackCount += 1;
109         this->fd = fd;
110         this->events = events;
111         return nextResult;
112     }
113 };
114 
115 class StubMessageHandler : public MessageHandler {
116 public:
117     Vector<Message> messages;
118 
handleMessage(const Message & message)119     virtual void handleMessage(const Message& message) {
120         messages.push(message);
121     }
122 };
123 
124 class LooperTest : public testing::Test {
125 protected:
126     sp<Looper> mLooper;
127 
SetUp()128     virtual void SetUp() {
129         mLooper = new Looper(true);
130     }
131 
TearDown()132     virtual void TearDown() {
133         mLooper.clear();
134     }
135 };
136 
137 
TEST_F(LooperTest,PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeout)138 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeout) {
139     StopWatch stopWatch("pollOnce");
140     int result = mLooper->pollOnce(100);
141     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
142 
143     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
144             << "elapsed time should approx. equal timeout";
145     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
146             << "pollOnce result should be LOOPER_POLL_TIMEOUT";
147 }
148 
TEST_F(LooperTest,PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturns)149 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturns) {
150     mLooper->wake();
151 
152     StopWatch stopWatch("pollOnce");
153     int result = mLooper->pollOnce(1000);
154     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
155 
156     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
157             << "elapsed time should approx. zero because wake() was called before waiting";
158     EXPECT_EQ(Looper::POLL_WAKE, result)
159             << "pollOnce result should be Looper::POLL_CALLBACK because loop was awoken";
160 }
161 
TEST_F(LooperTest,PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns)162 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns) {
163     sp<DelayedWake> delayedWake = new DelayedWake(100, mLooper);
164     delayedWake->run("LooperTest");
165 
166     StopWatch stopWatch("pollOnce");
167     int result = mLooper->pollOnce(1000);
168     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
169 
170     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
171             << "elapsed time should approx. equal wake delay";
172     EXPECT_EQ(Looper::POLL_WAKE, result)
173             << "pollOnce result should be Looper::POLL_CALLBACK because loop was awoken";
174 }
175 
TEST_F(LooperTest,PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturns)176 TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturns) {
177     StopWatch stopWatch("pollOnce");
178     int result = mLooper->pollOnce(0);
179     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
180 
181     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
182             << "elapsed time should be approx. zero";
183     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
184             << "pollOnce result should be Looper::POLL_TIMEOUT";
185 }
186 
TEST_F(LooperTest,PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns)187 TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns) {
188     Pipe pipe;
189     StubCallbackHandler handler(true);
190 
191     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
192 
193     StopWatch stopWatch("pollOnce");
194     int result = mLooper->pollOnce(0);
195     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
196 
197     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
198             << "elapsed time should be approx. zero";
199     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
200             << "pollOnce result should be Looper::POLL_TIMEOUT";
201     EXPECT_EQ(0, handler.callbackCount)
202             << "callback should not have been invoked because FD was not signalled";
203 }
204 
TEST_F(LooperTest,PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns)205 TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns) {
206     Pipe pipe;
207     StubCallbackHandler handler(true);
208 
209     ASSERT_EQ(OK, pipe.writeSignal());
210     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
211 
212     StopWatch stopWatch("pollOnce");
213     int result = mLooper->pollOnce(0);
214     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
215 
216     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
217             << "elapsed time should be approx. zero";
218     EXPECT_EQ(Looper::POLL_CALLBACK, result)
219             << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
220     EXPECT_EQ(1, handler.callbackCount)
221             << "callback should be invoked exactly once";
222     EXPECT_EQ(pipe.receiveFd, handler.fd)
223             << "callback should have received pipe fd as parameter";
224     EXPECT_EQ(Looper::EVENT_INPUT, handler.events)
225             << "callback should have received Looper::EVENT_INPUT as events";
226 }
227 
TEST_F(LooperTest,PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns)228 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns) {
229     Pipe pipe;
230     StubCallbackHandler handler(true);
231 
232     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
233 
234     StopWatch stopWatch("pollOnce");
235     int result = mLooper->pollOnce(100);
236     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
237 
238     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
239             << "elapsed time should approx. equal timeout";
240     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
241             << "pollOnce result should be Looper::POLL_TIMEOUT";
242     EXPECT_EQ(0, handler.callbackCount)
243             << "callback should not have been invoked because FD was not signalled";
244 }
245 
TEST_F(LooperTest,PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns)246 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns) {
247     Pipe pipe;
248     StubCallbackHandler handler(true);
249 
250     pipe.writeSignal();
251     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
252 
253     StopWatch stopWatch("pollOnce");
254     int result = mLooper->pollOnce(100);
255     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
256 
257     ASSERT_EQ(OK, pipe.readSignal())
258             << "signal should actually have been written";
259     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
260             << "elapsed time should be approx. zero";
261     EXPECT_EQ(Looper::POLL_CALLBACK, result)
262             << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
263     EXPECT_EQ(1, handler.callbackCount)
264             << "callback should be invoked exactly once";
265     EXPECT_EQ(pipe.receiveFd, handler.fd)
266             << "callback should have received pipe fd as parameter";
267     EXPECT_EQ(Looper::EVENT_INPUT, handler.events)
268             << "callback should have received Looper::EVENT_INPUT as events";
269 }
270 
TEST_F(LooperTest,PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns)271 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns) {
272     Pipe pipe;
273     StubCallbackHandler handler(true);
274     sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);
275 
276     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
277     delayedWriteSignal->run("LooperTest");
278 
279     StopWatch stopWatch("pollOnce");
280     int result = mLooper->pollOnce(1000);
281     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
282 
283     ASSERT_EQ(OK, pipe.readSignal())
284             << "signal should actually have been written";
285     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
286             << "elapsed time should approx. equal signal delay";
287     EXPECT_EQ(Looper::POLL_CALLBACK, result)
288             << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
289     EXPECT_EQ(1, handler.callbackCount)
290             << "callback should be invoked exactly once";
291     EXPECT_EQ(pipe.receiveFd, handler.fd)
292             << "callback should have received pipe fd as parameter";
293     EXPECT_EQ(Looper::EVENT_INPUT, handler.events)
294             << "callback should have received Looper::EVENT_INPUT as events";
295 }
296 
TEST_F(LooperTest,PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked)297 TEST_F(LooperTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {
298     Pipe pipe;
299     StubCallbackHandler handler(true);
300 
301     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
302     pipe.writeSignal(); // would cause FD to be considered signalled
303     mLooper->removeFd(pipe.receiveFd);
304 
305     StopWatch stopWatch("pollOnce");
306     int result = mLooper->pollOnce(100);
307     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
308 
309     ASSERT_EQ(OK, pipe.readSignal())
310             << "signal should actually have been written";
311     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
312             << "elapsed time should approx. equal timeout because FD was no longer registered";
313     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
314             << "pollOnce result should be Looper::POLL_TIMEOUT";
315     EXPECT_EQ(0, handler.callbackCount)
316             << "callback should not be invoked";
317 }
318 
TEST_F(LooperTest,PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater)319 TEST_F(LooperTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {
320     Pipe pipe;
321     StubCallbackHandler handler(false);
322 
323     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
324 
325     // First loop: Callback is registered and FD is signalled.
326     pipe.writeSignal();
327 
328     StopWatch stopWatch("pollOnce");
329     int result = mLooper->pollOnce(0);
330     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
331 
332     ASSERT_EQ(OK, pipe.readSignal())
333             << "signal should actually have been written";
334     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
335             << "elapsed time should approx. equal zero because FD was already signalled";
336     EXPECT_EQ(Looper::POLL_CALLBACK, result)
337             << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
338     EXPECT_EQ(1, handler.callbackCount)
339             << "callback should be invoked";
340 
341     // Second loop: Callback is no longer registered and FD is signalled.
342     pipe.writeSignal();
343 
344     stopWatch.reset();
345     result = mLooper->pollOnce(0);
346     elapsedMillis = ns2ms(stopWatch.elapsedTime());
347 
348     ASSERT_EQ(OK, pipe.readSignal())
349             << "signal should actually have been written";
350     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
351             << "elapsed time should approx. equal zero because timeout was zero";
352     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
353             << "pollOnce result should be Looper::POLL_TIMEOUT";
354     EXPECT_EQ(1, handler.callbackCount)
355             << "callback should not be invoked this time";
356 }
357 
TEST_F(LooperTest,PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent)358 TEST_F(LooperTest, PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent) {
359     const int expectedIdent = 5;
360     void* expectedData = this;
361 
362     Pipe pipe;
363 
364     pipe.writeSignal();
365     mLooper->addFd(pipe.receiveFd, expectedIdent, Looper::EVENT_INPUT, nullptr, expectedData);
366 
367     StopWatch stopWatch("pollOnce");
368     int fd;
369     int events;
370     void* data;
371     int result = mLooper->pollOnce(100, &fd, &events, &data);
372     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
373 
374     ASSERT_EQ(OK, pipe.readSignal())
375             << "signal should actually have been written";
376     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
377             << "elapsed time should be approx. zero";
378     EXPECT_EQ(expectedIdent, result)
379             << "pollOnce result should be the ident of the FD that was signalled";
380     EXPECT_EQ(pipe.receiveFd, fd)
381             << "pollOnce should have returned the received pipe fd";
382     EXPECT_EQ(Looper::EVENT_INPUT, events)
383             << "pollOnce should have returned Looper::EVENT_INPUT as events";
384     EXPECT_EQ(expectedData, data)
385             << "pollOnce should have returned the data";
386 }
387 
TEST_F(LooperTest,AddFd_WhenCallbackAdded_ReturnsOne)388 TEST_F(LooperTest, AddFd_WhenCallbackAdded_ReturnsOne) {
389     Pipe pipe;
390     int result = mLooper->addFd(pipe.receiveFd, 0, Looper::EVENT_INPUT, nullptr, nullptr);
391 
392     EXPECT_EQ(1, result)
393             << "addFd should return 1 because FD was added";
394 }
395 
TEST_F(LooperTest,AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError)396 TEST_F(LooperTest, AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError) {
397     Pipe pipe;
398     int result = mLooper->addFd(pipe.receiveFd, -1, Looper::EVENT_INPUT, nullptr, nullptr);
399 
400     EXPECT_EQ(-1, result)
401             << "addFd should return -1 because arguments were invalid";
402 }
403 
TEST_F(LooperTest,AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError)404 TEST_F(LooperTest, AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError) {
405     Pipe pipe;
406     sp<Looper> looper = new Looper(false /*allowNonCallbacks*/);
407     int result = looper->addFd(pipe.receiveFd, 0, 0, nullptr, nullptr);
408 
409     EXPECT_EQ(-1, result)
410             << "addFd should return -1 because arguments were invalid";
411 }
412 
TEST_F(LooperTest,RemoveFd_WhenCallbackNotAdded_ReturnsZero)413 TEST_F(LooperTest, RemoveFd_WhenCallbackNotAdded_ReturnsZero) {
414     int result = mLooper->removeFd(1);
415 
416     EXPECT_EQ(0, result)
417             << "removeFd should return 0 because FD not registered";
418 }
419 
TEST_F(LooperTest,RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime)420 TEST_F(LooperTest, RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime) {
421     Pipe pipe;
422     StubCallbackHandler handler(false);
423     handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
424 
425     // First time.
426     int result = mLooper->removeFd(pipe.receiveFd);
427 
428     EXPECT_EQ(1, result)
429             << "removeFd should return 1 first time because FD was registered";
430 
431     // Second time.
432     result = mLooper->removeFd(pipe.receiveFd);
433 
434     EXPECT_EQ(0, result)
435             << "removeFd should return 0 second time because FD was no longer registered";
436 }
437 
TEST_F(LooperTest,PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked)438 TEST_F(LooperTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {
439     Pipe pipe;
440     StubCallbackHandler handler1(true);
441     StubCallbackHandler handler2(true);
442 
443     handler1.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
444     handler2.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT); // replace it
445     pipe.writeSignal(); // would cause FD to be considered signalled
446 
447     StopWatch stopWatch("pollOnce");
448     int result = mLooper->pollOnce(100);
449     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
450 
451     ASSERT_EQ(OK, pipe.readSignal())
452             << "signal should actually have been written";
453     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
454             << "elapsed time should approx. zero because FD was already signalled";
455     EXPECT_EQ(Looper::POLL_CALLBACK, result)
456             << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
457     EXPECT_EQ(0, handler1.callbackCount)
458             << "original handler callback should not be invoked because it was replaced";
459     EXPECT_EQ(1, handler2.callbackCount)
460             << "replacement handler callback should be invoked";
461 }
462 
TEST_F(LooperTest,SendMessage_WhenOneMessageIsEnqueue_ShouldInvokeHandlerDuringNextPoll)463 TEST_F(LooperTest, SendMessage_WhenOneMessageIsEnqueue_ShouldInvokeHandlerDuringNextPoll) {
464     sp<StubMessageHandler> handler = new StubMessageHandler();
465     mLooper->sendMessage(handler, Message(MSG_TEST1));
466 
467     StopWatch stopWatch("pollOnce");
468     int result = mLooper->pollOnce(100);
469     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
470 
471     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
472             << "elapsed time should approx. zero because message was already sent";
473     EXPECT_EQ(Looper::POLL_CALLBACK, result)
474             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
475     EXPECT_EQ(size_t(1), handler->messages.size())
476             << "handled message";
477     EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
478             << "handled message";
479 }
480 
TEST_F(LooperTest,SendMessage_WhenMultipleMessagesAreEnqueued_ShouldInvokeHandlersInOrderDuringNextPoll)481 TEST_F(LooperTest, SendMessage_WhenMultipleMessagesAreEnqueued_ShouldInvokeHandlersInOrderDuringNextPoll) {
482     sp<StubMessageHandler> handler1 = new StubMessageHandler();
483     sp<StubMessageHandler> handler2 = new StubMessageHandler();
484     mLooper->sendMessage(handler1, Message(MSG_TEST1));
485     mLooper->sendMessage(handler2, Message(MSG_TEST2));
486     mLooper->sendMessage(handler1, Message(MSG_TEST3));
487     mLooper->sendMessage(handler1, Message(MSG_TEST4));
488 
489     StopWatch stopWatch("pollOnce");
490     int result = mLooper->pollOnce(1000);
491     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
492 
493     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
494             << "elapsed time should approx. zero because message was already sent";
495     EXPECT_EQ(Looper::POLL_CALLBACK, result)
496             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
497     EXPECT_EQ(size_t(3), handler1->messages.size())
498             << "handled message";
499     EXPECT_EQ(MSG_TEST1, handler1->messages[0].what)
500             << "handled message";
501     EXPECT_EQ(MSG_TEST3, handler1->messages[1].what)
502             << "handled message";
503     EXPECT_EQ(MSG_TEST4, handler1->messages[2].what)
504             << "handled message";
505     EXPECT_EQ(size_t(1), handler2->messages.size())
506             << "handled message";
507     EXPECT_EQ(MSG_TEST2, handler2->messages[0].what)
508             << "handled message";
509 }
510 
TEST_F(LooperTest,SendMessageDelayed_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime)511 TEST_F(LooperTest, SendMessageDelayed_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {
512     sp<StubMessageHandler> handler = new StubMessageHandler();
513     mLooper->sendMessageDelayed(ms2ns(100), handler, Message(MSG_TEST1));
514 
515     StopWatch stopWatch("pollOnce");
516     int result = mLooper->pollOnce(1000);
517     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
518 
519     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
520             << "first poll should end quickly because next message timeout was computed";
521     EXPECT_EQ(Looper::POLL_WAKE, result)
522             << "pollOnce result should be Looper::POLL_WAKE due to wakeup";
523     EXPECT_EQ(size_t(0), handler->messages.size())
524             << "no message handled yet";
525 
526     result = mLooper->pollOnce(1000);
527     elapsedMillis = ns2ms(stopWatch.elapsedTime());
528 
529     EXPECT_EQ(size_t(1), handler->messages.size())
530             << "handled message";
531     EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
532             << "handled message";
533     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
534             << "second poll should end around the time of the delayed message dispatch";
535     EXPECT_EQ(Looper::POLL_CALLBACK, result)
536             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
537 
538     result = mLooper->pollOnce(100);
539     elapsedMillis = ns2ms(stopWatch.elapsedTime());
540 
541     EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)
542             << "third poll should timeout";
543     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
544             << "pollOnce result should be Looper::POLL_TIMEOUT because there were no messages left";
545 }
546 
TEST_F(LooperTest,SendMessageDelayed_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll)547 TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {
548     sp<StubMessageHandler> handler = new StubMessageHandler();
549     mLooper->sendMessageDelayed(ms2ns(-1000), handler, Message(MSG_TEST1));
550 
551     StopWatch stopWatch("pollOnce");
552     int result = mLooper->pollOnce(100);
553     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
554 
555     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
556             << "elapsed time should approx. zero because message was already sent";
557     EXPECT_EQ(Looper::POLL_CALLBACK, result)
558             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
559     EXPECT_EQ(size_t(1), handler->messages.size())
560             << "handled message";
561     EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
562             << "handled message";
563 }
564 
TEST_F(LooperTest,SendMessageDelayed_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll)565 TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {
566     sp<StubMessageHandler> handler = new StubMessageHandler();
567     mLooper->sendMessageDelayed(0, handler, Message(MSG_TEST1));
568 
569     StopWatch stopWatch("pollOnce");
570     int result = mLooper->pollOnce(100);
571     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
572 
573     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
574             << "elapsed time should approx. zero because message was already sent";
575     EXPECT_EQ(Looper::POLL_CALLBACK, result)
576             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
577     EXPECT_EQ(size_t(1), handler->messages.size())
578             << "handled message";
579     EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
580             << "handled message";
581 }
582 
TEST_F(LooperTest,SendMessageAtTime_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime)583 TEST_F(LooperTest, SendMessageAtTime_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {
584     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
585     sp<StubMessageHandler> handler = new StubMessageHandler();
586     mLooper->sendMessageAtTime(now + ms2ns(100), handler, Message(MSG_TEST1));
587 
588     StopWatch stopWatch("pollOnce");
589     int result = mLooper->pollOnce(1000);
590     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
591 
592     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
593             << "first poll should end quickly because next message timeout was computed";
594     EXPECT_EQ(Looper::POLL_WAKE, result)
595             << "pollOnce result should be Looper::POLL_WAKE due to wakeup";
596     EXPECT_EQ(size_t(0), handler->messages.size())
597             << "no message handled yet";
598 
599     result = mLooper->pollOnce(1000);
600     elapsedMillis = ns2ms(stopWatch.elapsedTime());
601 
602     EXPECT_EQ(size_t(1), handler->messages.size())
603             << "handled message";
604     EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
605             << "handled message";
606     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
607             << "second poll should end around the time of the delayed message dispatch";
608     EXPECT_EQ(Looper::POLL_CALLBACK, result)
609             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
610 
611     result = mLooper->pollOnce(100);
612     elapsedMillis = ns2ms(stopWatch.elapsedTime());
613 
614     EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)
615             << "third poll should timeout";
616     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
617             << "pollOnce result should be Looper::POLL_TIMEOUT because there were no messages left";
618 }
619 
TEST_F(LooperTest,SendMessageAtTime_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll)620 TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {
621     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
622     sp<StubMessageHandler> handler = new StubMessageHandler();
623     mLooper->sendMessageAtTime(now - ms2ns(1000), handler, Message(MSG_TEST1));
624 
625     StopWatch stopWatch("pollOnce");
626     int result = mLooper->pollOnce(100);
627     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
628 
629     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
630             << "elapsed time should approx. zero because message was already sent";
631     EXPECT_EQ(Looper::POLL_CALLBACK, result)
632             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
633     EXPECT_EQ(size_t(1), handler->messages.size())
634             << "handled message";
635     EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
636             << "handled message";
637 }
638 
TEST_F(LooperTest,SendMessageAtTime_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll)639 TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {
640     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
641     sp<StubMessageHandler> handler = new StubMessageHandler();
642     mLooper->sendMessageAtTime(now, handler, Message(MSG_TEST1));
643 
644     StopWatch stopWatch("pollOnce");
645     int result = mLooper->pollOnce(100);
646     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
647 
648     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
649             << "elapsed time should approx. zero because message was already sent";
650     EXPECT_EQ(Looper::POLL_CALLBACK, result)
651             << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
652     EXPECT_EQ(size_t(1), handler->messages.size())
653             << "handled message";
654     EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
655             << "handled message";
656 }
657 
TEST_F(LooperTest,RemoveMessage_WhenRemovingAllMessagesForHandler_ShouldRemoveThoseMessage)658 TEST_F(LooperTest, RemoveMessage_WhenRemovingAllMessagesForHandler_ShouldRemoveThoseMessage) {
659     sp<StubMessageHandler> handler = new StubMessageHandler();
660     mLooper->sendMessage(handler, Message(MSG_TEST1));
661     mLooper->sendMessage(handler, Message(MSG_TEST2));
662     mLooper->sendMessage(handler, Message(MSG_TEST3));
663     mLooper->removeMessages(handler);
664 
665     StopWatch stopWatch("pollOnce");
666     int result = mLooper->pollOnce(0);
667     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
668 
669     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
670             << "elapsed time should approx. zero because message was sent so looper was awoken";
671     EXPECT_EQ(Looper::POLL_WAKE, result)
672             << "pollOnce result should be Looper::POLL_WAKE because looper was awoken";
673     EXPECT_EQ(size_t(0), handler->messages.size())
674             << "no messages to handle";
675 
676     result = mLooper->pollOnce(0);
677 
678     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
679             << "pollOnce result should be Looper::POLL_TIMEOUT because there was nothing to do";
680     EXPECT_EQ(size_t(0), handler->messages.size())
681             << "no messages to handle";
682 }
683 
TEST_F(LooperTest,RemoveMessage_WhenRemovingSomeMessagesForHandler_ShouldRemoveThoseMessage)684 TEST_F(LooperTest, RemoveMessage_WhenRemovingSomeMessagesForHandler_ShouldRemoveThoseMessage) {
685     sp<StubMessageHandler> handler = new StubMessageHandler();
686     mLooper->sendMessage(handler, Message(MSG_TEST1));
687     mLooper->sendMessage(handler, Message(MSG_TEST2));
688     mLooper->sendMessage(handler, Message(MSG_TEST3));
689     mLooper->sendMessage(handler, Message(MSG_TEST4));
690     mLooper->removeMessages(handler, MSG_TEST3);
691     mLooper->removeMessages(handler, MSG_TEST1);
692 
693     StopWatch stopWatch("pollOnce");
694     int result = mLooper->pollOnce(0);
695     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
696 
697     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
698             << "elapsed time should approx. zero because message was sent so looper was awoken";
699     EXPECT_EQ(Looper::POLL_CALLBACK, result)
700             << "pollOnce result should be Looper::POLL_CALLBACK because two messages were sent";
701     EXPECT_EQ(size_t(2), handler->messages.size())
702             << "no messages to handle";
703     EXPECT_EQ(MSG_TEST2, handler->messages[0].what)
704             << "handled message";
705     EXPECT_EQ(MSG_TEST4, handler->messages[1].what)
706             << "handled message";
707 
708     result = mLooper->pollOnce(0);
709 
710     EXPECT_EQ(Looper::POLL_TIMEOUT, result)
711             << "pollOnce result should be Looper::POLL_TIMEOUT because there was nothing to do";
712     EXPECT_EQ(size_t(2), handler->messages.size())
713             << "no more messages to handle";
714 }
715 
716 class LooperEventCallback : public LooperCallback {
717   public:
718     using Callback = std::function<int(int fd, int events)>;
LooperEventCallback(Callback callback)719     explicit LooperEventCallback(Callback callback) : mCallback(std::move(callback)) {}
handleEvent(int fd,int events,void *)720     int handleEvent(int fd, int events, void* /*data*/) override { return mCallback(fd, events); }
721 
722   private:
723     Callback mCallback;
724 };
725 
726 // A utility class that allows for pipes to be added and removed from the looper, and polls the
727 // looper from a different thread.
728 class ThreadedLooperUtil {
729   public:
ThreadedLooperUtil(const sp<Looper> & looper)730     explicit ThreadedLooperUtil(const sp<Looper>& looper) : mLooper(looper), mRunning(true) {
731         mThread = std::thread([this]() {
732             while (mRunning) {
733                 static constexpr std::chrono::milliseconds POLL_TIMEOUT(500);
734                 mLooper->pollOnce(POLL_TIMEOUT.count());
735             }
736         });
737     }
738 
~ThreadedLooperUtil()739     ~ThreadedLooperUtil() {
740         mRunning = false;
741         mThread.join();
742     }
743 
744     // Create a new pipe, and return the write end of the pipe and the id used to track the pipe.
745     // The read end of the pipe is added to the looper.
createPipe()746     std::pair<int /*id*/, base::unique_fd> createPipe() {
747         int pipeFd[2];
748         if (pipe(pipeFd)) {
749             ADD_FAILURE() << "pipe() failed.";
750             return {};
751         }
752         const int readFd = pipeFd[0];
753         const int writeFd = pipeFd[1];
754 
755         int id;
756         {  // acquire lock
757             std::scoped_lock l(mLock);
758 
759             id = mNextId++;
760             mFds.emplace(id, readFd);
761 
762             auto removeCallback = [this, id, readFd](int fd, int events) {
763                 EXPECT_EQ(readFd, fd) << "Received callback for incorrect fd.";
764                 if ((events & Looper::EVENT_HANGUP) == 0) {
765                     return 1;  // Not a hangup, keep the callback.
766                 }
767                 removePipe(id);
768                 return 0;  // Remove the callback.
769             };
770 
771             mLooper->addFd(readFd, 0, Looper::EVENT_INPUT,
772                            new LooperEventCallback(std::move(removeCallback)), nullptr);
773         }  // release lock
774 
775         return {id, base::unique_fd(writeFd)};
776     }
777 
778     // Remove the pipe with the given id.
removePipe(int id)779     void removePipe(int id) {
780         std::scoped_lock l(mLock);
781         if (mFds.find(id) == mFds.end()) {
782             return;
783         }
784         mLooper->removeFd(mFds[id].get());
785         mFds.erase(id);
786     }
787 
788     // Check if the pipe with the given id exists and has not been removed.
hasPipe(int id)789     bool hasPipe(int id) {
790         std::scoped_lock l(mLock);
791         return mFds.find(id) != mFds.end();
792     }
793 
794   private:
795     sp<Looper> mLooper;
796     std::atomic<bool> mRunning;
797     std::thread mThread;
798 
799     std::mutex mLock;
800     std::unordered_map<int, base::unique_fd> mFds GUARDED_BY(mLock);
801     int mNextId GUARDED_BY(mLock) = 0;
802 };
803 
TEST_F(LooperTest,MultiThreaded_NoUnexpectedFdRemoval)804 TEST_F(LooperTest, MultiThreaded_NoUnexpectedFdRemoval) {
805     ThreadedLooperUtil util(mLooper);
806 
807     // Iterate repeatedly to try to recreate a flaky instance.
808     for (int i = 0; i < 1000; i++) {
809         auto [firstPipeId, firstPipeFd] = util.createPipe();
810         const int firstFdNumber = firstPipeFd.get();
811 
812         // Close the first pipe's fd, causing a fd hangup.
813         firstPipeFd.reset();
814 
815         // Request to remove the pipe from this test thread. This causes a race for pipe removal
816         // between the hangup in the looper's thread and this remove request from the test thread.
817         util.removePipe(firstPipeId);
818 
819         // Create the second pipe. Since the fds for the first pipe are closed, this pipe should
820         // have the same fd numbers as the first pipe because the lowest unused fd number is used.
821         const auto [secondPipeId, fd] = util.createPipe();
822         EXPECT_EQ(firstFdNumber, fd.get())
823                 << "The first and second fds must match for the purposes of this test.";
824 
825         // Wait for unexpected hangup to occur.
826         std::this_thread::sleep_for(std::chrono::milliseconds(1));
827 
828         ASSERT_TRUE(util.hasPipe(secondPipeId)) << "The second pipe was removed unexpectedly.";
829 
830         util.removePipe(secondPipeId);
831     }
832     SUCCEED() << "No unexpectedly removed fds.";
833 }
834 
835 } // namespace android
836