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