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