Home | History | Annotate | Download | only in aura
      1 // Copyright (c) 2012 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/aura/window_event_dispatcher.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/bind.h"
     10 #include "base/run_loop.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "ui/aura/client/capture_client.h"
     13 #include "ui/aura/client/event_client.h"
     14 #include "ui/aura/client/focus_client.h"
     15 #include "ui/aura/env.h"
     16 #include "ui/aura/test/aura_test_base.h"
     17 #include "ui/aura/test/env_test_helper.h"
     18 #include "ui/aura/test/test_cursor_client.h"
     19 #include "ui/aura/test/test_screen.h"
     20 #include "ui/aura/test/test_window_delegate.h"
     21 #include "ui/aura/test/test_windows.h"
     22 #include "ui/aura/window.h"
     23 #include "ui/aura/window_tracker.h"
     24 #include "ui/base/hit_test.h"
     25 #include "ui/events/event.h"
     26 #include "ui/events/event_handler.h"
     27 #include "ui/events/event_utils.h"
     28 #include "ui/events/gestures/gesture_configuration.h"
     29 #include "ui/events/keycodes/keyboard_codes.h"
     30 #include "ui/events/test/event_generator.h"
     31 #include "ui/events/test/test_event_handler.h"
     32 #include "ui/gfx/point.h"
     33 #include "ui/gfx/rect.h"
     34 #include "ui/gfx/screen.h"
     35 #include "ui/gfx/transform.h"
     36 
     37 namespace aura {
     38 namespace {
     39 
     40 // A delegate that always returns a non-client component for hit tests.
     41 class NonClientDelegate : public test::TestWindowDelegate {
     42  public:
     43   NonClientDelegate()
     44       : non_client_count_(0),
     45         mouse_event_count_(0),
     46         mouse_event_flags_(0x0) {
     47   }
     48   virtual ~NonClientDelegate() {}
     49 
     50   int non_client_count() const { return non_client_count_; }
     51   gfx::Point non_client_location() const { return non_client_location_; }
     52   int mouse_event_count() const { return mouse_event_count_; }
     53   gfx::Point mouse_event_location() const { return mouse_event_location_; }
     54   int mouse_event_flags() const { return mouse_event_flags_; }
     55 
     56   virtual int GetNonClientComponent(const gfx::Point& location) const OVERRIDE {
     57     NonClientDelegate* self = const_cast<NonClientDelegate*>(this);
     58     self->non_client_count_++;
     59     self->non_client_location_ = location;
     60     return HTTOPLEFT;
     61   }
     62   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
     63     mouse_event_count_++;
     64     mouse_event_location_ = event->location();
     65     mouse_event_flags_ = event->flags();
     66     event->SetHandled();
     67   }
     68 
     69  private:
     70   int non_client_count_;
     71   gfx::Point non_client_location_;
     72   int mouse_event_count_;
     73   gfx::Point mouse_event_location_;
     74   int mouse_event_flags_;
     75 
     76   DISALLOW_COPY_AND_ASSIGN(NonClientDelegate);
     77 };
     78 
     79 // A simple event handler that consumes key events.
     80 class ConsumeKeyHandler : public ui::test::TestEventHandler {
     81  public:
     82   ConsumeKeyHandler() {}
     83   virtual ~ConsumeKeyHandler() {}
     84 
     85   // Overridden from ui::EventHandler:
     86   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
     87     ui::test::TestEventHandler::OnKeyEvent(event);
     88     event->StopPropagation();
     89   }
     90 
     91  private:
     92   DISALLOW_COPY_AND_ASSIGN(ConsumeKeyHandler);
     93 };
     94 
     95 bool IsFocusedWindow(aura::Window* window) {
     96   return client::GetFocusClient(window)->GetFocusedWindow() == window;
     97 }
     98 
     99 }  // namespace
    100 
    101 typedef test::AuraTestBase WindowEventDispatcherTest;
    102 
    103 TEST_F(WindowEventDispatcherTest, OnHostMouseEvent) {
    104   // Create two non-overlapping windows so we don't have to worry about which
    105   // is on top.
    106   scoped_ptr<NonClientDelegate> delegate1(new NonClientDelegate());
    107   scoped_ptr<NonClientDelegate> delegate2(new NonClientDelegate());
    108   const int kWindowWidth = 123;
    109   const int kWindowHeight = 45;
    110   gfx::Rect bounds1(100, 200, kWindowWidth, kWindowHeight);
    111   gfx::Rect bounds2(300, 400, kWindowWidth, kWindowHeight);
    112   scoped_ptr<aura::Window> window1(CreateTestWindowWithDelegate(
    113       delegate1.get(), -1234, bounds1, root_window()));
    114   scoped_ptr<aura::Window> window2(CreateTestWindowWithDelegate(
    115       delegate2.get(), -5678, bounds2, root_window()));
    116 
    117   // Send a mouse event to window1.
    118   gfx::Point point(101, 201);
    119   ui::MouseEvent event1(
    120       ui::ET_MOUSE_PRESSED, point, point, ui::EF_LEFT_MOUSE_BUTTON,
    121       ui::EF_LEFT_MOUSE_BUTTON);
    122   DispatchEventUsingWindowDispatcher(&event1);
    123 
    124   // Event was tested for non-client area for the target window.
    125   EXPECT_EQ(1, delegate1->non_client_count());
    126   EXPECT_EQ(0, delegate2->non_client_count());
    127   // The non-client component test was in local coordinates.
    128   EXPECT_EQ(gfx::Point(1, 1), delegate1->non_client_location());
    129   // Mouse event was received by target window.
    130   EXPECT_EQ(1, delegate1->mouse_event_count());
    131   EXPECT_EQ(0, delegate2->mouse_event_count());
    132   // Event was in local coordinates.
    133   EXPECT_EQ(gfx::Point(1, 1), delegate1->mouse_event_location());
    134   // Non-client flag was set.
    135   EXPECT_TRUE(delegate1->mouse_event_flags() & ui::EF_IS_NON_CLIENT);
    136 }
    137 
    138 TEST_F(WindowEventDispatcherTest, RepostEvent) {
    139   // Test RepostEvent in RootWindow. It only works for Mouse Press.
    140   EXPECT_FALSE(Env::GetInstance()->IsMouseButtonDown());
    141   gfx::Point point(10, 10);
    142   ui::MouseEvent event(
    143       ui::ET_MOUSE_PRESSED, point, point, ui::EF_LEFT_MOUSE_BUTTON,
    144       ui::EF_LEFT_MOUSE_BUTTON);
    145   host()->dispatcher()->RepostEvent(event);
    146   RunAllPendingInMessageLoop();
    147   EXPECT_TRUE(Env::GetInstance()->IsMouseButtonDown());
    148 }
    149 
    150 // Check that we correctly track the state of the mouse buttons in response to
    151 // button press and release events.
    152 TEST_F(WindowEventDispatcherTest, MouseButtonState) {
    153   EXPECT_FALSE(Env::GetInstance()->IsMouseButtonDown());
    154 
    155   gfx::Point location;
    156   scoped_ptr<ui::MouseEvent> event;
    157 
    158   // Press the left button.
    159   event.reset(new ui::MouseEvent(
    160       ui::ET_MOUSE_PRESSED,
    161       location,
    162       location,
    163       ui::EF_LEFT_MOUSE_BUTTON,
    164       ui::EF_LEFT_MOUSE_BUTTON));
    165   DispatchEventUsingWindowDispatcher(event.get());
    166   EXPECT_TRUE(Env::GetInstance()->IsMouseButtonDown());
    167 
    168   // Additionally press the right.
    169   event.reset(new ui::MouseEvent(
    170       ui::ET_MOUSE_PRESSED,
    171       location,
    172       location,
    173       ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON,
    174       ui::EF_RIGHT_MOUSE_BUTTON));
    175   DispatchEventUsingWindowDispatcher(event.get());
    176   EXPECT_TRUE(Env::GetInstance()->IsMouseButtonDown());
    177 
    178   // Release the left button.
    179   event.reset(new ui::MouseEvent(
    180       ui::ET_MOUSE_RELEASED,
    181       location,
    182       location,
    183       ui::EF_RIGHT_MOUSE_BUTTON,
    184       ui::EF_LEFT_MOUSE_BUTTON));
    185   DispatchEventUsingWindowDispatcher(event.get());
    186   EXPECT_TRUE(Env::GetInstance()->IsMouseButtonDown());
    187 
    188   // Release the right button.  We should ignore the Shift-is-down flag.
    189   event.reset(new ui::MouseEvent(
    190       ui::ET_MOUSE_RELEASED,
    191       location,
    192       location,
    193       ui::EF_SHIFT_DOWN,
    194       ui::EF_RIGHT_MOUSE_BUTTON));
    195   DispatchEventUsingWindowDispatcher(event.get());
    196   EXPECT_FALSE(Env::GetInstance()->IsMouseButtonDown());
    197 
    198   // Press the middle button.
    199   event.reset(new ui::MouseEvent(
    200       ui::ET_MOUSE_PRESSED,
    201       location,
    202       location,
    203       ui::EF_MIDDLE_MOUSE_BUTTON,
    204       ui::EF_MIDDLE_MOUSE_BUTTON));
    205   DispatchEventUsingWindowDispatcher(event.get());
    206   EXPECT_TRUE(Env::GetInstance()->IsMouseButtonDown());
    207 }
    208 
    209 TEST_F(WindowEventDispatcherTest, TranslatedEvent) {
    210   scoped_ptr<Window> w1(test::CreateTestWindowWithDelegate(NULL, 1,
    211       gfx::Rect(50, 50, 100, 100), root_window()));
    212 
    213   gfx::Point origin(100, 100);
    214   ui::MouseEvent root(ui::ET_MOUSE_PRESSED, origin, origin, 0, 0);
    215 
    216   EXPECT_EQ("100,100", root.location().ToString());
    217   EXPECT_EQ("100,100", root.root_location().ToString());
    218 
    219   ui::MouseEvent translated_event(
    220       root, static_cast<Window*>(root_window()), w1.get(),
    221       ui::ET_MOUSE_ENTERED, root.flags());
    222   EXPECT_EQ("50,50", translated_event.location().ToString());
    223   EXPECT_EQ("100,100", translated_event.root_location().ToString());
    224 }
    225 
    226 namespace {
    227 
    228 class TestEventClient : public client::EventClient {
    229  public:
    230   static const int kNonLockWindowId = 100;
    231   static const int kLockWindowId = 200;
    232 
    233   explicit TestEventClient(Window* root_window)
    234       : root_window_(root_window),
    235         lock_(false) {
    236     client::SetEventClient(root_window_, this);
    237     Window* lock_window =
    238         test::CreateTestWindowWithBounds(root_window_->bounds(), root_window_);
    239     lock_window->set_id(kLockWindowId);
    240     Window* non_lock_window =
    241         test::CreateTestWindowWithBounds(root_window_->bounds(), root_window_);
    242     non_lock_window->set_id(kNonLockWindowId);
    243   }
    244   virtual ~TestEventClient() {
    245     client::SetEventClient(root_window_, NULL);
    246   }
    247 
    248   // Starts/stops locking. Locking prevents windows other than those inside
    249   // the lock container from receiving events, getting focus etc.
    250   void Lock() {
    251     lock_ = true;
    252   }
    253   void Unlock() {
    254     lock_ = false;
    255   }
    256 
    257   Window* GetLockWindow() {
    258     return const_cast<Window*>(
    259         static_cast<const TestEventClient*>(this)->GetLockWindow());
    260   }
    261   const Window* GetLockWindow() const {
    262     return root_window_->GetChildById(kLockWindowId);
    263   }
    264   Window* GetNonLockWindow() {
    265     return root_window_->GetChildById(kNonLockWindowId);
    266   }
    267 
    268  private:
    269   // Overridden from client::EventClient:
    270   virtual bool CanProcessEventsWithinSubtree(
    271       const Window* window) const OVERRIDE {
    272     return lock_ ?
    273         window->Contains(GetLockWindow()) || GetLockWindow()->Contains(window) :
    274         true;
    275   }
    276 
    277   virtual ui::EventTarget* GetToplevelEventTarget() OVERRIDE {
    278     return NULL;
    279   }
    280 
    281   Window* root_window_;
    282   bool lock_;
    283 
    284   DISALLOW_COPY_AND_ASSIGN(TestEventClient);
    285 };
    286 
    287 }  // namespace
    288 
    289 TEST_F(WindowEventDispatcherTest, CanProcessEventsWithinSubtree) {
    290   TestEventClient client(root_window());
    291   test::TestWindowDelegate d;
    292 
    293   ui::test::TestEventHandler nonlock_ef;
    294   ui::test::TestEventHandler lock_ef;
    295   client.GetNonLockWindow()->AddPreTargetHandler(&nonlock_ef);
    296   client.GetLockWindow()->AddPreTargetHandler(&lock_ef);
    297 
    298   Window* w1 = test::CreateTestWindowWithBounds(gfx::Rect(10, 10, 20, 20),
    299                                                 client.GetNonLockWindow());
    300   w1->set_id(1);
    301   Window* w2 = test::CreateTestWindowWithBounds(gfx::Rect(30, 30, 20, 20),
    302                                                 client.GetNonLockWindow());
    303   w2->set_id(2);
    304   scoped_ptr<Window> w3(
    305       test::CreateTestWindowWithDelegate(&d, 3, gfx::Rect(30, 30, 20, 20),
    306                                          client.GetLockWindow()));
    307 
    308   w1->Focus();
    309   EXPECT_TRUE(IsFocusedWindow(w1));
    310 
    311   client.Lock();
    312 
    313   // Since we're locked, the attempt to focus w2 will be ignored.
    314   w2->Focus();
    315   EXPECT_TRUE(IsFocusedWindow(w1));
    316   EXPECT_FALSE(IsFocusedWindow(w2));
    317 
    318   {
    319     // Attempting to send a key event to w1 (not in the lock container) should
    320     // cause focus to be reset.
    321     ui::test::EventGenerator generator(root_window());
    322     generator.PressKey(ui::VKEY_SPACE, 0);
    323     EXPECT_EQ(NULL, client::GetFocusClient(w1)->GetFocusedWindow());
    324     EXPECT_FALSE(IsFocusedWindow(w1));
    325   }
    326 
    327   {
    328     // Events sent to a window not in the lock container will not be processed.
    329     // i.e. never sent to the non-lock container's event filter.
    330     ui::test::EventGenerator generator(root_window(), w1);
    331     generator.ClickLeftButton();
    332     EXPECT_EQ(0, nonlock_ef.num_mouse_events());
    333 
    334     // Events sent to a window in the lock container will be processed.
    335     ui::test::EventGenerator generator3(root_window(), w3.get());
    336     generator3.PressLeftButton();
    337     EXPECT_EQ(1, lock_ef.num_mouse_events());
    338   }
    339 
    340   // Prevent w3 from being deleted by the hierarchy since its delegate is owned
    341   // by this scope.
    342   w3->parent()->RemoveChild(w3.get());
    343 }
    344 
    345 TEST_F(WindowEventDispatcherTest, IgnoreUnknownKeys) {
    346   ConsumeKeyHandler handler;
    347   root_window()->AddPreTargetHandler(&handler);
    348 
    349   ui::KeyEvent unknown_event(ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN, ui::EF_NONE);
    350   DispatchEventUsingWindowDispatcher(&unknown_event);
    351   EXPECT_FALSE(unknown_event.handled());
    352   EXPECT_EQ(0, handler.num_key_events());
    353 
    354   handler.Reset();
    355   ui::KeyEvent known_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
    356   DispatchEventUsingWindowDispatcher(&known_event);
    357   EXPECT_TRUE(known_event.handled());
    358   EXPECT_EQ(1, handler.num_key_events());
    359 
    360   handler.Reset();
    361   ui::KeyEvent ime_event(ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN,
    362                          ui::EF_IME_FABRICATED_KEY);
    363   DispatchEventUsingWindowDispatcher(&ime_event);
    364   EXPECT_TRUE(ime_event.handled());
    365   EXPECT_EQ(1, handler.num_key_events());
    366 
    367   handler.Reset();
    368   ui::KeyEvent unknown_key_with_char_event(ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN,
    369                                            ui::EF_NONE);
    370   unknown_key_with_char_event.set_character(0x00e4 /* "" */);
    371   DispatchEventUsingWindowDispatcher(&unknown_key_with_char_event);
    372   EXPECT_TRUE(unknown_key_with_char_event.handled());
    373   EXPECT_EQ(1, handler.num_key_events());
    374 }
    375 
    376 TEST_F(WindowEventDispatcherTest, NoDelegateWindowReceivesKeyEvents) {
    377   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), NULL));
    378   w1->Show();
    379   w1->Focus();
    380 
    381   ui::test::TestEventHandler handler;
    382   w1->AddPreTargetHandler(&handler);
    383   ui::KeyEvent key_press(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
    384   DispatchEventUsingWindowDispatcher(&key_press);
    385   EXPECT_TRUE(key_press.handled());
    386   EXPECT_EQ(1, handler.num_key_events());
    387 
    388   w1->RemovePreTargetHandler(&handler);
    389 }
    390 
    391 // Tests that touch-events that are beyond the bounds of the root-window do get
    392 // propagated to the event filters correctly with the root as the target.
    393 TEST_F(WindowEventDispatcherTest, TouchEventsOutsideBounds) {
    394   ui::test::TestEventHandler handler;
    395   root_window()->AddPreTargetHandler(&handler);
    396 
    397   gfx::Point position = root_window()->bounds().origin();
    398   position.Offset(-10, -10);
    399   ui::TouchEvent press(
    400       ui::ET_TOUCH_PRESSED, position, 0, ui::EventTimeForNow());
    401   DispatchEventUsingWindowDispatcher(&press);
    402   EXPECT_EQ(1, handler.num_touch_events());
    403 
    404   position = root_window()->bounds().origin();
    405   position.Offset(root_window()->bounds().width() + 10,
    406                   root_window()->bounds().height() + 10);
    407   ui::TouchEvent release(
    408       ui::ET_TOUCH_RELEASED, position, 0, ui::EventTimeForNow());
    409   DispatchEventUsingWindowDispatcher(&release);
    410   EXPECT_EQ(2, handler.num_touch_events());
    411 }
    412 
    413 // Tests that scroll events are dispatched correctly.
    414 TEST_F(WindowEventDispatcherTest, ScrollEventDispatch) {
    415   base::TimeDelta now = ui::EventTimeForNow();
    416   ui::test::TestEventHandler handler;
    417   root_window()->AddPreTargetHandler(&handler);
    418 
    419   test::TestWindowDelegate delegate;
    420   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), &delegate));
    421   w1->SetBounds(gfx::Rect(20, 20, 40, 40));
    422 
    423   // A scroll event on the root-window itself is dispatched.
    424   ui::ScrollEvent scroll1(ui::ET_SCROLL,
    425                           gfx::Point(10, 10),
    426                           now,
    427                           0,
    428                           0, -10,
    429                           0, -10,
    430                           2);
    431   DispatchEventUsingWindowDispatcher(&scroll1);
    432   EXPECT_EQ(1, handler.num_scroll_events());
    433 
    434   // Scroll event on a window should be dispatched properly.
    435   ui::ScrollEvent scroll2(ui::ET_SCROLL,
    436                           gfx::Point(25, 30),
    437                           now,
    438                           0,
    439                           -10, 0,
    440                           -10, 0,
    441                           2);
    442   DispatchEventUsingWindowDispatcher(&scroll2);
    443   EXPECT_EQ(2, handler.num_scroll_events());
    444   root_window()->RemovePreTargetHandler(&handler);
    445 }
    446 
    447 namespace {
    448 
    449 // FilterFilter that tracks the types of events it's seen.
    450 class EventFilterRecorder : public ui::EventHandler {
    451  public:
    452   typedef std::vector<ui::EventType> Events;
    453   typedef std::vector<gfx::Point> EventLocations;
    454   typedef std::vector<int> EventFlags;
    455 
    456   EventFilterRecorder()
    457       : wait_until_event_(ui::ET_UNKNOWN) {
    458   }
    459 
    460   const Events& events() const { return events_; }
    461 
    462   const EventLocations& mouse_locations() const { return mouse_locations_; }
    463   gfx::Point mouse_location(int i) const { return mouse_locations_[i]; }
    464   const EventLocations& touch_locations() const { return touch_locations_; }
    465   const EventLocations& gesture_locations() const { return gesture_locations_; }
    466   const EventFlags& mouse_event_flags() const { return mouse_event_flags_; }
    467 
    468   void WaitUntilReceivedEvent(ui::EventType type) {
    469     wait_until_event_ = type;
    470     run_loop_.reset(new base::RunLoop());
    471     run_loop_->Run();
    472   }
    473 
    474   Events GetAndResetEvents() {
    475     Events events = events_;
    476     Reset();
    477     return events;
    478   }
    479 
    480   void Reset() {
    481     events_.clear();
    482     mouse_locations_.clear();
    483     touch_locations_.clear();
    484     gesture_locations_.clear();
    485     mouse_event_flags_.clear();
    486   }
    487 
    488   // ui::EventHandler overrides:
    489   virtual void OnEvent(ui::Event* event) OVERRIDE {
    490     ui::EventHandler::OnEvent(event);
    491     events_.push_back(event->type());
    492     if (wait_until_event_ == event->type() && run_loop_) {
    493       run_loop_->Quit();
    494       wait_until_event_ = ui::ET_UNKNOWN;
    495     }
    496   }
    497 
    498   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
    499     mouse_locations_.push_back(event->location());
    500     mouse_event_flags_.push_back(event->flags());
    501   }
    502 
    503   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
    504     touch_locations_.push_back(event->location());
    505   }
    506 
    507   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
    508     gesture_locations_.push_back(event->location());
    509   }
    510 
    511   bool HasReceivedEvent(ui::EventType type) {
    512     return std::find(events_.begin(), events_.end(), type) != events_.end();
    513   }
    514 
    515  private:
    516   scoped_ptr<base::RunLoop> run_loop_;
    517   ui::EventType wait_until_event_;
    518 
    519   Events events_;
    520   EventLocations mouse_locations_;
    521   EventLocations touch_locations_;
    522   EventLocations gesture_locations_;
    523   EventFlags mouse_event_flags_;
    524 
    525   DISALLOW_COPY_AND_ASSIGN(EventFilterRecorder);
    526 };
    527 
    528 // Converts an EventType to a string.
    529 std::string EventTypeToString(ui::EventType type) {
    530   switch (type) {
    531     case ui::ET_TOUCH_RELEASED:
    532       return "TOUCH_RELEASED";
    533 
    534     case ui::ET_TOUCH_CANCELLED:
    535       return "TOUCH_CANCELLED";
    536 
    537     case ui::ET_TOUCH_PRESSED:
    538       return "TOUCH_PRESSED";
    539 
    540     case ui::ET_TOUCH_MOVED:
    541       return "TOUCH_MOVED";
    542 
    543     case ui::ET_MOUSE_PRESSED:
    544       return "MOUSE_PRESSED";
    545 
    546     case ui::ET_MOUSE_DRAGGED:
    547       return "MOUSE_DRAGGED";
    548 
    549     case ui::ET_MOUSE_RELEASED:
    550       return "MOUSE_RELEASED";
    551 
    552     case ui::ET_MOUSE_MOVED:
    553       return "MOUSE_MOVED";
    554 
    555     case ui::ET_MOUSE_ENTERED:
    556       return "MOUSE_ENTERED";
    557 
    558     case ui::ET_MOUSE_EXITED:
    559       return "MOUSE_EXITED";
    560 
    561     case ui::ET_GESTURE_SCROLL_BEGIN:
    562       return "GESTURE_SCROLL_BEGIN";
    563 
    564     case ui::ET_GESTURE_SCROLL_END:
    565       return "GESTURE_SCROLL_END";
    566 
    567     case ui::ET_GESTURE_SCROLL_UPDATE:
    568       return "GESTURE_SCROLL_UPDATE";
    569 
    570     case ui::ET_GESTURE_PINCH_BEGIN:
    571       return "GESTURE_PINCH_BEGIN";
    572 
    573     case ui::ET_GESTURE_PINCH_END:
    574       return "GESTURE_PINCH_END";
    575 
    576     case ui::ET_GESTURE_PINCH_UPDATE:
    577       return "GESTURE_PINCH_UPDATE";
    578 
    579     case ui::ET_GESTURE_TAP:
    580       return "GESTURE_TAP";
    581 
    582     case ui::ET_GESTURE_TAP_DOWN:
    583       return "GESTURE_TAP_DOWN";
    584 
    585     case ui::ET_GESTURE_TAP_CANCEL:
    586       return "GESTURE_TAP_CANCEL";
    587 
    588     case ui::ET_GESTURE_SHOW_PRESS:
    589       return "GESTURE_SHOW_PRESS";
    590 
    591     case ui::ET_GESTURE_BEGIN:
    592       return "GESTURE_BEGIN";
    593 
    594     case ui::ET_GESTURE_END:
    595       return "GESTURE_END";
    596 
    597     default:
    598       // We should explicitly require each event type.
    599       NOTREACHED() << "Received unexpected event: " << type;
    600       break;
    601   }
    602   return "";
    603 }
    604 
    605 std::string EventTypesToString(const EventFilterRecorder::Events& events) {
    606   std::string result;
    607   for (size_t i = 0; i < events.size(); ++i) {
    608     if (i != 0)
    609       result += " ";
    610     result += EventTypeToString(events[i]);
    611   }
    612   return result;
    613 }
    614 
    615 }  // namespace
    616 
    617 #if defined(OS_WIN) && defined(ARCH_CPU_X86)
    618 #define MAYBE(x) DISABLED_##x
    619 #else
    620 #define MAYBE(x) x
    621 #endif
    622 
    623 // Verifies a repost mouse event targets the window with capture (if there is
    624 // one).
    625 // Flaky on 32-bit Windows bots.  http://crbug.com/388290
    626 TEST_F(WindowEventDispatcherTest, MAYBE(RepostTargetsCaptureWindow)) {
    627   // Set capture on |window| generate a mouse event (that is reposted) and not
    628   // over |window| and verify |window| gets it (|window| gets it because it has
    629   // capture).
    630   EXPECT_FALSE(Env::GetInstance()->IsMouseButtonDown());
    631   EventFilterRecorder recorder;
    632   scoped_ptr<Window> window(CreateNormalWindow(1, root_window(), NULL));
    633   window->SetBounds(gfx::Rect(20, 20, 40, 30));
    634   window->AddPreTargetHandler(&recorder);
    635   window->SetCapture();
    636   const ui::MouseEvent press_event(
    637       ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
    638       ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
    639   host()->dispatcher()->RepostEvent(press_event);
    640   RunAllPendingInMessageLoop();  // Necessitated by RepostEvent().
    641   // Mouse moves/enters may be generated. We only care about a pressed.
    642   EXPECT_TRUE(EventTypesToString(recorder.events()).find("MOUSE_PRESSED") !=
    643               std::string::npos) << EventTypesToString(recorder.events());
    644 }
    645 
    646 TEST_F(WindowEventDispatcherTest, MouseMovesHeld) {
    647   EventFilterRecorder recorder;
    648   root_window()->AddPreTargetHandler(&recorder);
    649 
    650   test::TestWindowDelegate delegate;
    651   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
    652       &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
    653 
    654   ui::MouseEvent mouse_move_event(ui::ET_MOUSE_MOVED, gfx::Point(0, 0),
    655                                   gfx::Point(0, 0), 0, 0);
    656   DispatchEventUsingWindowDispatcher(&mouse_move_event);
    657   // Discard MOUSE_ENTER.
    658   recorder.Reset();
    659 
    660   host()->dispatcher()->HoldPointerMoves();
    661 
    662   // Check that we don't immediately dispatch the MOUSE_DRAGGED event.
    663   ui::MouseEvent mouse_dragged_event(ui::ET_MOUSE_DRAGGED, gfx::Point(0, 0),
    664                                      gfx::Point(0, 0), 0, 0);
    665   DispatchEventUsingWindowDispatcher(&mouse_dragged_event);
    666   EXPECT_TRUE(recorder.events().empty());
    667 
    668   // Check that we do dispatch the held MOUSE_DRAGGED event before another type
    669   // of event.
    670   ui::MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0),
    671                                      gfx::Point(0, 0), 0, 0);
    672   DispatchEventUsingWindowDispatcher(&mouse_pressed_event);
    673   EXPECT_EQ("MOUSE_DRAGGED MOUSE_PRESSED",
    674             EventTypesToString(recorder.events()));
    675   recorder.Reset();
    676 
    677   // Check that we coalesce held MOUSE_DRAGGED events.
    678   ui::MouseEvent mouse_dragged_event2(ui::ET_MOUSE_DRAGGED, gfx::Point(10, 10),
    679                                       gfx::Point(10, 10), 0, 0);
    680   DispatchEventUsingWindowDispatcher(&mouse_dragged_event);
    681   DispatchEventUsingWindowDispatcher(&mouse_dragged_event2);
    682   EXPECT_TRUE(recorder.events().empty());
    683   DispatchEventUsingWindowDispatcher(&mouse_pressed_event);
    684   EXPECT_EQ("MOUSE_DRAGGED MOUSE_PRESSED",
    685             EventTypesToString(recorder.events()));
    686   recorder.Reset();
    687 
    688   // Check that on ReleasePointerMoves, held events are not dispatched
    689   // immediately, but posted instead.
    690   DispatchEventUsingWindowDispatcher(&mouse_dragged_event);
    691   host()->dispatcher()->ReleasePointerMoves();
    692   EXPECT_TRUE(recorder.events().empty());
    693   RunAllPendingInMessageLoop();
    694   EXPECT_EQ("MOUSE_DRAGGED", EventTypesToString(recorder.events()));
    695   recorder.Reset();
    696 
    697   // However if another message comes in before the dispatch of the posted
    698   // event, check that the posted event is dispatched before this new event.
    699   host()->dispatcher()->HoldPointerMoves();
    700   DispatchEventUsingWindowDispatcher(&mouse_dragged_event);
    701   host()->dispatcher()->ReleasePointerMoves();
    702   DispatchEventUsingWindowDispatcher(&mouse_pressed_event);
    703   EXPECT_EQ("MOUSE_DRAGGED MOUSE_PRESSED",
    704             EventTypesToString(recorder.events()));
    705   recorder.Reset();
    706   RunAllPendingInMessageLoop();
    707   EXPECT_TRUE(recorder.events().empty());
    708 
    709   // Check that if the other message is another MOUSE_DRAGGED, we still coalesce
    710   // them.
    711   host()->dispatcher()->HoldPointerMoves();
    712   DispatchEventUsingWindowDispatcher(&mouse_dragged_event);
    713   host()->dispatcher()->ReleasePointerMoves();
    714   DispatchEventUsingWindowDispatcher(&mouse_dragged_event2);
    715   EXPECT_EQ("MOUSE_DRAGGED", EventTypesToString(recorder.events()));
    716   recorder.Reset();
    717   RunAllPendingInMessageLoop();
    718   EXPECT_TRUE(recorder.events().empty());
    719 
    720   // Check that synthetic mouse move event has a right location when issued
    721   // while holding pointer moves.
    722   ui::MouseEvent mouse_dragged_event3(ui::ET_MOUSE_DRAGGED, gfx::Point(28, 28),
    723                                       gfx::Point(28, 28), 0, 0);
    724   host()->dispatcher()->HoldPointerMoves();
    725   DispatchEventUsingWindowDispatcher(&mouse_dragged_event);
    726   DispatchEventUsingWindowDispatcher(&mouse_dragged_event2);
    727   window->SetBounds(gfx::Rect(15, 15, 80, 80));
    728   DispatchEventUsingWindowDispatcher(&mouse_dragged_event3);
    729   RunAllPendingInMessageLoop();
    730   EXPECT_TRUE(recorder.events().empty());
    731   host()->dispatcher()->ReleasePointerMoves();
    732   RunAllPendingInMessageLoop();
    733   EXPECT_EQ("MOUSE_MOVED", EventTypesToString(recorder.events()));
    734   EXPECT_EQ(gfx::Point(13, 13), recorder.mouse_location(0));
    735   recorder.Reset();
    736   root_window()->RemovePreTargetHandler(&recorder);
    737 }
    738 
    739 TEST_F(WindowEventDispatcherTest, TouchMovesHeld) {
    740   EventFilterRecorder recorder;
    741   root_window()->AddPreTargetHandler(&recorder);
    742 
    743   test::TestWindowDelegate delegate;
    744   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
    745       &delegate, 1, gfx::Rect(50, 50, 100, 100), root_window()));
    746 
    747   // Starting the touch and throwing out the first few events, since the system
    748   // is going to generate synthetic mouse events that are not relevant to the
    749   // test.
    750   ui::TouchEvent touch_pressed_event(
    751       ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, ui::EventTimeForNow());
    752   DispatchEventUsingWindowDispatcher(&touch_pressed_event);
    753   recorder.WaitUntilReceivedEvent(ui::ET_GESTURE_SHOW_PRESS);
    754   recorder.Reset();
    755 
    756   host()->dispatcher()->HoldPointerMoves();
    757 
    758   // Check that we don't immediately dispatch the TOUCH_MOVED event.
    759   ui::TouchEvent touch_moved_event(
    760       ui::ET_TOUCH_MOVED, gfx::Point(10, 10), 0, ui::EventTimeForNow());
    761   ui::TouchEvent touch_moved_event2(
    762       ui::ET_TOUCH_MOVED, gfx::Point(11, 10), 0, ui::EventTimeForNow());
    763   ui::TouchEvent touch_moved_event3(
    764       ui::ET_TOUCH_MOVED, gfx::Point(12, 10), 0, ui::EventTimeForNow());
    765 
    766   DispatchEventUsingWindowDispatcher(&touch_moved_event);
    767   EXPECT_TRUE(recorder.events().empty());
    768 
    769   // Check that on ReleasePointerMoves, held events are not dispatched
    770   // immediately, but posted instead.
    771   DispatchEventUsingWindowDispatcher(&touch_moved_event2);
    772   host()->dispatcher()->ReleasePointerMoves();
    773   EXPECT_TRUE(recorder.events().empty());
    774 
    775   RunAllPendingInMessageLoop();
    776   EXPECT_EQ("TOUCH_MOVED", EventTypesToString(recorder.events()));
    777   recorder.Reset();
    778 
    779   // If another touch event occurs then the held touch should be dispatched
    780   // immediately before it.
    781   ui::TouchEvent touch_released_event(
    782       ui::ET_TOUCH_RELEASED, gfx::Point(10, 10), 0, ui::EventTimeForNow());
    783   recorder.Reset();
    784   host()->dispatcher()->HoldPointerMoves();
    785   DispatchEventUsingWindowDispatcher(&touch_moved_event3);
    786   DispatchEventUsingWindowDispatcher(&touch_released_event);
    787   EXPECT_EQ("TOUCH_MOVED TOUCH_RELEASED GESTURE_TAP GESTURE_END",
    788             EventTypesToString(recorder.events()));
    789   recorder.Reset();
    790   host()->dispatcher()->ReleasePointerMoves();
    791   RunAllPendingInMessageLoop();
    792   EXPECT_TRUE(recorder.events().empty());
    793 }
    794 
    795 // Verifies that a direct call to ProcessedTouchEvent() with a
    796 // TOUCH_PRESSED event does not cause a crash.
    797 TEST_F(WindowEventDispatcherTest, CallToProcessedTouchEvent) {
    798   test::TestWindowDelegate delegate;
    799   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
    800       &delegate, 1, gfx::Rect(50, 50, 100, 100), root_window()));
    801 
    802   ui::TouchEvent touch(
    803       ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1, ui::EventTimeForNow());
    804   host()->dispatcher()->ProcessedTouchEvent(
    805       &touch, window.get(), ui::ER_UNHANDLED);
    806 }
    807 
    808 // This event handler requests the dispatcher to start holding pointer-move
    809 // events when it receives the first scroll-update gesture.
    810 class HoldPointerOnScrollHandler : public ui::test::TestEventHandler {
    811  public:
    812   HoldPointerOnScrollHandler(WindowEventDispatcher* dispatcher,
    813                              EventFilterRecorder* filter)
    814       : dispatcher_(dispatcher),
    815         filter_(filter),
    816         holding_moves_(false) {}
    817   virtual ~HoldPointerOnScrollHandler() {}
    818 
    819  private:
    820   // ui::test::TestEventHandler:
    821   virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE {
    822     if (!holding_moves_ && gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
    823       holding_moves_ = true;
    824       dispatcher_->HoldPointerMoves();
    825       filter_->Reset();
    826     } else if (gesture->type() == ui::ET_GESTURE_SCROLL_END) {
    827       dispatcher_->ReleasePointerMoves();
    828       holding_moves_ = false;
    829     }
    830   }
    831 
    832   WindowEventDispatcher* dispatcher_;
    833   EventFilterRecorder* filter_;
    834   bool holding_moves_;
    835 
    836   DISALLOW_COPY_AND_ASSIGN(HoldPointerOnScrollHandler);
    837 };
    838 
    839 // Tests that touch-move events don't contribute to an in-progress scroll
    840 // gesture if touch-move events are being held by the dispatcher.
    841 TEST_F(WindowEventDispatcherTest, TouchMovesHeldOnScroll) {
    842   EventFilterRecorder recorder;
    843   root_window()->AddPreTargetHandler(&recorder);
    844   test::TestWindowDelegate delegate;
    845   HoldPointerOnScrollHandler handler(host()->dispatcher(), &recorder);
    846   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
    847       &delegate, 1, gfx::Rect(50, 50, 100, 100), root_window()));
    848   window->AddPreTargetHandler(&handler);
    849 
    850   ui::test::EventGenerator generator(root_window());
    851   generator.GestureScrollSequence(
    852       gfx::Point(60, 60), gfx::Point(10, 60),
    853       base::TimeDelta::FromMilliseconds(100), 25);
    854 
    855   // |handler| will have reset |filter| and started holding the touch-move
    856   // events when scrolling started. At the end of the scroll (i.e. upon
    857   // touch-release), the held touch-move event will have been dispatched first,
    858   // along with the subsequent events (i.e. touch-release, scroll-end, and
    859   // gesture-end).
    860   const EventFilterRecorder::Events& events = recorder.events();
    861   EXPECT_EQ(
    862       "TOUCH_MOVED GESTURE_SCROLL_UPDATE TOUCH_RELEASED "
    863       "GESTURE_SCROLL_END GESTURE_END",
    864       EventTypesToString(events));
    865   ASSERT_EQ(2u, recorder.touch_locations().size());
    866   EXPECT_EQ(gfx::Point(-40, 10).ToString(),
    867             recorder.touch_locations()[0].ToString());
    868   EXPECT_EQ(gfx::Point(-40, 10).ToString(),
    869             recorder.touch_locations()[1].ToString());
    870 }
    871 
    872 // Tests that a 'held' touch-event does contribute to gesture event when it is
    873 // dispatched.
    874 TEST_F(WindowEventDispatcherTest, HeldTouchMoveContributesToGesture) {
    875   EventFilterRecorder recorder;
    876   root_window()->AddPreTargetHandler(&recorder);
    877 
    878   const gfx::Point location(20, 20);
    879   ui::TouchEvent press(
    880       ui::ET_TOUCH_PRESSED, location, 0, ui::EventTimeForNow());
    881   DispatchEventUsingWindowDispatcher(&press);
    882   EXPECT_TRUE(recorder.HasReceivedEvent(ui::ET_TOUCH_PRESSED));
    883   recorder.Reset();
    884 
    885   host()->dispatcher()->HoldPointerMoves();
    886 
    887   ui::TouchEvent move(ui::ET_TOUCH_MOVED,
    888                       location + gfx::Vector2d(100, 100),
    889                       0,
    890                       ui::EventTimeForNow());
    891   DispatchEventUsingWindowDispatcher(&move);
    892   EXPECT_FALSE(recorder.HasReceivedEvent(ui::ET_TOUCH_MOVED));
    893   EXPECT_FALSE(recorder.HasReceivedEvent(ui::ET_GESTURE_SCROLL_BEGIN));
    894   recorder.Reset();
    895 
    896   host()->dispatcher()->ReleasePointerMoves();
    897   EXPECT_FALSE(recorder.HasReceivedEvent(ui::ET_TOUCH_MOVED));
    898   RunAllPendingInMessageLoop();
    899   EXPECT_TRUE(recorder.HasReceivedEvent(ui::ET_TOUCH_MOVED));
    900   EXPECT_TRUE(recorder.HasReceivedEvent(ui::ET_GESTURE_SCROLL_BEGIN));
    901   EXPECT_TRUE(recorder.HasReceivedEvent(ui::ET_GESTURE_SCROLL_UPDATE));
    902 
    903   root_window()->RemovePreTargetHandler(&recorder);
    904 }
    905 
    906 // Tests that synthetic mouse events are ignored when mouse
    907 // events are disabled.
    908 TEST_F(WindowEventDispatcherTest, DispatchSyntheticMouseEvents) {
    909   EventFilterRecorder recorder;
    910   root_window()->AddPreTargetHandler(&recorder);
    911 
    912   test::TestWindowDelegate delegate;
    913   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
    914       &delegate, 1234, gfx::Rect(5, 5, 100, 100), root_window()));
    915   window->Show();
    916   window->SetCapture();
    917 
    918   test::TestCursorClient cursor_client(root_window());
    919 
    920   // Dispatch a non-synthetic mouse event when mouse events are enabled.
    921   ui::MouseEvent mouse1(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
    922                         gfx::Point(10, 10), 0, 0);
    923   DispatchEventUsingWindowDispatcher(&mouse1);
    924   EXPECT_FALSE(recorder.events().empty());
    925   recorder.Reset();
    926 
    927   // Dispatch a synthetic mouse event when mouse events are enabled.
    928   ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
    929                         gfx::Point(10, 10), ui::EF_IS_SYNTHESIZED, 0);
    930   DispatchEventUsingWindowDispatcher(&mouse2);
    931   EXPECT_FALSE(recorder.events().empty());
    932   recorder.Reset();
    933 
    934   // Dispatch a synthetic mouse event when mouse events are disabled.
    935   cursor_client.DisableMouseEvents();
    936   DispatchEventUsingWindowDispatcher(&mouse2);
    937   EXPECT_TRUE(recorder.events().empty());
    938   root_window()->RemovePreTargetHandler(&recorder);
    939 }
    940 
    941 // Tests that a mouse-move event is not synthesized when a mouse-button is down.
    942 TEST_F(WindowEventDispatcherTest, DoNotSynthesizeWhileButtonDown) {
    943   EventFilterRecorder recorder;
    944   test::TestWindowDelegate delegate;
    945   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
    946       &delegate, 1234, gfx::Rect(5, 5, 100, 100), root_window()));
    947   window->Show();
    948 
    949   window->AddPreTargetHandler(&recorder);
    950   // Dispatch a non-synthetic mouse event when mouse events are enabled.
    951   ui::MouseEvent mouse1(ui::ET_MOUSE_PRESSED, gfx::Point(10, 10),
    952                         gfx::Point(10, 10), ui::EF_LEFT_MOUSE_BUTTON,
    953                         ui::EF_LEFT_MOUSE_BUTTON);
    954   DispatchEventUsingWindowDispatcher(&mouse1);
    955   ASSERT_EQ(1u, recorder.events().size());
    956   EXPECT_EQ(ui::ET_MOUSE_PRESSED, recorder.events()[0]);
    957   window->RemovePreTargetHandler(&recorder);
    958   recorder.Reset();
    959 
    960   // Move |window| away from underneath the cursor.
    961   root_window()->AddPreTargetHandler(&recorder);
    962   window->SetBounds(gfx::Rect(30, 30, 100, 100));
    963   EXPECT_TRUE(recorder.events().empty());
    964   RunAllPendingInMessageLoop();
    965   EXPECT_TRUE(recorder.events().empty());
    966   root_window()->RemovePreTargetHandler(&recorder);
    967 }
    968 
    969 #if defined(OS_WIN) && defined(ARCH_CPU_X86)
    970 #define MAYBE(x) DISABLED_##x
    971 #else
    972 #define MAYBE(x) x
    973 #endif
    974 
    975 // Tests synthetic mouse events generated when window bounds changes such that
    976 // the cursor previously outside the window becomes inside, or vice versa.
    977 // Do not synthesize events if the window ignores events or is invisible.
    978 // Flaky on 32-bit Windows bots.  http://crbug.com/388272
    979 TEST_F(WindowEventDispatcherTest,
    980        MAYBE(SynthesizeMouseEventsOnWindowBoundsChanged)) {
    981   test::TestWindowDelegate delegate;
    982   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
    983       &delegate, 1234, gfx::Rect(5, 5, 100, 100), root_window()));
    984   window->Show();
    985   window->SetCapture();
    986 
    987   EventFilterRecorder recorder;
    988   window->AddPreTargetHandler(&recorder);
    989 
    990   // Dispatch a non-synthetic mouse event to place cursor inside window bounds.
    991   ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
    992                        gfx::Point(10, 10), 0, 0);
    993   DispatchEventUsingWindowDispatcher(&mouse);
    994   EXPECT_FALSE(recorder.events().empty());
    995   recorder.Reset();
    996 
    997   // Update the window bounds so that cursor is now outside the window.
    998   // This should trigger a synthetic MOVED event.
    999   gfx::Rect bounds1(20, 20, 100, 100);
   1000   window->SetBounds(bounds1);
   1001   RunAllPendingInMessageLoop();
   1002   ASSERT_FALSE(recorder.events().empty());
   1003   ASSERT_FALSE(recorder.mouse_event_flags().empty());
   1004   EXPECT_EQ(ui::ET_MOUSE_MOVED, recorder.events().back());
   1005   EXPECT_EQ(ui::EF_IS_SYNTHESIZED, recorder.mouse_event_flags().back());
   1006   recorder.Reset();
   1007 
   1008   // Set window to ignore events.
   1009   window->set_ignore_events(true);
   1010 
   1011   // Update the window bounds so that cursor is back inside the window.
   1012   // This should not trigger a synthetic event.
   1013   gfx::Rect bounds2(5, 5, 100, 100);
   1014   window->SetBounds(bounds2);
   1015   RunAllPendingInMessageLoop();
   1016   EXPECT_TRUE(recorder.events().empty());
   1017   recorder.Reset();
   1018 
   1019   // Set window to accept events but invisible.
   1020   window->set_ignore_events(false);
   1021   window->Hide();
   1022   recorder.Reset();
   1023 
   1024   // Update the window bounds so that cursor is outside the window.
   1025   // This should not trigger a synthetic event.
   1026   window->SetBounds(bounds1);
   1027   RunAllPendingInMessageLoop();
   1028   EXPECT_TRUE(recorder.events().empty());
   1029 }
   1030 
   1031 // Tests that a mouse exit is dispatched to the last known cursor location
   1032 // when the cursor becomes invisible.
   1033 TEST_F(WindowEventDispatcherTest, DispatchMouseExitWhenCursorHidden) {
   1034   EventFilterRecorder recorder;
   1035   root_window()->AddPreTargetHandler(&recorder);
   1036 
   1037   test::TestWindowDelegate delegate;
   1038   gfx::Point window_origin(7, 18);
   1039   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   1040       &delegate, 1234, gfx::Rect(window_origin, gfx::Size(100, 100)),
   1041       root_window()));
   1042   window->Show();
   1043 
   1044   // Dispatch a mouse move event into the window.
   1045   gfx::Point mouse_location(gfx::Point(15, 25));
   1046   ui::MouseEvent mouse1(ui::ET_MOUSE_MOVED, mouse_location,
   1047                         mouse_location, 0, 0);
   1048   EXPECT_TRUE(recorder.events().empty());
   1049   DispatchEventUsingWindowDispatcher(&mouse1);
   1050   EXPECT_FALSE(recorder.events().empty());
   1051   recorder.Reset();
   1052 
   1053   // Hide the cursor and verify a mouse exit was dispatched.
   1054   host()->OnCursorVisibilityChanged(false);
   1055   EXPECT_FALSE(recorder.events().empty());
   1056   EXPECT_EQ("MOUSE_EXITED", EventTypesToString(recorder.events()));
   1057 
   1058   // Verify the mouse exit was dispatched at the correct location
   1059   // (in the correct coordinate space).
   1060   int translated_x = mouse_location.x() - window_origin.x();
   1061   int translated_y = mouse_location.y() - window_origin.y();
   1062   gfx::Point translated_point(translated_x, translated_y);
   1063   EXPECT_EQ(recorder.mouse_location(0).ToString(), translated_point.ToString());
   1064   root_window()->RemovePreTargetHandler(&recorder);
   1065 }
   1066 
   1067 // Tests that a synthetic mouse exit is dispatched to the last known cursor
   1068 // location after mouse events are disabled on the cursor client.
   1069 TEST_F(WindowEventDispatcherTest,
   1070        DispatchSyntheticMouseExitAfterMouseEventsDisabled) {
   1071   EventFilterRecorder recorder;
   1072   root_window()->AddPreTargetHandler(&recorder);
   1073 
   1074   test::TestWindowDelegate delegate;
   1075   gfx::Point window_origin(7, 18);
   1076   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   1077       &delegate, 1234, gfx::Rect(window_origin, gfx::Size(100, 100)),
   1078       root_window()));
   1079   window->Show();
   1080 
   1081   // Dispatch a mouse move event into the window.
   1082   gfx::Point mouse_location(gfx::Point(15, 25));
   1083   ui::MouseEvent mouse1(ui::ET_MOUSE_MOVED, mouse_location,
   1084                         mouse_location, 0, 0);
   1085   EXPECT_TRUE(recorder.events().empty());
   1086   DispatchEventUsingWindowDispatcher(&mouse1);
   1087   EXPECT_FALSE(recorder.events().empty());
   1088   recorder.Reset();
   1089 
   1090   test::TestCursorClient cursor_client(root_window());
   1091   cursor_client.DisableMouseEvents();
   1092 
   1093   gfx::Point mouse_exit_location(gfx::Point(150, 150));
   1094   ui::MouseEvent mouse2(ui::ET_MOUSE_EXITED, gfx::Point(150, 150),
   1095                         gfx::Point(150, 150), ui::EF_IS_SYNTHESIZED, 0);
   1096   DispatchEventUsingWindowDispatcher(&mouse2);
   1097 
   1098   EXPECT_FALSE(recorder.events().empty());
   1099   // We get the mouse exited event twice in our filter. Once during the
   1100   // predispatch phase and during the actual dispatch.
   1101   EXPECT_EQ("MOUSE_EXITED MOUSE_EXITED", EventTypesToString(recorder.events()));
   1102 
   1103   // Verify the mouse exit was dispatched at the correct location
   1104   // (in the correct coordinate space).
   1105   int translated_x = mouse_exit_location.x() - window_origin.x();
   1106   int translated_y = mouse_exit_location.y() - window_origin.y();
   1107   gfx::Point translated_point(translated_x, translated_y);
   1108   EXPECT_EQ(recorder.mouse_location(0).ToString(), translated_point.ToString());
   1109   root_window()->RemovePreTargetHandler(&recorder);
   1110 }
   1111 
   1112 class DeletingEventFilter : public ui::EventHandler {
   1113  public:
   1114   DeletingEventFilter()
   1115       : delete_during_pre_handle_(false) {}
   1116   virtual ~DeletingEventFilter() {}
   1117 
   1118   void Reset(bool delete_during_pre_handle) {
   1119     delete_during_pre_handle_ = delete_during_pre_handle;
   1120   }
   1121 
   1122  private:
   1123   // Overridden from ui::EventHandler:
   1124   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
   1125     if (delete_during_pre_handle_)
   1126       delete event->target();
   1127   }
   1128 
   1129   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   1130     if (delete_during_pre_handle_)
   1131       delete event->target();
   1132   }
   1133 
   1134   bool delete_during_pre_handle_;
   1135 
   1136   DISALLOW_COPY_AND_ASSIGN(DeletingEventFilter);
   1137 };
   1138 
   1139 class DeletingWindowDelegate : public test::TestWindowDelegate {
   1140  public:
   1141   DeletingWindowDelegate()
   1142       : window_(NULL),
   1143         delete_during_handle_(false),
   1144         got_event_(false) {}
   1145   virtual ~DeletingWindowDelegate() {}
   1146 
   1147   void Reset(Window* window, bool delete_during_handle) {
   1148     window_ = window;
   1149     delete_during_handle_ = delete_during_handle;
   1150     got_event_ = false;
   1151   }
   1152   bool got_event() const { return got_event_; }
   1153 
   1154  private:
   1155   // Overridden from WindowDelegate:
   1156   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
   1157     if (delete_during_handle_)
   1158       delete window_;
   1159     got_event_ = true;
   1160   }
   1161 
   1162   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   1163     if (delete_during_handle_)
   1164       delete window_;
   1165     got_event_ = true;
   1166   }
   1167 
   1168   Window* window_;
   1169   bool delete_during_handle_;
   1170   bool got_event_;
   1171 
   1172   DISALLOW_COPY_AND_ASSIGN(DeletingWindowDelegate);
   1173 };
   1174 
   1175 TEST_F(WindowEventDispatcherTest, DeleteWindowDuringDispatch) {
   1176   // Verifies that we can delete a window during each phase of event handling.
   1177   // Deleting the window should not cause a crash, only prevent further
   1178   // processing from occurring.
   1179   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), NULL));
   1180   DeletingWindowDelegate d11;
   1181   Window* w11 = CreateNormalWindow(11, w1.get(), &d11);
   1182   WindowTracker tracker;
   1183   DeletingEventFilter w1_filter;
   1184   w1->AddPreTargetHandler(&w1_filter);
   1185   client::GetFocusClient(w1.get())->FocusWindow(w11);
   1186 
   1187   ui::test::EventGenerator generator(root_window(), w11);
   1188 
   1189   // First up, no one deletes anything.
   1190   tracker.Add(w11);
   1191   d11.Reset(w11, false);
   1192 
   1193   generator.PressLeftButton();
   1194   EXPECT_TRUE(tracker.Contains(w11));
   1195   EXPECT_TRUE(d11.got_event());
   1196   generator.ReleaseLeftButton();
   1197 
   1198   // Delegate deletes w11. This will prevent the post-handle step from applying.
   1199   w1_filter.Reset(false);
   1200   d11.Reset(w11, true);
   1201   generator.PressKey(ui::VKEY_A, 0);
   1202   EXPECT_FALSE(tracker.Contains(w11));
   1203   EXPECT_TRUE(d11.got_event());
   1204 
   1205   // Pre-handle step deletes w11. This will prevent the delegate and the post-
   1206   // handle steps from applying.
   1207   w11 = CreateNormalWindow(11, w1.get(), &d11);
   1208   w1_filter.Reset(true);
   1209   d11.Reset(w11, false);
   1210   generator.PressLeftButton();
   1211   EXPECT_FALSE(tracker.Contains(w11));
   1212   EXPECT_FALSE(d11.got_event());
   1213 }
   1214 
   1215 namespace {
   1216 
   1217 // A window delegate that detaches the parent of the target's parent window when
   1218 // it receives a tap event.
   1219 class DetachesParentOnTapDelegate : public test::TestWindowDelegate {
   1220  public:
   1221   DetachesParentOnTapDelegate() {}
   1222   virtual ~DetachesParentOnTapDelegate() {}
   1223 
   1224  private:
   1225   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
   1226     if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
   1227       event->SetHandled();
   1228       return;
   1229     }
   1230 
   1231     if (event->type() == ui::ET_GESTURE_TAP) {
   1232       Window* parent = static_cast<Window*>(event->target())->parent();
   1233       parent->parent()->RemoveChild(parent);
   1234       event->SetHandled();
   1235     }
   1236   }
   1237 
   1238   DISALLOW_COPY_AND_ASSIGN(DetachesParentOnTapDelegate);
   1239 };
   1240 
   1241 }  // namespace
   1242 
   1243 // Tests that the gesture recognizer is reset for all child windows when a
   1244 // window hides. No expectations, just checks that the test does not crash.
   1245 TEST_F(WindowEventDispatcherTest,
   1246        GestureRecognizerResetsTargetWhenParentHides) {
   1247   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), NULL));
   1248   DetachesParentOnTapDelegate delegate;
   1249   scoped_ptr<Window> parent(CreateNormalWindow(22, w1.get(), NULL));
   1250   Window* child = CreateNormalWindow(11, parent.get(), &delegate);
   1251   ui::test::EventGenerator generator(root_window(), child);
   1252   generator.GestureTapAt(gfx::Point(40, 40));
   1253 }
   1254 
   1255 namespace {
   1256 
   1257 // A window delegate that processes nested gestures on tap.
   1258 class NestedGestureDelegate : public test::TestWindowDelegate {
   1259  public:
   1260   NestedGestureDelegate(ui::test::EventGenerator* generator,
   1261                         const gfx::Point tap_location)
   1262       : generator_(generator),
   1263         tap_location_(tap_location),
   1264         gesture_end_count_(0) {}
   1265   virtual ~NestedGestureDelegate() {}
   1266 
   1267   int gesture_end_count() const { return gesture_end_count_; }
   1268 
   1269  private:
   1270   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
   1271     switch (event->type()) {
   1272       case ui::ET_GESTURE_TAP_DOWN:
   1273         event->SetHandled();
   1274         break;
   1275       case ui::ET_GESTURE_TAP:
   1276         if (generator_)
   1277           generator_->GestureTapAt(tap_location_);
   1278         event->SetHandled();
   1279         break;
   1280       case ui::ET_GESTURE_END:
   1281         ++gesture_end_count_;
   1282         break;
   1283       default:
   1284         break;
   1285     }
   1286   }
   1287 
   1288   ui::test::EventGenerator* generator_;
   1289   const gfx::Point tap_location_;
   1290   int gesture_end_count_;
   1291   DISALLOW_COPY_AND_ASSIGN(NestedGestureDelegate);
   1292 };
   1293 
   1294 }  // namespace
   1295 
   1296 // Tests that gesture end is delivered after nested gesture processing.
   1297 TEST_F(WindowEventDispatcherTest, GestureEndDeliveredAfterNestedGestures) {
   1298   NestedGestureDelegate d1(NULL, gfx::Point());
   1299   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), &d1));
   1300   w1->SetBounds(gfx::Rect(0, 0, 100, 100));
   1301 
   1302   ui::test::EventGenerator nested_generator(root_window(), w1.get());
   1303   NestedGestureDelegate d2(&nested_generator, w1->bounds().CenterPoint());
   1304   scoped_ptr<Window> w2(CreateNormalWindow(1, root_window(), &d2));
   1305   w2->SetBounds(gfx::Rect(100, 0, 100, 100));
   1306 
   1307   // Tap on w2 which triggers nested gestures for w1.
   1308   ui::test::EventGenerator generator(root_window(), w2.get());
   1309   generator.GestureTapAt(w2->bounds().CenterPoint());
   1310 
   1311   // Both windows should get their gesture end events.
   1312   EXPECT_EQ(1, d1.gesture_end_count());
   1313   EXPECT_EQ(1, d2.gesture_end_count());
   1314 }
   1315 
   1316 // Tests whether we can repost the Tap down gesture event.
   1317 TEST_F(WindowEventDispatcherTest, RepostTapdownGestureTest) {
   1318   EventFilterRecorder recorder;
   1319   root_window()->AddPreTargetHandler(&recorder);
   1320 
   1321   test::TestWindowDelegate delegate;
   1322   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   1323       &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
   1324 
   1325   ui::GestureEventDetails details(ui::ET_GESTURE_TAP_DOWN);
   1326   gfx::Point point(10, 10);
   1327   ui::GestureEvent event(point.x(),
   1328                          point.y(),
   1329                          0,
   1330                          ui::EventTimeForNow(),
   1331                          details);
   1332   host()->dispatcher()->RepostEvent(event);
   1333   RunAllPendingInMessageLoop();
   1334   // TODO(rbyers): Currently disabled - crbug.com/170987
   1335   EXPECT_FALSE(EventTypesToString(recorder.events()).find("GESTURE_TAP_DOWN") !=
   1336               std::string::npos);
   1337   recorder.Reset();
   1338   root_window()->RemovePreTargetHandler(&recorder);
   1339 }
   1340 
   1341 // This class inherits from the EventFilterRecorder class which provides a
   1342 // facility to record events. This class additionally provides a facility to
   1343 // repost the ET_GESTURE_TAP_DOWN gesture to the target window and records
   1344 // events after that.
   1345 class RepostGestureEventRecorder : public EventFilterRecorder {
   1346  public:
   1347   RepostGestureEventRecorder(aura::Window* repost_source,
   1348                              aura::Window* repost_target)
   1349       : repost_source_(repost_source),
   1350         repost_target_(repost_target),
   1351         reposted_(false),
   1352         done_cleanup_(false) {}
   1353 
   1354   virtual ~RepostGestureEventRecorder() {}
   1355 
   1356   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
   1357     if (reposted_ && event->type() == ui::ET_TOUCH_PRESSED) {
   1358       done_cleanup_ = true;
   1359       Reset();
   1360     }
   1361     EventFilterRecorder::OnTouchEvent(event);
   1362   }
   1363 
   1364   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
   1365     EXPECT_EQ(done_cleanup_ ? repost_target_ : repost_source_, event->target());
   1366     if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
   1367       if (!reposted_) {
   1368         EXPECT_NE(repost_target_, event->target());
   1369         reposted_ = true;
   1370         repost_target_->GetHost()->dispatcher()->RepostEvent(*event);
   1371         // Ensure that the reposted gesture event above goes to the
   1372         // repost_target_;
   1373         repost_source_->GetRootWindow()->RemoveChild(repost_source_);
   1374         return;
   1375       }
   1376     }
   1377     EventFilterRecorder::OnGestureEvent(event);
   1378   }
   1379 
   1380   // Ignore mouse events as they don't fire at all times. This causes
   1381   // the GestureRepostEventOrder test to fail randomly.
   1382   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {}
   1383 
   1384  private:
   1385   aura::Window* repost_source_;
   1386   aura::Window* repost_target_;
   1387   // set to true if we reposted the ET_GESTURE_TAP_DOWN event.
   1388   bool reposted_;
   1389   // set true if we're done cleaning up after hiding repost_source_;
   1390   bool done_cleanup_;
   1391   DISALLOW_COPY_AND_ASSIGN(RepostGestureEventRecorder);
   1392 };
   1393 
   1394 // Tests whether events which are generated after the reposted gesture event
   1395 // are received after that. In this case the scroll sequence events should
   1396 // be received after the reposted gesture event.
   1397 TEST_F(WindowEventDispatcherTest, GestureRepostEventOrder) {
   1398   // Expected events at the end for the repost_target window defined below.
   1399   const char kExpectedTargetEvents[] =
   1400     // TODO)(rbyers): Gesture event reposting is disabled - crbug.com/279039.
   1401     // "GESTURE_BEGIN GESTURE_TAP_DOWN "
   1402     "TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED "
   1403     "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE TOUCH_MOVED "
   1404     "GESTURE_SCROLL_UPDATE TOUCH_MOVED GESTURE_SCROLL_UPDATE TOUCH_RELEASED "
   1405     "GESTURE_SCROLL_END GESTURE_END";
   1406   // We create two windows.
   1407   // The first window (repost_source) is the one to which the initial tap
   1408   // gesture is sent. It reposts this event to the second window
   1409   // (repost_target).
   1410   // We then generate the scroll sequence for repost_target and look for two
   1411   // ET_GESTURE_TAP_DOWN events in the event list at the end.
   1412   test::TestWindowDelegate delegate;
   1413   scoped_ptr<aura::Window> repost_target(CreateTestWindowWithDelegate(
   1414       &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
   1415 
   1416   scoped_ptr<aura::Window> repost_source(CreateTestWindowWithDelegate(
   1417       &delegate, 1, gfx::Rect(0, 0, 50, 50), root_window()));
   1418 
   1419   RepostGestureEventRecorder repost_event_recorder(repost_source.get(),
   1420                                                    repost_target.get());
   1421   root_window()->AddPreTargetHandler(&repost_event_recorder);
   1422 
   1423   // Generate a tap down gesture for the repost_source. This will be reposted
   1424   // to repost_target.
   1425   ui::test::EventGenerator repost_generator(root_window(), repost_source.get());
   1426   repost_generator.GestureTapAt(gfx::Point(40, 40));
   1427   RunAllPendingInMessageLoop();
   1428 
   1429   ui::test::EventGenerator scroll_generator(root_window(), repost_target.get());
   1430   scroll_generator.GestureScrollSequence(
   1431       gfx::Point(80, 80),
   1432       gfx::Point(100, 100),
   1433       base::TimeDelta::FromMilliseconds(100),
   1434       3);
   1435   RunAllPendingInMessageLoop();
   1436 
   1437   int tap_down_count = 0;
   1438   for (size_t i = 0; i < repost_event_recorder.events().size(); ++i) {
   1439     if (repost_event_recorder.events()[i] == ui::ET_GESTURE_TAP_DOWN)
   1440       ++tap_down_count;
   1441   }
   1442 
   1443   // We expect two tap down events. One from the repost and the other one from
   1444   // the scroll sequence posted above.
   1445   // TODO(rbyers): Currently disabled - crbug.com/170987
   1446   EXPECT_EQ(1, tap_down_count);
   1447 
   1448   EXPECT_EQ(kExpectedTargetEvents,
   1449             EventTypesToString(repost_event_recorder.events()));
   1450   root_window()->RemovePreTargetHandler(&repost_event_recorder);
   1451 }
   1452 
   1453 class OnMouseExitDeletingEventFilter : public EventFilterRecorder {
   1454  public:
   1455   OnMouseExitDeletingEventFilter() : window_to_delete_(NULL) {}
   1456   virtual ~OnMouseExitDeletingEventFilter() {}
   1457 
   1458   void set_window_to_delete(Window* window_to_delete) {
   1459     window_to_delete_ = window_to_delete;
   1460   }
   1461 
   1462  private:
   1463   // Overridden from ui::EventHandler:
   1464   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   1465     EventFilterRecorder::OnMouseEvent(event);
   1466     if (window_to_delete_) {
   1467       delete window_to_delete_;
   1468       window_to_delete_ = NULL;
   1469     }
   1470   }
   1471 
   1472   Window* window_to_delete_;
   1473 
   1474   DISALLOW_COPY_AND_ASSIGN(OnMouseExitDeletingEventFilter);
   1475 };
   1476 
   1477 // Tests that RootWindow drops mouse-moved event that is supposed to be sent to
   1478 // a child, but the child is destroyed because of the synthesized mouse-exit
   1479 // event generated on the previous mouse_moved_handler_.
   1480 TEST_F(WindowEventDispatcherTest, DeleteWindowDuringMouseMovedDispatch) {
   1481   // Create window 1 and set its event filter. Window 1 will take ownership of
   1482   // the event filter.
   1483   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), NULL));
   1484   OnMouseExitDeletingEventFilter w1_filter;
   1485   w1->AddPreTargetHandler(&w1_filter);
   1486   w1->SetBounds(gfx::Rect(20, 20, 60, 60));
   1487   EXPECT_EQ(NULL, host()->dispatcher()->mouse_moved_handler());
   1488 
   1489   ui::test::EventGenerator generator(root_window(), w1.get());
   1490 
   1491   // Move mouse over window 1 to set it as the |mouse_moved_handler_| for the
   1492   // root window.
   1493   generator.MoveMouseTo(51, 51);
   1494   EXPECT_EQ(w1.get(), host()->dispatcher()->mouse_moved_handler());
   1495 
   1496   // Create window 2 under the mouse cursor and stack it above window 1.
   1497   Window* w2 = CreateNormalWindow(2, root_window(), NULL);
   1498   w2->SetBounds(gfx::Rect(30, 30, 40, 40));
   1499   root_window()->StackChildAbove(w2, w1.get());
   1500 
   1501   // Set window 2 as the window that is to be deleted when a mouse-exited event
   1502   // happens on window 1.
   1503   w1_filter.set_window_to_delete(w2);
   1504 
   1505   // Move mosue over window 2. This should generate a mouse-exited event for
   1506   // window 1 resulting in deletion of window 2. The original mouse-moved event
   1507   // that was targeted to window 2 should be dropped since window 2 is
   1508   // destroyed. This test passes if no crash happens.
   1509   generator.MoveMouseTo(52, 52);
   1510   EXPECT_EQ(NULL, host()->dispatcher()->mouse_moved_handler());
   1511 
   1512   // Check events received by window 1.
   1513   EXPECT_EQ("MOUSE_ENTERED MOUSE_MOVED MOUSE_EXITED",
   1514             EventTypesToString(w1_filter.events()));
   1515 }
   1516 
   1517 namespace {
   1518 
   1519 // Used to track if OnWindowDestroying() is invoked and if there is a valid
   1520 // RootWindow at such time.
   1521 class ValidRootDuringDestructionWindowObserver : public aura::WindowObserver {
   1522  public:
   1523   ValidRootDuringDestructionWindowObserver(bool* got_destroying,
   1524                                            bool* has_valid_root)
   1525       : got_destroying_(got_destroying),
   1526         has_valid_root_(has_valid_root) {
   1527   }
   1528 
   1529   // WindowObserver:
   1530   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
   1531     *got_destroying_ = true;
   1532     *has_valid_root_ = (window->GetRootWindow() != NULL);
   1533   }
   1534 
   1535  private:
   1536   bool* got_destroying_;
   1537   bool* has_valid_root_;
   1538 
   1539   DISALLOW_COPY_AND_ASSIGN(ValidRootDuringDestructionWindowObserver);
   1540 };
   1541 
   1542 }  // namespace
   1543 
   1544 // Verifies GetRootWindow() from ~Window returns a valid root.
   1545 TEST_F(WindowEventDispatcherTest, ValidRootDuringDestruction) {
   1546   bool got_destroying = false;
   1547   bool has_valid_root = false;
   1548   ValidRootDuringDestructionWindowObserver observer(&got_destroying,
   1549                                                     &has_valid_root);
   1550   {
   1551     scoped_ptr<WindowTreeHost> host(
   1552         WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100)));
   1553     host->InitHost();
   1554     // Owned by WindowEventDispatcher.
   1555     Window* w1 = CreateNormalWindow(1, host->window(), NULL);
   1556     w1->AddObserver(&observer);
   1557   }
   1558   EXPECT_TRUE(got_destroying);
   1559   EXPECT_TRUE(has_valid_root);
   1560 }
   1561 
   1562 namespace {
   1563 
   1564 // See description above DontResetHeldEvent for details.
   1565 class DontResetHeldEventWindowDelegate : public test::TestWindowDelegate {
   1566  public:
   1567   explicit DontResetHeldEventWindowDelegate(aura::Window* root)
   1568       : root_(root),
   1569         mouse_event_count_(0) {}
   1570   virtual ~DontResetHeldEventWindowDelegate() {}
   1571 
   1572   int mouse_event_count() const { return mouse_event_count_; }
   1573 
   1574   // TestWindowDelegate:
   1575   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   1576     if ((event->flags() & ui::EF_SHIFT_DOWN) != 0 &&
   1577         mouse_event_count_++ == 0) {
   1578       ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED,
   1579                                  gfx::Point(10, 10), gfx::Point(10, 10),
   1580                                  ui::EF_SHIFT_DOWN, 0);
   1581       root_->GetHost()->dispatcher()->RepostEvent(mouse_event);
   1582     }
   1583   }
   1584 
   1585  private:
   1586   Window* root_;
   1587   int mouse_event_count_;
   1588 
   1589   DISALLOW_COPY_AND_ASSIGN(DontResetHeldEventWindowDelegate);
   1590 };
   1591 
   1592 }  // namespace
   1593 
   1594 // Verifies RootWindow doesn't reset |RootWindow::held_repostable_event_| after
   1595 // dispatching. This is done by using DontResetHeldEventWindowDelegate, which
   1596 // tracks the number of events with ui::EF_SHIFT_DOWN set (all reposted events
   1597 // have EF_SHIFT_DOWN). When the first event is seen RepostEvent() is used to
   1598 // schedule another reposted event.
   1599 TEST_F(WindowEventDispatcherTest, DontResetHeldEvent) {
   1600   DontResetHeldEventWindowDelegate delegate(root_window());
   1601   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), &delegate));
   1602   w1->SetBounds(gfx::Rect(0, 0, 40, 40));
   1603   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED,
   1604                          gfx::Point(10, 10), gfx::Point(10, 10),
   1605                          ui::EF_SHIFT_DOWN, 0);
   1606   root_window()->GetHost()->dispatcher()->RepostEvent(pressed);
   1607   ui::MouseEvent pressed2(ui::ET_MOUSE_PRESSED,
   1608                           gfx::Point(10, 10), gfx::Point(10, 10), 0, 0);
   1609   // Dispatch an event to flush event scheduled by way of RepostEvent().
   1610   DispatchEventUsingWindowDispatcher(&pressed2);
   1611   // Delegate should have seen reposted event (identified by way of
   1612   // EF_SHIFT_DOWN). Dispatch another event to flush the second
   1613   // RepostedEvent().
   1614   EXPECT_EQ(1, delegate.mouse_event_count());
   1615   DispatchEventUsingWindowDispatcher(&pressed2);
   1616   EXPECT_EQ(2, delegate.mouse_event_count());
   1617 }
   1618 
   1619 namespace {
   1620 
   1621 // See description above DeleteHostFromHeldMouseEvent for details.
   1622 class DeleteHostFromHeldMouseEventDelegate
   1623     : public test::TestWindowDelegate {
   1624  public:
   1625   explicit DeleteHostFromHeldMouseEventDelegate(WindowTreeHost* host)
   1626       : host_(host),
   1627         got_mouse_event_(false),
   1628         got_destroy_(false) {
   1629   }
   1630   virtual ~DeleteHostFromHeldMouseEventDelegate() {}
   1631 
   1632   bool got_mouse_event() const { return got_mouse_event_; }
   1633   bool got_destroy() const { return got_destroy_; }
   1634 
   1635   // TestWindowDelegate:
   1636   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   1637     if ((event->flags() & ui::EF_SHIFT_DOWN) != 0) {
   1638       got_mouse_event_ = true;
   1639       delete host_;
   1640     }
   1641   }
   1642   virtual void OnWindowDestroyed(Window* window) OVERRIDE {
   1643     got_destroy_ = true;
   1644   }
   1645 
   1646  private:
   1647   WindowTreeHost* host_;
   1648   bool got_mouse_event_;
   1649   bool got_destroy_;
   1650 
   1651   DISALLOW_COPY_AND_ASSIGN(DeleteHostFromHeldMouseEventDelegate);
   1652 };
   1653 
   1654 }  // namespace
   1655 
   1656 // Verifies if a WindowTreeHost is deleted from dispatching a held mouse event
   1657 // we don't crash.
   1658 TEST_F(WindowEventDispatcherTest, DeleteHostFromHeldMouseEvent) {
   1659   // Should be deleted by |delegate|.
   1660   WindowTreeHost* h2 = WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100));
   1661   h2->InitHost();
   1662   DeleteHostFromHeldMouseEventDelegate delegate(h2);
   1663   // Owned by |h2|.
   1664   Window* w1 = CreateNormalWindow(1, h2->window(), &delegate);
   1665   w1->SetBounds(gfx::Rect(0, 0, 40, 40));
   1666   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED,
   1667                          gfx::Point(10, 10), gfx::Point(10, 10),
   1668                          ui::EF_SHIFT_DOWN, 0);
   1669   h2->dispatcher()->RepostEvent(pressed);
   1670   // RunAllPendingInMessageLoop() to make sure the |pressed| is run.
   1671   RunAllPendingInMessageLoop();
   1672   EXPECT_TRUE(delegate.got_mouse_event());
   1673   EXPECT_TRUE(delegate.got_destroy());
   1674 }
   1675 
   1676 TEST_F(WindowEventDispatcherTest, WindowHideCancelsActiveTouches) {
   1677   EventFilterRecorder recorder;
   1678   root_window()->AddPreTargetHandler(&recorder);
   1679 
   1680   test::TestWindowDelegate delegate;
   1681   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   1682       &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
   1683 
   1684   gfx::Point position1 = root_window()->bounds().origin();
   1685   ui::TouchEvent press(
   1686       ui::ET_TOUCH_PRESSED, position1, 0, ui::EventTimeForNow());
   1687   DispatchEventUsingWindowDispatcher(&press);
   1688 
   1689   EXPECT_EQ("TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN",
   1690             EventTypesToString(recorder.GetAndResetEvents()));
   1691 
   1692   window->Hide();
   1693 
   1694   EXPECT_EQ(ui::ET_TOUCH_CANCELLED, recorder.events()[0]);
   1695   EXPECT_TRUE(recorder.HasReceivedEvent(ui::ET_GESTURE_TAP_CANCEL));
   1696   EXPECT_TRUE(recorder.HasReceivedEvent(ui::ET_GESTURE_END));
   1697   EXPECT_EQ(3U, recorder.events().size());
   1698   root_window()->RemovePreTargetHandler(&recorder);
   1699 }
   1700 
   1701 TEST_F(WindowEventDispatcherTest, WindowHideCancelsActiveGestures) {
   1702   EventFilterRecorder recorder;
   1703   root_window()->AddPreTargetHandler(&recorder);
   1704 
   1705   test::TestWindowDelegate delegate;
   1706   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   1707       &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
   1708 
   1709   gfx::Point position1 = root_window()->bounds().origin();
   1710   gfx::Point position2 = root_window()->bounds().CenterPoint();
   1711   ui::TouchEvent press(
   1712       ui::ET_TOUCH_PRESSED, position1, 0, ui::EventTimeForNow());
   1713   DispatchEventUsingWindowDispatcher(&press);
   1714 
   1715   ui::TouchEvent move(
   1716       ui::ET_TOUCH_MOVED, position2, 0, ui::EventTimeForNow());
   1717   DispatchEventUsingWindowDispatcher(&move);
   1718 
   1719   ui::TouchEvent press2(
   1720       ui::ET_TOUCH_PRESSED, position1, 1, ui::EventTimeForNow());
   1721   DispatchEventUsingWindowDispatcher(&press2);
   1722 
   1723   // TODO(tdresser): once the unified Gesture Recognizer has stuck, remove the
   1724   // special casing here. See crbug.com/332418 for details.
   1725   std::string expected =
   1726       "TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED "
   1727       "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE "
   1728       "TOUCH_PRESSED GESTURE_BEGIN GESTURE_PINCH_BEGIN";
   1729 
   1730   std::string expected_ugr =
   1731       "TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED "
   1732       "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE "
   1733       "TOUCH_PRESSED GESTURE_BEGIN";
   1734 
   1735   std::string events_string = EventTypesToString(recorder.GetAndResetEvents());
   1736   EXPECT_TRUE((expected == events_string) || (expected_ugr == events_string));
   1737 
   1738   window->Hide();
   1739 
   1740   expected =
   1741       "TOUCH_CANCELLED GESTURE_PINCH_END GESTURE_END TOUCH_CANCELLED "
   1742       "GESTURE_SCROLL_END GESTURE_END";
   1743   expected_ugr =
   1744       "TOUCH_CANCELLED GESTURE_SCROLL_END GESTURE_END TOUCH_CANCELLED "
   1745       "GESTURE_END";
   1746 
   1747   events_string = EventTypesToString(recorder.GetAndResetEvents());
   1748   EXPECT_TRUE((expected == events_string) || (expected_ugr == events_string));
   1749 
   1750   root_window()->RemovePreTargetHandler(&recorder);
   1751 }
   1752 
   1753 // Places two windows side by side. Presses down on one window, and starts a
   1754 // scroll. Sets capture on the other window and ensures that the "ending" events
   1755 // aren't sent to the window which gained capture.
   1756 TEST_F(WindowEventDispatcherTest, EndingEventDoesntRetarget) {
   1757   EventFilterRecorder recorder1;
   1758   EventFilterRecorder recorder2;
   1759   scoped_ptr<Window> window1(CreateNormalWindow(1, root_window(), NULL));
   1760   window1->SetBounds(gfx::Rect(0, 0, 40, 40));
   1761 
   1762   scoped_ptr<Window> window2(CreateNormalWindow(2, root_window(), NULL));
   1763   window2->SetBounds(gfx::Rect(40, 0, 40, 40));
   1764 
   1765   window1->AddPreTargetHandler(&recorder1);
   1766   window2->AddPreTargetHandler(&recorder2);
   1767 
   1768   gfx::Point position = window1->bounds().origin();
   1769   ui::TouchEvent press(
   1770       ui::ET_TOUCH_PRESSED, position, 0, ui::EventTimeForNow());
   1771   DispatchEventUsingWindowDispatcher(&press);
   1772 
   1773   gfx::Point position2 = window1->bounds().CenterPoint();
   1774   ui::TouchEvent move(
   1775       ui::ET_TOUCH_MOVED, position2, 0, ui::EventTimeForNow());
   1776   DispatchEventUsingWindowDispatcher(&move);
   1777 
   1778   window2->SetCapture();
   1779 
   1780   EXPECT_EQ("TOUCH_PRESSED GESTURE_BEGIN GESTURE_TAP_DOWN TOUCH_MOVED "
   1781             "GESTURE_TAP_CANCEL GESTURE_SCROLL_BEGIN GESTURE_SCROLL_UPDATE "
   1782             "TOUCH_CANCELLED GESTURE_SCROLL_END GESTURE_END",
   1783             EventTypesToString(recorder1.events()));
   1784 
   1785   EXPECT_TRUE(recorder2.events().empty());
   1786 }
   1787 
   1788 namespace {
   1789 
   1790 // This class creates and manages a window which is destroyed as soon as
   1791 // capture is lost. This is the case for the drag and drop capture window.
   1792 class CaptureWindowTracker : public test::TestWindowDelegate {
   1793  public:
   1794   CaptureWindowTracker() {}
   1795   virtual ~CaptureWindowTracker() {}
   1796 
   1797   void CreateCaptureWindow(aura::Window* root_window) {
   1798     capture_window_.reset(test::CreateTestWindowWithDelegate(
   1799         this, -1234, gfx::Rect(20, 20, 20, 20), root_window));
   1800     capture_window_->SetCapture();
   1801   }
   1802 
   1803   void reset() {
   1804     capture_window_.reset();
   1805   }
   1806 
   1807   virtual void OnCaptureLost() OVERRIDE {
   1808     capture_window_.reset();
   1809   }
   1810 
   1811   virtual void OnWindowDestroyed(Window* window) OVERRIDE {
   1812     TestWindowDelegate::OnWindowDestroyed(window);
   1813     capture_window_.reset();
   1814   }
   1815 
   1816   aura::Window* capture_window() { return capture_window_.get(); }
   1817 
   1818  private:
   1819   scoped_ptr<aura::Window> capture_window_;
   1820 
   1821   DISALLOW_COPY_AND_ASSIGN(CaptureWindowTracker);
   1822 };
   1823 
   1824 }
   1825 
   1826 // Verifies handling loss of capture by the capture window being hidden.
   1827 TEST_F(WindowEventDispatcherTest, CaptureWindowHidden) {
   1828   CaptureWindowTracker capture_window_tracker;
   1829   capture_window_tracker.CreateCaptureWindow(root_window());
   1830   capture_window_tracker.capture_window()->Hide();
   1831   EXPECT_EQ(NULL, capture_window_tracker.capture_window());
   1832 }
   1833 
   1834 // Verifies handling loss of capture by the capture window being destroyed.
   1835 TEST_F(WindowEventDispatcherTest, CaptureWindowDestroyed) {
   1836   CaptureWindowTracker capture_window_tracker;
   1837   capture_window_tracker.CreateCaptureWindow(root_window());
   1838   capture_window_tracker.reset();
   1839   EXPECT_EQ(NULL, capture_window_tracker.capture_window());
   1840 }
   1841 
   1842 class ExitMessageLoopOnMousePress : public ui::test::TestEventHandler {
   1843  public:
   1844   ExitMessageLoopOnMousePress() {}
   1845   virtual ~ExitMessageLoopOnMousePress() {}
   1846 
   1847  protected:
   1848   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   1849     ui::test::TestEventHandler::OnMouseEvent(event);
   1850     if (event->type() == ui::ET_MOUSE_PRESSED)
   1851       base::MessageLoopForUI::current()->Quit();
   1852   }
   1853 
   1854  private:
   1855   DISALLOW_COPY_AND_ASSIGN(ExitMessageLoopOnMousePress);
   1856 };
   1857 
   1858 class WindowEventDispatcherTestWithMessageLoop
   1859     : public WindowEventDispatcherTest {
   1860  public:
   1861   WindowEventDispatcherTestWithMessageLoop() {}
   1862   virtual ~WindowEventDispatcherTestWithMessageLoop() {}
   1863 
   1864   void RunTest() {
   1865     // Reset any event the window may have received when bringing up the window
   1866     // (e.g. mouse-move events if the mouse cursor is over the window).
   1867     handler_.Reset();
   1868 
   1869     // Start a nested message-loop, post an event to be dispatched, and then
   1870     // terminate the message-loop. When the message-loop unwinds and gets back,
   1871     // the reposted event should not have fired.
   1872     scoped_ptr<ui::MouseEvent> mouse(new ui::MouseEvent(ui::ET_MOUSE_PRESSED,
   1873                                                         gfx::Point(10, 10),
   1874                                                         gfx::Point(10, 10),
   1875                                                         ui::EF_NONE,
   1876                                                         ui::EF_NONE));
   1877     message_loop()->PostTask(
   1878         FROM_HERE,
   1879         base::Bind(&WindowEventDispatcherTestWithMessageLoop::RepostEventHelper,
   1880                    host()->dispatcher(),
   1881                    base::Passed(&mouse)));
   1882     message_loop()->PostTask(FROM_HERE, message_loop()->QuitClosure());
   1883 
   1884     base::MessageLoop::ScopedNestableTaskAllower allow(message_loop());
   1885     base::RunLoop loop;
   1886     loop.Run();
   1887     EXPECT_EQ(0, handler_.num_mouse_events());
   1888 
   1889     // Let the current message-loop run. The event-handler will terminate the
   1890     // message-loop when it receives the reposted event.
   1891   }
   1892 
   1893   base::MessageLoop* message_loop() {
   1894     return base::MessageLoopForUI::current();
   1895   }
   1896 
   1897  protected:
   1898   virtual void SetUp() OVERRIDE {
   1899     WindowEventDispatcherTest::SetUp();
   1900     window_.reset(CreateNormalWindow(1, root_window(), NULL));
   1901     window_->AddPreTargetHandler(&handler_);
   1902   }
   1903 
   1904   virtual void TearDown() OVERRIDE {
   1905     window_.reset();
   1906     WindowEventDispatcherTest::TearDown();
   1907   }
   1908 
   1909  private:
   1910   // Used to avoid a copying |event| when binding to a closure.
   1911   static void RepostEventHelper(WindowEventDispatcher* dispatcher,
   1912                                 scoped_ptr<ui::MouseEvent> event) {
   1913     dispatcher->RepostEvent(*event);
   1914   }
   1915 
   1916   scoped_ptr<Window> window_;
   1917   ExitMessageLoopOnMousePress handler_;
   1918 
   1919   DISALLOW_COPY_AND_ASSIGN(WindowEventDispatcherTestWithMessageLoop);
   1920 };
   1921 
   1922 TEST_F(WindowEventDispatcherTestWithMessageLoop, EventRepostedInNonNestedLoop) {
   1923   CHECK(!message_loop()->is_running());
   1924   // Perform the test in a callback, so that it runs after the message-loop
   1925   // starts.
   1926   message_loop()->PostTask(
   1927       FROM_HERE, base::Bind(
   1928           &WindowEventDispatcherTestWithMessageLoop::RunTest,
   1929           base::Unretained(this)));
   1930   message_loop()->Run();
   1931 }
   1932 
   1933 class WindowEventDispatcherTestInHighDPI : public WindowEventDispatcherTest {
   1934  public:
   1935   WindowEventDispatcherTestInHighDPI() {}
   1936   virtual ~WindowEventDispatcherTestInHighDPI() {}
   1937 
   1938  protected:
   1939   virtual void SetUp() OVERRIDE {
   1940     WindowEventDispatcherTest::SetUp();
   1941     test_screen()->SetDeviceScaleFactor(2.f);
   1942   }
   1943 };
   1944 
   1945 TEST_F(WindowEventDispatcherTestInHighDPI, EventLocationTransform) {
   1946   test::TestWindowDelegate delegate;
   1947   scoped_ptr<aura::Window> child(test::CreateTestWindowWithDelegate(&delegate,
   1948       1234, gfx::Rect(20, 20, 100, 100), root_window()));
   1949   child->Show();
   1950 
   1951   ui::test::TestEventHandler handler_child;
   1952   ui::test::TestEventHandler handler_root;
   1953   root_window()->AddPreTargetHandler(&handler_root);
   1954   child->AddPreTargetHandler(&handler_child);
   1955 
   1956   {
   1957     ui::MouseEvent move(ui::ET_MOUSE_MOVED,
   1958                         gfx::Point(30, 30), gfx::Point(30, 30),
   1959                         ui::EF_NONE, ui::EF_NONE);
   1960     DispatchEventUsingWindowDispatcher(&move);
   1961     EXPECT_EQ(0, handler_child.num_mouse_events());
   1962     EXPECT_EQ(1, handler_root.num_mouse_events());
   1963   }
   1964 
   1965   {
   1966     ui::MouseEvent move(ui::ET_MOUSE_MOVED,
   1967                         gfx::Point(50, 50), gfx::Point(50, 50),
   1968                         ui::EF_NONE, ui::EF_NONE);
   1969     DispatchEventUsingWindowDispatcher(&move);
   1970     // The child receives an ENTER, and a MOVED event.
   1971     EXPECT_EQ(2, handler_child.num_mouse_events());
   1972     // The root receives both the ENTER and the MOVED events dispatched to
   1973     // |child|, as well as an EXIT event.
   1974     EXPECT_EQ(3, handler_root.num_mouse_events());
   1975   }
   1976 
   1977   child->RemovePreTargetHandler(&handler_child);
   1978   root_window()->RemovePreTargetHandler(&handler_root);
   1979 }
   1980 
   1981 TEST_F(WindowEventDispatcherTestInHighDPI, TouchMovesHeldOnScroll) {
   1982   EventFilterRecorder recorder;
   1983   root_window()->AddPreTargetHandler(&recorder);
   1984   test::TestWindowDelegate delegate;
   1985   HoldPointerOnScrollHandler handler(host()->dispatcher(), &recorder);
   1986   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   1987       &delegate, 1, gfx::Rect(50, 50, 100, 100), root_window()));
   1988   window->AddPreTargetHandler(&handler);
   1989 
   1990   ui::test::EventGenerator generator(root_window());
   1991   generator.GestureScrollSequence(
   1992       gfx::Point(120, 120), gfx::Point(20, 120),
   1993       base::TimeDelta::FromMilliseconds(100), 25);
   1994 
   1995   // |handler| will have reset |filter| and started holding the touch-move
   1996   // events when scrolling started. At the end of the scroll (i.e. upon
   1997   // touch-release), the held touch-move event will have been dispatched first,
   1998   // along with the subsequent events (i.e. touch-release, scroll-end, and
   1999   // gesture-end).
   2000   const EventFilterRecorder::Events& events = recorder.events();
   2001   EXPECT_EQ(
   2002       "TOUCH_MOVED GESTURE_SCROLL_UPDATE TOUCH_RELEASED "
   2003       "GESTURE_SCROLL_END GESTURE_END",
   2004       EventTypesToString(events));
   2005   ASSERT_EQ(2u, recorder.touch_locations().size());
   2006   EXPECT_EQ(gfx::Point(-40, 10).ToString(),
   2007             recorder.touch_locations()[0].ToString());
   2008   EXPECT_EQ(gfx::Point(-40, 10).ToString(),
   2009             recorder.touch_locations()[1].ToString());
   2010 }
   2011 
   2012 class SelfDestructDelegate : public test::TestWindowDelegate {
   2013  public:
   2014   SelfDestructDelegate() {}
   2015   virtual ~SelfDestructDelegate() {}
   2016 
   2017   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   2018     window_.reset();
   2019   }
   2020 
   2021   void set_window(scoped_ptr<aura::Window> window) {
   2022     window_ = window.Pass();
   2023   }
   2024   bool has_window() const { return !!window_.get(); }
   2025 
   2026  private:
   2027   scoped_ptr<aura::Window> window_;
   2028   DISALLOW_COPY_AND_ASSIGN(SelfDestructDelegate);
   2029 };
   2030 
   2031 TEST_F(WindowEventDispatcherTest, SynthesizedLocatedEvent) {
   2032   ui::test::EventGenerator generator(root_window());
   2033   generator.MoveMouseTo(10, 10);
   2034   EXPECT_EQ("10,10",
   2035             Env::GetInstance()->last_mouse_location().ToString());
   2036 
   2037   // Synthesized event should not update the mouse location.
   2038   ui::MouseEvent mouseev(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(),
   2039                          ui::EF_IS_SYNTHESIZED, 0);
   2040   generator.Dispatch(&mouseev);
   2041   EXPECT_EQ("10,10",
   2042             Env::GetInstance()->last_mouse_location().ToString());
   2043 
   2044   generator.MoveMouseTo(0, 0);
   2045   EXPECT_EQ("0,0",
   2046             Env::GetInstance()->last_mouse_location().ToString());
   2047 
   2048   // Make sure the location gets updated when a syntheiszed enter
   2049   // event destroyed the window.
   2050   SelfDestructDelegate delegate;
   2051   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   2052       &delegate, 1, gfx::Rect(50, 50, 100, 100), root_window()));
   2053   delegate.set_window(window.Pass());
   2054   EXPECT_TRUE(delegate.has_window());
   2055 
   2056   generator.MoveMouseTo(100, 100);
   2057   EXPECT_FALSE(delegate.has_window());
   2058   EXPECT_EQ("100,100",
   2059             Env::GetInstance()->last_mouse_location().ToString());
   2060 }
   2061 
   2062 class StaticFocusClient : public client::FocusClient {
   2063  public:
   2064   explicit StaticFocusClient(Window* focused)
   2065       : focused_(focused) {}
   2066   virtual ~StaticFocusClient() {}
   2067 
   2068  private:
   2069   // client::FocusClient:
   2070   virtual void AddObserver(client::FocusChangeObserver* observer) OVERRIDE {}
   2071   virtual void RemoveObserver(client::FocusChangeObserver* observer) OVERRIDE {}
   2072   virtual void FocusWindow(Window* window) OVERRIDE {}
   2073   virtual void ResetFocusWithinActiveWindow(Window* window) OVERRIDE {}
   2074   virtual Window* GetFocusedWindow() OVERRIDE { return focused_; }
   2075 
   2076   Window* focused_;
   2077 
   2078   DISALLOW_COPY_AND_ASSIGN(StaticFocusClient);
   2079 };
   2080 
   2081 // Tests that host-cancel-mode event can be dispatched to a dispatcher safely
   2082 // when the focused window does not live in the dispatcher's tree.
   2083 TEST_F(WindowEventDispatcherTest, HostCancelModeWithFocusedWindowOutside) {
   2084   test::TestWindowDelegate delegate;
   2085   scoped_ptr<Window> focused(CreateTestWindowWithDelegate(&delegate, 123,
   2086       gfx::Rect(20, 30, 100, 50), NULL));
   2087   StaticFocusClient focus_client(focused.get());
   2088   client::SetFocusClient(root_window(), &focus_client);
   2089   EXPECT_FALSE(root_window()->Contains(focused.get()));
   2090   EXPECT_EQ(focused.get(),
   2091             client::GetFocusClient(root_window())->GetFocusedWindow());
   2092   host()->dispatcher()->DispatchCancelModeEvent();
   2093   EXPECT_EQ(focused.get(),
   2094             client::GetFocusClient(root_window())->GetFocusedWindow());
   2095 }
   2096 
   2097 // Dispatches a mouse-move event to |target| when it receives a mouse-move
   2098 // event.
   2099 class DispatchEventHandler : public ui::EventHandler {
   2100  public:
   2101   explicit DispatchEventHandler(Window* target)
   2102       : target_(target),
   2103         dispatched_(false) {}
   2104   virtual ~DispatchEventHandler() {}
   2105 
   2106   bool dispatched() const { return dispatched_; }
   2107  private:
   2108   // ui::EventHandler:
   2109   virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE {
   2110     if (mouse->type() == ui::ET_MOUSE_MOVED) {
   2111       ui::MouseEvent move(ui::ET_MOUSE_MOVED, target_->bounds().CenterPoint(),
   2112           target_->bounds().CenterPoint(), ui::EF_NONE, ui::EF_NONE);
   2113       ui::EventDispatchDetails details =
   2114           target_->GetHost()->dispatcher()->OnEventFromSource(&move);
   2115       ASSERT_FALSE(details.dispatcher_destroyed);
   2116       EXPECT_FALSE(details.target_destroyed);
   2117       EXPECT_EQ(target_, move.target());
   2118       dispatched_ = true;
   2119     }
   2120     ui::EventHandler::OnMouseEvent(mouse);
   2121   }
   2122 
   2123   Window* target_;
   2124   bool dispatched_;
   2125 
   2126   DISALLOW_COPY_AND_ASSIGN(DispatchEventHandler);
   2127 };
   2128 
   2129 // Moves |window| to |root_window| when it receives a mouse-move event.
   2130 class MoveWindowHandler : public ui::EventHandler {
   2131  public:
   2132   MoveWindowHandler(Window* window, Window* root_window)
   2133       : window_to_move_(window),
   2134         root_window_to_move_to_(root_window) {}
   2135   virtual ~MoveWindowHandler() {}
   2136 
   2137  private:
   2138   // ui::EventHandler:
   2139   virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE {
   2140     if (mouse->type() == ui::ET_MOUSE_MOVED) {
   2141       root_window_to_move_to_->AddChild(window_to_move_);
   2142     }
   2143     ui::EventHandler::OnMouseEvent(mouse);
   2144   }
   2145 
   2146   Window* window_to_move_;
   2147   Window* root_window_to_move_to_;
   2148 
   2149   DISALLOW_COPY_AND_ASSIGN(MoveWindowHandler);
   2150 };
   2151 
   2152 // Tests that nested event dispatch works correctly if the target of the older
   2153 // event being dispatched is moved to a different dispatcher in response to an
   2154 // event in the inner loop.
   2155 TEST_F(WindowEventDispatcherTest, NestedEventDispatchTargetMoved) {
   2156   scoped_ptr<WindowTreeHost> second_host(
   2157       WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50)));
   2158   second_host->InitHost();
   2159   Window* second_root = second_host->window();
   2160 
   2161   // Create two windows parented to |root_window()|.
   2162   test::TestWindowDelegate delegate;
   2163   scoped_ptr<Window> first(CreateTestWindowWithDelegate(&delegate, 123,
   2164       gfx::Rect(20, 10, 10, 20), root_window()));
   2165   scoped_ptr<Window> second(CreateTestWindowWithDelegate(&delegate, 234,
   2166       gfx::Rect(40, 10, 50, 20), root_window()));
   2167 
   2168   // Setup a handler on |first| so that it dispatches an event to |second| when
   2169   // |first| receives an event.
   2170   DispatchEventHandler dispatch_event(second.get());
   2171   first->AddPreTargetHandler(&dispatch_event);
   2172 
   2173   // Setup a handler on |second| so that it moves |first| into |second_root|
   2174   // when |second| receives an event.
   2175   MoveWindowHandler move_window(first.get(), second_root);
   2176   second->AddPreTargetHandler(&move_window);
   2177 
   2178   // Some sanity checks: |first| is inside |root_window()|'s tree.
   2179   EXPECT_EQ(root_window(), first->GetRootWindow());
   2180   // The two root windows are different.
   2181   EXPECT_NE(root_window(), second_root);
   2182 
   2183   // Dispatch an event to |first|.
   2184   ui::MouseEvent move(ui::ET_MOUSE_MOVED, first->bounds().CenterPoint(),
   2185                       first->bounds().CenterPoint(), ui::EF_NONE, ui::EF_NONE);
   2186   ui::EventDispatchDetails details =
   2187       host()->dispatcher()->OnEventFromSource(&move);
   2188   ASSERT_FALSE(details.dispatcher_destroyed);
   2189   EXPECT_TRUE(details.target_destroyed);
   2190   EXPECT_EQ(first.get(), move.target());
   2191   EXPECT_TRUE(dispatch_event.dispatched());
   2192   EXPECT_EQ(second_root, first->GetRootWindow());
   2193 
   2194   first->RemovePreTargetHandler(&dispatch_event);
   2195   second->RemovePreTargetHandler(&move_window);
   2196 }
   2197 
   2198 class AlwaysMouseDownInputStateLookup : public InputStateLookup {
   2199  public:
   2200   AlwaysMouseDownInputStateLookup() {}
   2201   virtual ~AlwaysMouseDownInputStateLookup() {}
   2202 
   2203  private:
   2204   // InputStateLookup:
   2205   virtual bool IsMouseButtonDown() const OVERRIDE { return true; }
   2206 
   2207   DISALLOW_COPY_AND_ASSIGN(AlwaysMouseDownInputStateLookup);
   2208 };
   2209 
   2210 TEST_F(WindowEventDispatcherTest,
   2211        CursorVisibilityChangedWhileCaptureWindowInAnotherDispatcher) {
   2212   test::EventCountDelegate delegate;
   2213   scoped_ptr<Window> window(CreateTestWindowWithDelegate(&delegate, 123,
   2214       gfx::Rect(20, 10, 10, 20), root_window()));
   2215   window->Show();
   2216 
   2217   scoped_ptr<WindowTreeHost> second_host(
   2218       WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50)));
   2219   second_host->InitHost();
   2220   WindowEventDispatcher* second_dispatcher = second_host->dispatcher();
   2221 
   2222   // Install an InputStateLookup on the Env that always claims that a
   2223   // mouse-button is down.
   2224   test::EnvTestHelper(Env::GetInstance()).SetInputStateLookup(
   2225       scoped_ptr<InputStateLookup>(new AlwaysMouseDownInputStateLookup()));
   2226 
   2227   window->SetCapture();
   2228 
   2229   // Because the mouse button is down, setting the capture on |window| will set
   2230   // it as the mouse-move handler for |root_window()|.
   2231   EXPECT_EQ(window.get(), host()->dispatcher()->mouse_moved_handler());
   2232 
   2233   // This does not set |window| as the mouse-move handler for the second
   2234   // dispatcher.
   2235   EXPECT_EQ(NULL, second_dispatcher->mouse_moved_handler());
   2236 
   2237   // However, some capture-client updates the capture in each root-window on a
   2238   // capture. Emulate that here. Because of this, the second dispatcher also has
   2239   // |window| as the mouse-move handler.
   2240   client::CaptureDelegate* second_capture_delegate = second_dispatcher;
   2241   second_capture_delegate->UpdateCapture(NULL, window.get());
   2242   EXPECT_EQ(window.get(), second_dispatcher->mouse_moved_handler());
   2243 
   2244   // Reset the mouse-event counts for |window|.
   2245   delegate.GetMouseMotionCountsAndReset();
   2246 
   2247   // Notify both hosts that the cursor is now hidden. This should send a single
   2248   // mouse-exit event to |window|.
   2249   host()->OnCursorVisibilityChanged(false);
   2250   second_host->OnCursorVisibilityChanged(false);
   2251   EXPECT_EQ("0 0 1", delegate.GetMouseMotionCountsAndReset());
   2252 }
   2253 
   2254 TEST_F(WindowEventDispatcherTest,
   2255        RedirectedEventToDifferentDispatcherLocation) {
   2256   scoped_ptr<WindowTreeHost> second_host(
   2257       WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50)));
   2258   second_host->InitHost();
   2259   client::SetCaptureClient(second_host->window(),
   2260                            client::GetCaptureClient(root_window()));
   2261 
   2262   test::EventCountDelegate delegate;
   2263   scoped_ptr<Window> window_first(CreateTestWindowWithDelegate(&delegate, 123,
   2264       gfx::Rect(20, 10, 10, 20), root_window()));
   2265   window_first->Show();
   2266 
   2267   scoped_ptr<Window> window_second(CreateTestWindowWithDelegate(&delegate, 12,
   2268       gfx::Rect(10, 10, 20, 30), second_host->window()));
   2269   window_second->Show();
   2270 
   2271   window_second->SetCapture();
   2272   EXPECT_EQ(window_second.get(),
   2273             client::GetCaptureWindow(root_window()));
   2274 
   2275   // Send an event to the first host. Make sure it goes to |window_second| in
   2276   // |second_host| instead (since it has capture).
   2277   EventFilterRecorder recorder_first;
   2278   window_first->AddPreTargetHandler(&recorder_first);
   2279   EventFilterRecorder recorder_second;
   2280   window_second->AddPreTargetHandler(&recorder_second);
   2281   const gfx::Point event_location(25, 15);
   2282   ui::MouseEvent mouse(ui::ET_MOUSE_PRESSED, event_location,
   2283                        event_location, ui::EF_LEFT_MOUSE_BUTTON,
   2284                        ui::EF_LEFT_MOUSE_BUTTON);
   2285   DispatchEventUsingWindowDispatcher(&mouse);
   2286   EXPECT_TRUE(recorder_first.events().empty());
   2287   ASSERT_EQ(1u, recorder_second.events().size());
   2288   EXPECT_EQ(ui::ET_MOUSE_PRESSED, recorder_second.events()[0]);
   2289   EXPECT_EQ(event_location.ToString(),
   2290             recorder_second.mouse_locations()[0].ToString());
   2291 }
   2292 
   2293 class AsyncWindowDelegate : public test::TestWindowDelegate {
   2294  public:
   2295   AsyncWindowDelegate(WindowEventDispatcher* dispatcher)
   2296       : dispatcher_(dispatcher) {}
   2297 
   2298   void set_window(Window* window) {
   2299     window_ = window;
   2300   }
   2301  private:
   2302   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
   2303     // Convert touch event back to root window coordinates.
   2304     event->ConvertLocationToTarget(window_, window_->GetRootWindow());
   2305     dispatcher_->ProcessedTouchEvent(event, window_, ui::ER_UNHANDLED);
   2306     event->StopPropagation();
   2307   }
   2308 
   2309   WindowEventDispatcher* dispatcher_;
   2310   Window* window_;
   2311 
   2312   DISALLOW_COPY_AND_ASSIGN(AsyncWindowDelegate);
   2313 };
   2314 
   2315 // Tests that gesture events dispatched through the asynchronous flow have
   2316 // co-ordinates in the right co-ordinate space.
   2317 TEST_F(WindowEventDispatcherTest, GestureEventCoordinates) {
   2318   const float kX = 67.3f;
   2319   const float kY = 97.8f;
   2320 
   2321   const int kWindowOffset = 50;
   2322   EventFilterRecorder recorder;
   2323   root_window()->AddPreTargetHandler(&recorder);
   2324   AsyncWindowDelegate delegate(host()->dispatcher());
   2325   HoldPointerOnScrollHandler handler(host()->dispatcher(), &recorder);
   2326   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
   2327       &delegate,
   2328       1,
   2329       gfx::Rect(kWindowOffset, kWindowOffset, 100, 100),
   2330       root_window()));
   2331   window->AddPreTargetHandler(&handler);
   2332 
   2333   delegate.set_window(window.get());
   2334 
   2335   ui::TouchEvent touch_pressed_event(
   2336       ui::ET_TOUCH_PRESSED, gfx::PointF(kX, kY), 0, ui::EventTimeForNow());
   2337 
   2338   DispatchEventUsingWindowDispatcher(&touch_pressed_event);
   2339 
   2340   ASSERT_EQ(1u, recorder.touch_locations().size());
   2341   EXPECT_EQ(gfx::Point(kX - kWindowOffset, kY - kWindowOffset).ToString(),
   2342             recorder.touch_locations()[0].ToString());
   2343 
   2344   ASSERT_EQ(2u, recorder.gesture_locations().size());
   2345   EXPECT_EQ(gfx::Point(kX - kWindowOffset, kY - kWindowOffset).ToString(),
   2346             recorder.gesture_locations()[0].ToString());
   2347 }
   2348 
   2349 }  // namespace aura
   2350