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