1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/events/platform/platform_event_source.h" 6 7#include "base/bind.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/memory/scoped_vector.h" 10#include "base/message_loop/message_loop.h" 11#include "base/run_loop.h" 12#include "testing/gtest/include/gtest/gtest.h" 13#include "ui/events/platform/platform_event_dispatcher.h" 14#include "ui/events/platform/platform_event_observer.h" 15#include "ui/events/platform/scoped_event_dispatcher.h" 16 17namespace ui { 18 19namespace { 20 21scoped_ptr<PlatformEvent> CreatePlatformEvent() { 22 scoped_ptr<PlatformEvent> event(new PlatformEvent()); 23 memset(event.get(), 0, sizeof(PlatformEvent)); 24 return event.Pass(); 25} 26 27template <typename T> 28void DestroyScopedPtr(scoped_ptr<T> object) {} 29 30void RemoveDispatcher(PlatformEventDispatcher* dispatcher) { 31 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(dispatcher); 32} 33 34void RemoveDispatchers(PlatformEventDispatcher* first, 35 PlatformEventDispatcher* second) { 36 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(first); 37 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(second); 38} 39 40void AddDispatcher(PlatformEventDispatcher* dispatcher) { 41 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(dispatcher); 42} 43 44} // namespace 45 46class TestPlatformEventSource : public PlatformEventSource { 47 public: 48 TestPlatformEventSource() 49 : stop_stream_(false) { 50 } 51 virtual ~TestPlatformEventSource() {} 52 53 uint32_t Dispatch(const PlatformEvent& event) { return DispatchEvent(event); } 54 55 // Dispatches the stream of events, and returns the number of events that are 56 // dispatched before it is requested to stop. 57 size_t DispatchEventStream(const ScopedVector<PlatformEvent>& events) { 58 stop_stream_ = false; 59 for (size_t count = 0; count < events.size(); ++count) { 60 DispatchEvent(*events[count]); 61 if (stop_stream_) 62 return count + 1; 63 } 64 return events.size(); 65 } 66 67 // PlatformEventSource: 68 virtual void StopCurrentEventStream() OVERRIDE { 69 stop_stream_ = true; 70 } 71 72 private: 73 bool stop_stream_; 74 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventSource); 75}; 76 77class TestPlatformEventDispatcher : public PlatformEventDispatcher { 78 public: 79 TestPlatformEventDispatcher(int id, std::vector<int>* list) 80 : id_(id), 81 list_(list), 82 post_dispatch_action_(POST_DISPATCH_NONE), 83 stop_stream_(false) { 84 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); 85 } 86 virtual ~TestPlatformEventDispatcher() { 87 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); 88 } 89 90 void set_post_dispatch_action(uint32_t action) { 91 post_dispatch_action_ = action; 92 } 93 94 protected: 95 // PlatformEventDispatcher: 96 virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE { 97 return true; 98 } 99 100 virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE { 101 list_->push_back(id_); 102 return post_dispatch_action_; 103 } 104 105 private: 106 int id_; 107 std::vector<int>* list_; 108 uint32_t post_dispatch_action_; 109 bool stop_stream_; 110 111 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventDispatcher); 112}; 113 114class TestPlatformEventObserver : public PlatformEventObserver { 115 public: 116 TestPlatformEventObserver(int id, std::vector<int>* list) 117 : id_(id), list_(list) { 118 PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); 119 } 120 virtual ~TestPlatformEventObserver() { 121 PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); 122 } 123 124 protected: 125 // PlatformEventObserver: 126 virtual void WillProcessEvent(const PlatformEvent& event) OVERRIDE { 127 list_->push_back(id_); 128 } 129 130 virtual void DidProcessEvent(const PlatformEvent& event) OVERRIDE {} 131 132 private: 133 int id_; 134 std::vector<int>* list_; 135 136 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventObserver); 137}; 138 139class PlatformEventTest : public testing::Test { 140 public: 141 PlatformEventTest() {} 142 virtual ~PlatformEventTest() {} 143 144 TestPlatformEventSource* source() { return source_.get(); } 145 146 protected: 147 // testing::Test: 148 virtual void SetUp() OVERRIDE { 149 source_.reset(new TestPlatformEventSource()); 150 } 151 152 private: 153 scoped_ptr<TestPlatformEventSource> source_; 154 155 DISALLOW_COPY_AND_ASSIGN(PlatformEventTest); 156}; 157 158// Tests that a dispatcher receives an event. 159TEST_F(PlatformEventTest, DispatcherBasic) { 160 std::vector<int> list_dispatcher; 161 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 162 source()->Dispatch(*event); 163 EXPECT_EQ(0u, list_dispatcher.size()); 164 { 165 TestPlatformEventDispatcher dispatcher(1, &list_dispatcher); 166 167 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 168 source()->Dispatch(*event); 169 ASSERT_EQ(1u, list_dispatcher.size()); 170 EXPECT_EQ(1, list_dispatcher[0]); 171 } 172 173 list_dispatcher.clear(); 174 event = CreatePlatformEvent(); 175 source()->Dispatch(*event); 176 EXPECT_EQ(0u, list_dispatcher.size()); 177} 178 179// Tests that dispatchers receive events in the correct order. 180TEST_F(PlatformEventTest, DispatcherOrder) { 181 std::vector<int> list_dispatcher; 182 int sequence[] = {21, 3, 6, 45}; 183 ScopedVector<TestPlatformEventDispatcher> dispatchers; 184 for (size_t i = 0; i < arraysize(sequence); ++i) { 185 dispatchers.push_back( 186 new TestPlatformEventDispatcher(sequence[i], &list_dispatcher)); 187 } 188 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 189 source()->Dispatch(*event); 190 ASSERT_EQ(arraysize(sequence), list_dispatcher.size()); 191 EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)), 192 list_dispatcher); 193} 194 195// Tests that if a dispatcher consumes the event, the subsequent dispatchers do 196// not receive the event. 197TEST_F(PlatformEventTest, DispatcherConsumesEventToStopDispatch) { 198 std::vector<int> list_dispatcher; 199 TestPlatformEventDispatcher first(12, &list_dispatcher); 200 TestPlatformEventDispatcher second(23, &list_dispatcher); 201 202 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 203 source()->Dispatch(*event); 204 ASSERT_EQ(2u, list_dispatcher.size()); 205 EXPECT_EQ(12, list_dispatcher[0]); 206 EXPECT_EQ(23, list_dispatcher[1]); 207 list_dispatcher.clear(); 208 209 first.set_post_dispatch_action(POST_DISPATCH_STOP_PROPAGATION); 210 event = CreatePlatformEvent(); 211 source()->Dispatch(*event); 212 ASSERT_EQ(1u, list_dispatcher.size()); 213 EXPECT_EQ(12, list_dispatcher[0]); 214} 215 216// Tests that observers receive events. 217TEST_F(PlatformEventTest, ObserverBasic) { 218 std::vector<int> list_observer; 219 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 220 source()->Dispatch(*event); 221 EXPECT_EQ(0u, list_observer.size()); 222 { 223 TestPlatformEventObserver observer(31, &list_observer); 224 225 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 226 source()->Dispatch(*event); 227 ASSERT_EQ(1u, list_observer.size()); 228 EXPECT_EQ(31, list_observer[0]); 229 } 230 231 list_observer.clear(); 232 event = CreatePlatformEvent(); 233 source()->Dispatch(*event); 234 EXPECT_EQ(0u, list_observer.size()); 235} 236 237// Tests that observers receive events in the correct order. 238TEST_F(PlatformEventTest, ObserverOrder) { 239 std::vector<int> list_observer; 240 const int sequence[] = {21, 3, 6, 45}; 241 ScopedVector<TestPlatformEventObserver> observers; 242 for (size_t i = 0; i < arraysize(sequence); ++i) { 243 observers.push_back( 244 new TestPlatformEventObserver(sequence[i], &list_observer)); 245 } 246 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 247 source()->Dispatch(*event); 248 ASSERT_EQ(arraysize(sequence), list_observer.size()); 249 EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)), 250 list_observer); 251} 252 253// Tests that observers and dispatchers receive events in the correct order. 254TEST_F(PlatformEventTest, DispatcherAndObserverOrder) { 255 std::vector<int> list; 256 TestPlatformEventDispatcher first_d(12, &list); 257 TestPlatformEventObserver first_o(10, &list); 258 TestPlatformEventDispatcher second_d(23, &list); 259 TestPlatformEventObserver second_o(20, &list); 260 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 261 source()->Dispatch(*event); 262 const int expected[] = {10, 20, 12, 23}; 263 EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list); 264} 265 266// Tests that an overridden dispatcher receives events before the default 267// dispatchers. 268TEST_F(PlatformEventTest, OverriddenDispatcherBasic) { 269 std::vector<int> list; 270 TestPlatformEventDispatcher dispatcher(10, &list); 271 TestPlatformEventObserver observer(15, &list); 272 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 273 source()->Dispatch(*event); 274 ASSERT_EQ(2u, list.size()); 275 EXPECT_EQ(15, list[0]); 276 EXPECT_EQ(10, list[1]); 277 list.clear(); 278 279 TestPlatformEventDispatcher overriding_dispatcher(20, &list); 280 source()->RemovePlatformEventDispatcher(&overriding_dispatcher); 281 scoped_ptr<ScopedEventDispatcher> handle = 282 source()->OverrideDispatcher(&overriding_dispatcher); 283 source()->Dispatch(*event); 284 ASSERT_EQ(2u, list.size()); 285 EXPECT_EQ(15, list[0]); 286 EXPECT_EQ(20, list[1]); 287} 288 289// Tests that an overridden dispatcher can request that the default dispatchers 290// can dispatch the events. 291TEST_F(PlatformEventTest, OverriddenDispatcherInvokeDefaultDispatcher) { 292 std::vector<int> list; 293 TestPlatformEventDispatcher dispatcher(10, &list); 294 TestPlatformEventObserver observer(15, &list); 295 TestPlatformEventDispatcher overriding_dispatcher(20, &list); 296 source()->RemovePlatformEventDispatcher(&overriding_dispatcher); 297 scoped_ptr<ScopedEventDispatcher> handle = 298 source()->OverrideDispatcher(&overriding_dispatcher); 299 overriding_dispatcher.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT); 300 301 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 302 source()->Dispatch(*event); 303 // First the observer, then the overriding dispatcher, then the default 304 // dispatcher. 305 ASSERT_EQ(3u, list.size()); 306 EXPECT_EQ(15, list[0]); 307 EXPECT_EQ(20, list[1]); 308 EXPECT_EQ(10, list[2]); 309 list.clear(); 310 311 // Install a second overriding dispatcher. 312 TestPlatformEventDispatcher second_overriding(50, &list); 313 source()->RemovePlatformEventDispatcher(&second_overriding); 314 scoped_ptr<ScopedEventDispatcher> second_override_handle = 315 source()->OverrideDispatcher(&second_overriding); 316 source()->Dispatch(*event); 317 ASSERT_EQ(2u, list.size()); 318 EXPECT_EQ(15, list[0]); 319 EXPECT_EQ(50, list[1]); 320 list.clear(); 321 322 second_overriding.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT); 323 source()->Dispatch(*event); 324 // First the observer, then the second overriding dispatcher, then the default 325 // dispatcher. 326 ASSERT_EQ(3u, list.size()); 327 EXPECT_EQ(15, list[0]); 328 EXPECT_EQ(50, list[1]); 329 EXPECT_EQ(10, list[2]); 330} 331 332// Runs a callback during an event dispatch. 333class RunCallbackDuringDispatch : public TestPlatformEventDispatcher { 334 public: 335 RunCallbackDuringDispatch(int id, std::vector<int>* list) 336 : TestPlatformEventDispatcher(id, list) {} 337 virtual ~RunCallbackDuringDispatch() {} 338 339 void set_callback(const base::Closure& callback) { 340 callback_ = callback; 341 } 342 343 protected: 344 // PlatformEventDispatcher: 345 virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE { 346 if (!callback_.is_null()) 347 callback_.Run(); 348 return TestPlatformEventDispatcher::DispatchEvent(event); 349 } 350 351 private: 352 base::Closure callback_; 353 354 DISALLOW_COPY_AND_ASSIGN(RunCallbackDuringDispatch); 355}; 356 357// Test that if a dispatcher removes another dispatcher that is later in the 358// dispatcher list during dispatching an event, then event dispatching still 359// continues correctly. 360TEST_F(PlatformEventTest, DispatcherRemovesNextDispatcherDuringDispatch) { 361 std::vector<int> list; 362 TestPlatformEventDispatcher first(10, &list); 363 RunCallbackDuringDispatch second(15, &list); 364 TestPlatformEventDispatcher third(20, &list); 365 TestPlatformEventDispatcher fourth(30, &list); 366 367 second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&third))); 368 369 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 370 source()->Dispatch(*event); 371 // |second| removes |third| from the dispatcher list during dispatch. So the 372 // event should only reach |first|, |second|, and |fourth|. 373 ASSERT_EQ(3u, list.size()); 374 EXPECT_EQ(10, list[0]); 375 EXPECT_EQ(15, list[1]); 376 EXPECT_EQ(30, list[2]); 377} 378 379// Tests that if a dispatcher removes itself from the dispatcher list during 380// dispatching an event, then event dispatching continues correctly. 381TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatch) { 382 std::vector<int> list; 383 TestPlatformEventDispatcher first(10, &list); 384 RunCallbackDuringDispatch second(15, &list); 385 TestPlatformEventDispatcher third(20, &list); 386 387 second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&second))); 388 389 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 390 source()->Dispatch(*event); 391 // |second| removes itself from the dispatcher list during dispatch. So the 392 // event should reach all three dispatchers in the list. 393 ASSERT_EQ(3u, list.size()); 394 EXPECT_EQ(10, list[0]); 395 EXPECT_EQ(15, list[1]); 396 EXPECT_EQ(20, list[2]); 397} 398 399// Tests that if a dispatcher removes itself from the dispatcher list during 400// dispatching an event, and this dispatcher is last in the dispatcher-list, 401// then event dispatching ends correctly. 402TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatchLast) { 403 std::vector<int> list; 404 TestPlatformEventDispatcher first(10, &list); 405 RunCallbackDuringDispatch second(15, &list); 406 407 second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&second))); 408 409 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 410 source()->Dispatch(*event); 411 // |second| removes itself during dispatch. So both dispatchers will have 412 // received the event. 413 ASSERT_EQ(2u, list.size()); 414 EXPECT_EQ(10, list[0]); 415 EXPECT_EQ(15, list[1]); 416} 417 418// Tests that if a dispatcher removes a single dispatcher that comes before it 419// in the dispatcher list, then dispatch continues correctly. 420TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatcherDuringDispatch) { 421 std::vector<int> list; 422 TestPlatformEventDispatcher first(10, &list); 423 RunCallbackDuringDispatch second(15, &list); 424 TestPlatformEventDispatcher third(20, &list); 425 426 second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&first))); 427 428 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 429 source()->Dispatch(*event); 430 // |second| removes |first| from the dispatcher list during dispatch. The 431 // event should reach all three dispatchers. 432 ASSERT_EQ(3u, list.size()); 433 EXPECT_EQ(10, list[0]); 434 EXPECT_EQ(15, list[1]); 435 EXPECT_EQ(20, list[2]); 436} 437 438// Tests that if a dispatcher removes multiple dispatchers that comes before it 439// in the dispatcher list, then dispatch continues correctly. 440TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatchersDuringDispatch) { 441 std::vector<int> list; 442 TestPlatformEventDispatcher first(10, &list); 443 TestPlatformEventDispatcher second(12, &list); 444 RunCallbackDuringDispatch third(15, &list); 445 TestPlatformEventDispatcher fourth(20, &list); 446 447 third.set_callback(base::Bind(&RemoveDispatchers, 448 base::Unretained(&first), 449 base::Unretained(&second))); 450 451 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 452 source()->Dispatch(*event); 453 // |third| removes |first| and |second| from the dispatcher list during 454 // dispatch. The event should reach all three dispatchers. 455 ASSERT_EQ(4u, list.size()); 456 EXPECT_EQ(10, list[0]); 457 EXPECT_EQ(12, list[1]); 458 EXPECT_EQ(15, list[2]); 459 EXPECT_EQ(20, list[3]); 460} 461 462// Tests that adding a dispatcher during dispatching an event receives that 463// event. 464TEST_F(PlatformEventTest, DispatcherAddedDuringDispatchReceivesEvent) { 465 std::vector<int> list; 466 TestPlatformEventDispatcher first(10, &list); 467 RunCallbackDuringDispatch second(15, &list); 468 TestPlatformEventDispatcher third(20, &list); 469 TestPlatformEventDispatcher fourth(30, &list); 470 RemoveDispatchers(&third, &fourth); 471 472 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 473 source()->Dispatch(*event); 474 ASSERT_EQ(2u, list.size()); 475 EXPECT_EQ(10, list[0]); 476 EXPECT_EQ(15, list[1]); 477 478 second.set_callback(base::Bind(&AddDispatcher, base::Unretained(&third))); 479 list.clear(); 480 source()->Dispatch(*event); 481 ASSERT_EQ(3u, list.size()); 482 EXPECT_EQ(10, list[0]); 483 EXPECT_EQ(15, list[1]); 484 EXPECT_EQ(20, list[2]); 485 486 second.set_callback(base::Bind(&AddDispatcher, base::Unretained(&fourth))); 487 list.clear(); 488 source()->Dispatch(*event); 489 ASSERT_EQ(4u, list.size()); 490 EXPECT_EQ(10, list[0]); 491 EXPECT_EQ(15, list[1]); 492 EXPECT_EQ(20, list[2]); 493 EXPECT_EQ(30, list[3]); 494} 495 496// Provides mechanism for running tests from inside an active message-loop. 497class PlatformEventTestWithMessageLoop : public PlatformEventTest { 498 public: 499 PlatformEventTestWithMessageLoop() {} 500 virtual ~PlatformEventTestWithMessageLoop() {} 501 502 void Run() { 503 message_loop_.PostTask( 504 FROM_HERE, 505 base::Bind(&PlatformEventTestWithMessageLoop::RunTest, 506 base::Unretained(this))); 507 message_loop_.Run(); 508 } 509 510 protected: 511 void RunTest() { 512 RunTestImpl(); 513 message_loop_.Quit(); 514 } 515 516 virtual void RunTestImpl() = 0; 517 518 private: 519 base::MessageLoopForUI message_loop_; 520 521 DISALLOW_COPY_AND_ASSIGN(PlatformEventTestWithMessageLoop); 522}; 523 524#define RUN_TEST_IN_MESSAGE_LOOP(name) \ 525 TEST_F(name, Run) { Run(); } 526 527// Tests that a ScopedEventDispatcher restores the previous dispatcher when 528// destroyed. 529class ScopedDispatcherRestoresAfterDestroy 530 : public PlatformEventTestWithMessageLoop { 531 public: 532 // PlatformEventTestWithMessageLoop: 533 virtual void RunTestImpl() OVERRIDE { 534 std::vector<int> list; 535 TestPlatformEventDispatcher dispatcher(10, &list); 536 TestPlatformEventObserver observer(15, &list); 537 538 TestPlatformEventDispatcher first_overriding(20, &list); 539 source()->RemovePlatformEventDispatcher(&first_overriding); 540 scoped_ptr<ScopedEventDispatcher> first_override_handle = 541 source()->OverrideDispatcher(&first_overriding); 542 543 // Install a second overriding dispatcher. 544 TestPlatformEventDispatcher second_overriding(50, &list); 545 source()->RemovePlatformEventDispatcher(&second_overriding); 546 scoped_ptr<ScopedEventDispatcher> second_override_handle = 547 source()->OverrideDispatcher(&second_overriding); 548 549 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 550 source()->Dispatch(*event); 551 ASSERT_EQ(2u, list.size()); 552 EXPECT_EQ(15, list[0]); 553 EXPECT_EQ(50, list[1]); 554 list.clear(); 555 556 second_override_handle.reset(); 557 source()->Dispatch(*event); 558 ASSERT_EQ(2u, list.size()); 559 EXPECT_EQ(15, list[0]); 560 EXPECT_EQ(20, list[1]); 561 } 562}; 563 564RUN_TEST_IN_MESSAGE_LOOP(ScopedDispatcherRestoresAfterDestroy) 565 566// This dispatcher destroys the handle to the ScopedEventDispatcher when 567// dispatching an event. 568class DestroyScopedHandleDispatcher : public TestPlatformEventDispatcher { 569 public: 570 DestroyScopedHandleDispatcher(int id, std::vector<int>* list) 571 : TestPlatformEventDispatcher(id, list) {} 572 virtual ~DestroyScopedHandleDispatcher() {} 573 574 void SetScopedHandle(scoped_ptr<ScopedEventDispatcher> handler) { 575 handler_ = handler.Pass(); 576 } 577 578 void set_callback(const base::Closure& callback) { 579 callback_ = callback; 580 } 581 582 private: 583 // PlatformEventDispatcher: 584 virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE { 585 return true; 586 } 587 588 virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE { 589 handler_.reset(); 590 uint32_t action = TestPlatformEventDispatcher::DispatchEvent(event); 591 if (!callback_.is_null()) { 592 callback_.Run(); 593 callback_ = base::Closure(); 594 } 595 return action; 596 } 597 598 scoped_ptr<ScopedEventDispatcher> handler_; 599 base::Closure callback_; 600 601 DISALLOW_COPY_AND_ASSIGN(DestroyScopedHandleDispatcher); 602}; 603 604// Tests that resetting an overridden dispatcher causes the nested message-loop 605// iteration to stop and the rest of the events are dispatched in the next 606// iteration. 607class DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration 608 : public PlatformEventTestWithMessageLoop { 609 public: 610 void NestedTask(std::vector<int>* list, 611 TestPlatformEventDispatcher* dispatcher) { 612 ScopedVector<PlatformEvent> events; 613 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 614 events.push_back(event.release()); 615 event = CreatePlatformEvent(); 616 events.push_back(event.release()); 617 618 // Attempt to dispatch a couple of events. Dispatching the first event will 619 // have terminated the ScopedEventDispatcher object, which will terminate 620 // the current iteration of the message-loop. 621 size_t count = source()->DispatchEventStream(events); 622 EXPECT_EQ(1u, count); 623 ASSERT_EQ(2u, list->size()); 624 EXPECT_EQ(15, (*list)[0]); 625 EXPECT_EQ(20, (*list)[1]); 626 list->clear(); 627 628 ASSERT_LT(count, events.size()); 629 events.erase(events.begin(), events.begin() + count); 630 631 count = source()->DispatchEventStream(events); 632 EXPECT_EQ(1u, count); 633 ASSERT_EQ(2u, list->size()); 634 EXPECT_EQ(15, (*list)[0]); 635 EXPECT_EQ(10, (*list)[1]); 636 list->clear(); 637 638 // Terminate the message-loop. 639 base::MessageLoopForUI::current()->QuitNow(); 640 } 641 642 // PlatformEventTestWithMessageLoop: 643 virtual void RunTestImpl() OVERRIDE { 644 std::vector<int> list; 645 TestPlatformEventDispatcher dispatcher(10, &list); 646 TestPlatformEventObserver observer(15, &list); 647 648 DestroyScopedHandleDispatcher overriding(20, &list); 649 source()->RemovePlatformEventDispatcher(&overriding); 650 scoped_ptr<ScopedEventDispatcher> override_handle = 651 source()->OverrideDispatcher(&overriding); 652 653 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 654 source()->Dispatch(*event); 655 ASSERT_EQ(2u, list.size()); 656 EXPECT_EQ(15, list[0]); 657 EXPECT_EQ(20, list[1]); 658 list.clear(); 659 660 overriding.SetScopedHandle(override_handle.Pass()); 661 base::RunLoop run_loop; 662 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); 663 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); 664 loop->PostTask( 665 FROM_HERE, 666 base::Bind( 667 &DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration:: 668 NestedTask, 669 base::Unretained(this), 670 base::Unretained(&list), 671 base::Unretained(&overriding))); 672 run_loop.Run(); 673 674 // Dispatching the event should now reach the default dispatcher. 675 source()->Dispatch(*event); 676 ASSERT_EQ(2u, list.size()); 677 EXPECT_EQ(15, list[0]); 678 EXPECT_EQ(10, list[1]); 679 } 680}; 681 682RUN_TEST_IN_MESSAGE_LOOP( 683 DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration) 684 685// Tests that resetting an overridden dispatcher, and installing another 686// overridden dispatcher before the nested message-loop completely unwinds 687// function correctly. 688class ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration 689 : public PlatformEventTestWithMessageLoop { 690 public: 691 void NestedTask(scoped_ptr<ScopedEventDispatcher> dispatch_handle, 692 std::vector<int>* list) { 693 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 694 source()->Dispatch(*event); 695 ASSERT_EQ(2u, list->size()); 696 EXPECT_EQ(15, (*list)[0]); 697 EXPECT_EQ(20, (*list)[1]); 698 list->clear(); 699 700 // Reset the override dispatcher. This should restore the default 701 // dispatcher. 702 dispatch_handle.reset(); 703 source()->Dispatch(*event); 704 ASSERT_EQ(2u, list->size()); 705 EXPECT_EQ(15, (*list)[0]); 706 EXPECT_EQ(10, (*list)[1]); 707 list->clear(); 708 709 // Install another override-dispatcher. 710 DestroyScopedHandleDispatcher second_overriding(70, list); 711 source()->RemovePlatformEventDispatcher(&second_overriding); 712 scoped_ptr<ScopedEventDispatcher> second_override_handle = 713 source()->OverrideDispatcher(&second_overriding); 714 715 source()->Dispatch(*event); 716 ASSERT_EQ(2u, list->size()); 717 EXPECT_EQ(15, (*list)[0]); 718 EXPECT_EQ(70, (*list)[1]); 719 list->clear(); 720 721 second_overriding.SetScopedHandle(second_override_handle.Pass()); 722 second_overriding.set_post_dispatch_action(POST_DISPATCH_NONE); 723 base::RunLoop run_loop; 724 second_overriding.set_callback(run_loop.QuitClosure()); 725 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); 726 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); 727 loop->PostTask( 728 FROM_HERE, 729 base::Bind(base::IgnoreResult(&TestPlatformEventSource::Dispatch), 730 base::Unretained(source()), 731 *event)); 732 run_loop.Run(); 733 ASSERT_EQ(2u, list->size()); 734 EXPECT_EQ(15, (*list)[0]); 735 EXPECT_EQ(70, (*list)[1]); 736 list->clear(); 737 738 // Terminate the message-loop. 739 base::MessageLoopForUI::current()->QuitNow(); 740 } 741 742 // PlatformEventTestWithMessageLoop: 743 virtual void RunTestImpl() OVERRIDE { 744 std::vector<int> list; 745 TestPlatformEventDispatcher dispatcher(10, &list); 746 TestPlatformEventObserver observer(15, &list); 747 748 TestPlatformEventDispatcher overriding(20, &list); 749 source()->RemovePlatformEventDispatcher(&overriding); 750 scoped_ptr<ScopedEventDispatcher> override_handle = 751 source()->OverrideDispatcher(&overriding); 752 753 scoped_ptr<PlatformEvent> event(CreatePlatformEvent()); 754 source()->Dispatch(*event); 755 ASSERT_EQ(2u, list.size()); 756 EXPECT_EQ(15, list[0]); 757 EXPECT_EQ(20, list[1]); 758 list.clear(); 759 760 // Start a nested message-loop, and destroy |override_handle| in the nested 761 // loop. That should terminate the nested loop, restore the previous 762 // dispatchers, and return control to this function. 763 base::RunLoop run_loop; 764 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); 765 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); 766 loop->PostTask( 767 FROM_HERE, 768 base::Bind( 769 &ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration:: 770 NestedTask, 771 base::Unretained(this), 772 base::Passed(&override_handle), 773 base::Unretained(&list))); 774 run_loop.Run(); 775 776 // Dispatching the event should now reach the default dispatcher. 777 source()->Dispatch(*event); 778 ASSERT_EQ(2u, list.size()); 779 EXPECT_EQ(15, list[0]); 780 EXPECT_EQ(10, list[1]); 781 } 782}; 783 784RUN_TEST_IN_MESSAGE_LOOP( 785 ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration) 786 787} // namespace ui 788