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