blob: 37bdf05445646204964b8110543f5016d9ff0b83 [file] [log] [blame]
Jeff Brown7901eb22010-09-13 23:17:30 -07001//
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
Elliott Hughes01705e42019-02-07 12:41:37 -080012#include <utils/threads.h>
Jeff Brown7901eb22010-09-13 23:17:30 -070013
Steven Morelandc1e04d82019-09-18 12:12:11 -070014// b/141212746 - increased for virtual platforms with higher volatility
Jeff Brown7901eb22010-09-13 23:17:30 -070015// # of milliseconds to fudge stopwatch measurements
Steven Morelandc1e04d82019-09-18 12:12:11 -070016#define TIMING_TOLERANCE_MS 100
Jeff Brown7901eb22010-09-13 23:17:30 -070017
18namespace android {
19
Jeff Brown3e2e38b2011-03-02 14:41:58 -080020enum {
21 MSG_TEST1 = 1,
22 MSG_TEST2 = 2,
23 MSG_TEST3 = 3,
24 MSG_TEST4 = 4,
25};
26
Elliott Hughes01705e42019-02-07 12:41:37 -080027class Pipe {
28public:
29 int sendFd;
30 int receiveFd;
31
32 Pipe() {
33 int fds[2];
34 ::pipe(fds);
35
36 receiveFd = fds[0];
37 sendFd = fds[1];
38 }
39
40 ~Pipe() {
41 if (sendFd != -1) {
42 ::close(sendFd);
43 }
44
45 if (receiveFd != -1) {
46 ::close(receiveFd);
47 }
48 }
49
50 status_t writeSignal() {
51 ssize_t nWritten = ::write(sendFd, "*", 1);
52 return nWritten == 1 ? 0 : -errno;
53 }
54
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
62class DelayedTask : public Thread {
63 int mDelayMillis;
64
65public:
66 explicit DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
67
68protected:
69 virtual ~DelayedTask() { }
70
71 virtual void doTask() = 0;
72
73 virtual bool threadLoop() {
74 usleep(mDelayMillis * 1000);
75 doTask();
76 return false;
77 }
78};
79
Jeff Brown7901eb22010-09-13 23:17:30 -070080class DelayedWake : public DelayedTask {
81 sp<Looper> mLooper;
82
83public:
84 DelayedWake(int delayMillis, const sp<Looper> looper) :
85 DelayedTask(delayMillis), mLooper(looper) {
86 }
87
88protected:
89 virtual void doTask() {
90 mLooper->wake();
91 }
92};
93
94class DelayedWriteSignal : public DelayedTask {
95 Pipe* mPipe;
96
97public:
98 DelayedWriteSignal(int delayMillis, Pipe* pipe) :
99 DelayedTask(delayMillis), mPipe(pipe) {
100 }
101
102protected:
103 virtual void doTask() {
104 mPipe->writeSignal();
105 }
106};
107
108class CallbackHandler {
109public:
110 void setCallback(const sp<Looper>& looper, int fd, int events) {
111 looper->addFd(fd, 0, events, staticHandler, this);
112 }
113
114protected:
115 virtual ~CallbackHandler() { }
116
117 virtual int handler(int fd, int events) = 0;
118
119private:
120 static int staticHandler(int fd, int events, void* data) {
121 return static_cast<CallbackHandler*>(data)->handler(fd, events);
122 }
123};
124
125class StubCallbackHandler : public CallbackHandler {
126public:
127 int nextResult;
128 int callbackCount;
129
130 int fd;
131 int events;
132
Chih-Hung Hsieh034c4752016-07-12 13:50:44 -0700133 explicit StubCallbackHandler(int nextResult) : nextResult(nextResult),
Jeff Brown7901eb22010-09-13 23:17:30 -0700134 callbackCount(0), fd(-1), events(-1) {
135 }
136
137protected:
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
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800146class StubMessageHandler : public MessageHandler {
147public:
148 Vector<Message> messages;
149
150 virtual void handleMessage(const Message& message) {
151 messages.push(message);
152 }
153};
154
Jeff Brown7901eb22010-09-13 23:17:30 -0700155class LooperTest : public testing::Test {
156protected:
157 sp<Looper> mLooper;
158
159 virtual void SetUp() {
160 mLooper = new Looper(true);
161 }
162
163 virtual void TearDown() {
164 mLooper.clear();
165 }
166};
167
168
169TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800176 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
177 << "pollOnce result should be LOOPER_POLL_TIMEOUT";
Jeff Brown7901eb22010-09-13 23:17:30 -0700178}
179
180TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800189 EXPECT_EQ(Looper::POLL_WAKE, result)
190 << "pollOnce result should be Looper::POLL_CALLBACK because loop was awoken";
Jeff Brown7901eb22010-09-13 23:17:30 -0700191}
192
193TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns) {
194 sp<DelayedWake> delayedWake = new DelayedWake(100, mLooper);
Brian Carlstrome71b9142016-03-12 16:08:12 -0800195 delayedWake->run("LooperTest");
Jeff Brown7901eb22010-09-13 23:17:30 -0700196
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800203 EXPECT_EQ(Looper::POLL_WAKE, result)
204 << "pollOnce result should be Looper::POLL_CALLBACK because loop was awoken";
Jeff Brown7901eb22010-09-13 23:17:30 -0700205}
206
207TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800214 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
215 << "pollOnce result should be Looper::POLL_TIMEOUT";
Jeff Brown7901eb22010-09-13 23:17:30 -0700216}
217
218TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns) {
219 Pipe pipe;
220 StubCallbackHandler handler(true);
221
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800222 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Jeff Brown7901eb22010-09-13 23:17:30 -0700223
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800230 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
231 << "pollOnce result should be Looper::POLL_TIMEOUT";
Jeff Brown7901eb22010-09-13 23:17:30 -0700232 EXPECT_EQ(0, handler.callbackCount)
233 << "callback should not have been invoked because FD was not signalled";
234}
235
236TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns) {
237 Pipe pipe;
238 StubCallbackHandler handler(true);
239
240 ASSERT_EQ(OK, pipe.writeSignal());
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800241 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Jeff Brown7901eb22010-09-13 23:17:30 -0700242
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800249 EXPECT_EQ(Looper::POLL_CALLBACK, result)
250 << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
Jeff Brown7901eb22010-09-13 23:17:30 -0700251 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800255 EXPECT_EQ(Looper::EVENT_INPUT, handler.events)
256 << "callback should have received Looper::EVENT_INPUT as events";
Jeff Brown7901eb22010-09-13 23:17:30 -0700257}
258
259TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns) {
260 Pipe pipe;
261 StubCallbackHandler handler(true);
262
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800263 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Jeff Brown7901eb22010-09-13 23:17:30 -0700264
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800271 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
272 << "pollOnce result should be Looper::POLL_TIMEOUT";
Jeff Brown7901eb22010-09-13 23:17:30 -0700273 EXPECT_EQ(0, handler.callbackCount)
274 << "callback should not have been invoked because FD was not signalled";
275}
276
277TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns) {
278 Pipe pipe;
279 StubCallbackHandler handler(true);
280
281 pipe.writeSignal();
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800282 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Jeff Brown7901eb22010-09-13 23:17:30 -0700283
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800292 EXPECT_EQ(Looper::POLL_CALLBACK, result)
293 << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
Jeff Brown7901eb22010-09-13 23:17:30 -0700294 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800298 EXPECT_EQ(Looper::EVENT_INPUT, handler.events)
299 << "callback should have received Looper::EVENT_INPUT as events";
Jeff Brown7901eb22010-09-13 23:17:30 -0700300}
301
302TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns) {
303 Pipe pipe;
304 StubCallbackHandler handler(true);
305 sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);
306
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800307 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Brian Carlstrome71b9142016-03-12 16:08:12 -0800308 delayedWriteSignal->run("LooperTest");
Jeff Brown7901eb22010-09-13 23:17:30 -0700309
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800318 EXPECT_EQ(Looper::POLL_CALLBACK, result)
319 << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
Jeff Brown7901eb22010-09-13 23:17:30 -0700320 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800324 EXPECT_EQ(Looper::EVENT_INPUT, handler.events)
325 << "callback should have received Looper::EVENT_INPUT as events";
Jeff Brown7901eb22010-09-13 23:17:30 -0700326}
327
328TEST_F(LooperTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {
329 Pipe pipe;
330 StubCallbackHandler handler(true);
331
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800332 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Jeff Brown7901eb22010-09-13 23:17:30 -0700333 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800344 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
345 << "pollOnce result should be Looper::POLL_TIMEOUT";
Jeff Brown7901eb22010-09-13 23:17:30 -0700346 EXPECT_EQ(0, handler.callbackCount)
347 << "callback should not be invoked";
348}
349
350TEST_F(LooperTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {
351 Pipe pipe;
352 StubCallbackHandler handler(false);
353
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800354 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Jeff Brown7901eb22010-09-13 23:17:30 -0700355
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800367 EXPECT_EQ(Looper::POLL_CALLBACK, result)
368 << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
Jeff Brown7901eb22010-09-13 23:17:30 -0700369 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800383 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
384 << "pollOnce result should be Looper::POLL_TIMEOUT";
Jeff Brown7901eb22010-09-13 23:17:30 -0700385 EXPECT_EQ(1, handler.callbackCount)
386 << "callback should not be invoked this time";
387}
388
389TEST_F(LooperTest, PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent) {
390 const int expectedIdent = 5;
391 void* expectedData = this;
392
393 Pipe pipe;
394
395 pipe.writeSignal();
Yi Konge1731a42018-07-16 18:11:34 -0700396 mLooper->addFd(pipe.receiveFd, expectedIdent, Looper::EVENT_INPUT, nullptr, expectedData);
Jeff Brown7901eb22010-09-13 23:17:30 -0700397
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800413 EXPECT_EQ(Looper::EVENT_INPUT, events)
414 << "pollOnce should have returned Looper::EVENT_INPUT as events";
Jeff Brown7901eb22010-09-13 23:17:30 -0700415 EXPECT_EQ(expectedData, data)
416 << "pollOnce should have returned the data";
417}
418
419TEST_F(LooperTest, AddFd_WhenCallbackAdded_ReturnsOne) {
420 Pipe pipe;
Yi Konge1731a42018-07-16 18:11:34 -0700421 int result = mLooper->addFd(pipe.receiveFd, 0, Looper::EVENT_INPUT, nullptr, nullptr);
Jeff Brown7901eb22010-09-13 23:17:30 -0700422
423 EXPECT_EQ(1, result)
424 << "addFd should return 1 because FD was added";
425}
426
Jeff Brown7901eb22010-09-13 23:17:30 -0700427TEST_F(LooperTest, AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError) {
428 Pipe pipe;
Yi Konge1731a42018-07-16 18:11:34 -0700429 int result = mLooper->addFd(pipe.receiveFd, -1, Looper::EVENT_INPUT, nullptr, nullptr);
Jeff Brown7901eb22010-09-13 23:17:30 -0700430
431 EXPECT_EQ(-1, result)
432 << "addFd should return -1 because arguments were invalid";
433}
434
435TEST_F(LooperTest, AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError) {
436 Pipe pipe;
437 sp<Looper> looper = new Looper(false /*allowNonCallbacks*/);
Yi Konge1731a42018-07-16 18:11:34 -0700438 int result = looper->addFd(pipe.receiveFd, 0, 0, nullptr, nullptr);
Jeff Brown7901eb22010-09-13 23:17:30 -0700439
440 EXPECT_EQ(-1, result)
441 << "addFd should return -1 because arguments were invalid";
442}
443
444TEST_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
451TEST_F(LooperTest, RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime) {
452 Pipe pipe;
453 StubCallbackHandler handler(false);
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800454 handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
Jeff Brown7901eb22010-09-13 23:17:30 -0700455
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
469TEST_F(LooperTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {
470 Pipe pipe;
471 StubCallbackHandler handler1(true);
472 StubCallbackHandler handler2(true);
473
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800474 handler1.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);
475 handler2.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT); // replace it
Jeff Brown7901eb22010-09-13 23:17:30 -0700476 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800486 EXPECT_EQ(Looper::POLL_CALLBACK, result)
487 << "pollOnce result should be Looper::POLL_CALLBACK because FD was signalled";
Jeff Brown7901eb22010-09-13 23:17:30 -0700488 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
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800494TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800504 EXPECT_EQ(Looper::POLL_CALLBACK, result)
505 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800506 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
512TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800526 EXPECT_EQ(Looper::POLL_CALLBACK, result)
527 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800528 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
542TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800552 EXPECT_EQ(Looper::POLL_WAKE, result)
553 << "pollOnce result should be Looper::POLL_WAKE due to wakeup";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800554 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800566 EXPECT_EQ(Looper::POLL_CALLBACK, result)
567 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800568
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800574 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
575 << "pollOnce result should be Looper::POLL_TIMEOUT because there were no messages left";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800576}
577
578TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800588 EXPECT_EQ(Looper::POLL_CALLBACK, result)
589 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800590 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
596TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800606 EXPECT_EQ(Looper::POLL_CALLBACK, result)
607 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800608 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
614TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800625 EXPECT_EQ(Looper::POLL_WAKE, result)
626 << "pollOnce result should be Looper::POLL_WAKE due to wakeup";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800627 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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800639 EXPECT_EQ(Looper::POLL_CALLBACK, result)
640 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800641
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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800647 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
648 << "pollOnce result should be Looper::POLL_TIMEOUT because there were no messages left";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800649}
650
651TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800662 EXPECT_EQ(Looper::POLL_CALLBACK, result)
663 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800664 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
670TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800681 EXPECT_EQ(Looper::POLL_CALLBACK, result)
682 << "pollOnce result should be Looper::POLL_CALLBACK because message was sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800683 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
689TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800702 EXPECT_EQ(Looper::POLL_WAKE, result)
703 << "pollOnce result should be Looper::POLL_WAKE because looper was awoken";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800704 EXPECT_EQ(size_t(0), handler->messages.size())
705 << "no messages to handle";
706
707 result = mLooper->pollOnce(0);
708
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800709 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
710 << "pollOnce result should be Looper::POLL_TIMEOUT because there was nothing to do";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800711 EXPECT_EQ(size_t(0), handler->messages.size())
712 << "no messages to handle";
713}
714
715TEST_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";
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800730 EXPECT_EQ(Looper::POLL_CALLBACK, result)
731 << "pollOnce result should be Looper::POLL_CALLBACK because two messages were sent";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800732 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
Brian Carlstrom1693d7e2013-12-11 22:46:45 -0800741 EXPECT_EQ(Looper::POLL_TIMEOUT, result)
742 << "pollOnce result should be Looper::POLL_TIMEOUT because there was nothing to do";
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800743 EXPECT_EQ(size_t(2), handler->messages.size())
744 << "no more messages to handle";
745}
Jeff Brown7901eb22010-09-13 23:17:30 -0700746
747} // namespace android