Index: ui/aura/test/event_generator.cc |
diff --git a/ui/aura/test/event_generator.cc b/ui/aura/test/event_generator.cc |
index 42deba8e3723b3b401bd14471b05fabc72f40f81..268958b4ab3f8623439158c56a13726713276c2f 100644 |
--- a/ui/aura/test/event_generator.cc |
+++ b/ui/aura/test/event_generator.cc |
@@ -4,7 +4,9 @@ |
#include "ui/aura/test/event_generator.h" |
+#include "base/bind.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop_proxy.h" |
#include "ui/aura/client/screen_position_client.h" |
#include "ui/aura/root_window.h" |
#include "ui/base/events/event.h" |
@@ -75,7 +77,8 @@ EventGenerator::EventGenerator(RootWindow* root_window) |
: delegate_(new DefaultEventGeneratorDelegate(root_window)), |
current_root_window_(delegate_->GetRootWindowAt(current_location_)), |
flags_(0), |
- grab_(false) { |
+ grab_(false), |
+ async_(false) { |
} |
EventGenerator::EventGenerator(RootWindow* root_window, const gfx::Point& point) |
@@ -83,7 +86,8 @@ EventGenerator::EventGenerator(RootWindow* root_window, const gfx::Point& point) |
current_location_(point), |
current_root_window_(delegate_->GetRootWindowAt(current_location_)), |
flags_(0), |
- grab_(false) { |
+ grab_(false), |
+ async_(false) { |
} |
EventGenerator::EventGenerator(RootWindow* root_window, Window* window) |
@@ -91,17 +95,23 @@ EventGenerator::EventGenerator(RootWindow* root_window, Window* window) |
current_location_(CenterOfWindow(window)), |
current_root_window_(delegate_->GetRootWindowAt(current_location_)), |
flags_(0), |
- grab_(false) { |
+ grab_(false), |
+ async_(false) { |
} |
EventGenerator::EventGenerator(EventGeneratorDelegate* delegate) |
: delegate_(delegate), |
current_root_window_(delegate_->GetRootWindowAt(current_location_)), |
flags_(0), |
- grab_(false) { |
+ grab_(false), |
+ async_(false) { |
} |
EventGenerator::~EventGenerator() { |
+ for (std::list<ui::Event*>::iterator i = pending_events_.begin(); |
+ i != pending_events_.end(); ++i) |
+ delete *i; |
+ pending_events_.clear(); |
} |
void EventGenerator::PressLeftButton() { |
@@ -146,7 +156,7 @@ void EventGenerator::MoveMouseTo(const gfx::Point& point, int count) { |
UpdateCurrentRootWindow(move_point); |
ConvertPointToTarget(current_root_window_, &move_point); |
ui::MouseEvent mouseev(event_type, move_point, move_point, flags_); |
- Dispatch(mouseev); |
+ Dispatch(&mouseev); |
} |
current_location_ = point; |
} |
@@ -171,12 +181,12 @@ void EventGenerator::MoveMouseToCenterOf(Window* window) { |
void EventGenerator::PressTouch() { |
TestTouchEvent touchev( |
ui::ET_TOUCH_PRESSED, GetLocationInCurrentRoot(), flags_); |
- Dispatch(touchev); |
+ Dispatch(&touchev); |
} |
void EventGenerator::MoveTouch(const gfx::Point& point) { |
TestTouchEvent touchev(ui::ET_TOUCH_MOVED, point, flags_); |
- Dispatch(touchev); |
+ Dispatch(&touchev); |
current_location_ = point; |
if (!grab_) |
@@ -186,7 +196,7 @@ void EventGenerator::MoveTouch(const gfx::Point& point) { |
void EventGenerator::ReleaseTouch() { |
TestTouchEvent touchev( |
ui::ET_TOUCH_RELEASED, GetLocationInCurrentRoot(), flags_); |
- Dispatch(touchev); |
+ Dispatch(&touchev); |
} |
void EventGenerator::PressMoveAndReleaseTouchTo(const gfx::Point& point) { |
@@ -205,12 +215,12 @@ void EventGenerator::GestureTapAt(const gfx::Point& location) { |
location, |
kTouchId, |
ui::EventTimeForNow()); |
- Dispatch(press); |
+ Dispatch(&press); |
ui::TouchEvent release( |
ui::ET_TOUCH_RELEASED, location, kTouchId, |
press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); |
- Dispatch(release); |
+ Dispatch(&release); |
} |
void EventGenerator::GestureTapDownAndUp(const gfx::Point& location) { |
@@ -219,12 +229,12 @@ void EventGenerator::GestureTapDownAndUp(const gfx::Point& location) { |
location, |
kTouchId, |
ui::EventTimeForNow()); |
- Dispatch(press); |
+ Dispatch(&press); |
ui::TouchEvent release( |
ui::ET_TOUCH_RELEASED, location, kTouchId, |
press.time_stamp() + base::TimeDelta::FromMilliseconds(1000)); |
- Dispatch(release); |
+ Dispatch(&release); |
} |
void EventGenerator::GestureScrollSequence(const gfx::Point& start, |
@@ -234,7 +244,7 @@ void EventGenerator::GestureScrollSequence(const gfx::Point& start, |
const int kTouchId = 5; |
base::TimeDelta timestamp = ui::EventTimeForNow(); |
ui::TouchEvent press(ui::ET_TOUCH_PRESSED, start, kTouchId, timestamp); |
- Dispatch(press); |
+ Dispatch(&press); |
int dx = (end.x() - start.x()) / steps; |
int dy = (end.y() - start.y()) / steps; |
@@ -243,11 +253,11 @@ void EventGenerator::GestureScrollSequence(const gfx::Point& start, |
location.Offset(dx, dy); |
timestamp += step_delay; |
ui::TouchEvent move(ui::ET_TOUCH_MOVED, location, kTouchId, timestamp); |
- Dispatch(move); |
+ Dispatch(&move); |
} |
ui::TouchEvent release(ui::ET_TOUCH_RELEASED, end, kTouchId, timestamp); |
- Dispatch(release); |
+ Dispatch(&release); |
} |
void EventGenerator::GestureMultiFingerScroll(int count, |
@@ -268,7 +278,7 @@ void EventGenerator::GestureMultiFingerScroll(int count, |
for (int i = 0; i < count; ++i) { |
points[i] = start[i]; |
ui::TouchEvent press(ui::ET_TOUCH_PRESSED, points[i], i, press_time); |
- Dispatch(press); |
+ Dispatch(&press); |
} |
for (int step = 0; step < steps; ++step) { |
@@ -277,7 +287,7 @@ void EventGenerator::GestureMultiFingerScroll(int count, |
for (int i = 0; i < count; ++i) { |
points[i].Offset(delta_x, delta_y); |
ui::TouchEvent move(ui::ET_TOUCH_MOVED, points[i], i, move_time); |
- Dispatch(move); |
+ Dispatch(&move); |
} |
} |
@@ -286,10 +296,88 @@ void EventGenerator::GestureMultiFingerScroll(int count, |
for (int i = 0; i < count; ++i) { |
ui::TouchEvent release( |
ui::ET_TOUCH_RELEASED, points[i], i, release_time); |
- Dispatch(release); |
+ Dispatch(&release); |
} |
} |
+void EventGenerator::ScrollSequence(const gfx::Point& start, |
+ const base::TimeDelta& step_delay, |
+ float x_offset, |
+ float y_offset, |
+ int steps, |
+ int num_fingers) { |
+ base::TimeDelta timestamp = base::TimeDelta::FromInternalValue( |
+ base::TimeTicks::Now().ToInternalValue()); |
+ ui::ScrollEvent fling_cancel(ui::ET_SCROLL_FLING_CANCEL, |
+ start, |
+ timestamp, |
+ 0, |
+ 0, |
+ 0, |
+ num_fingers); |
+ Dispatch(&fling_cancel); |
+ |
+ float dx = x_offset / steps; |
+ float dy = y_offset / steps; |
+ for (int i = 0; i < steps; ++i) { |
+ timestamp += step_delay; |
+ ui::ScrollEvent move(ui::ET_SCROLL, |
+ start, |
+ timestamp, |
+ 0, |
+ dx, |
+ dy, |
+ num_fingers); |
+ Dispatch(&move); |
+ } |
+ |
+ ui::ScrollEvent fling_start(ui::ET_SCROLL_FLING_START, |
+ start, |
+ timestamp, |
+ 0, |
+ x_offset, |
+ y_offset, |
+ num_fingers); |
+ Dispatch(&fling_start); |
+} |
+ |
+void EventGenerator::ScrollSequence(const gfx::Point& start, |
+ const base::TimeDelta& step_delay, |
+ const std::vector<gfx::Point>& offsets, |
+ int num_fingers) { |
+ int steps = offsets.size(); |
+ base::TimeDelta timestamp = ui::EventTimeForNow(); |
+ ui::ScrollEvent fling_cancel(ui::ET_SCROLL_FLING_CANCEL, |
+ start, |
+ timestamp, |
+ 0, |
+ 0, |
+ 0, |
+ num_fingers); |
+ Dispatch(&fling_cancel); |
+ |
+ for (int i = 0; i < steps; ++i) { |
+ timestamp += step_delay; |
+ ui::ScrollEvent scroll(ui::ET_SCROLL, |
+ start, |
+ timestamp, |
+ 0, |
+ offsets[i].x(), |
+ offsets[i].y(), |
+ num_fingers); |
+ Dispatch(&scroll); |
+ } |
+ |
+ ui::ScrollEvent fling_start(ui::ET_SCROLL_FLING_START, |
+ start, |
+ timestamp, |
+ 0, |
+ offsets[steps - 1].x(), |
+ offsets[steps - 1].y(), |
+ num_fingers); |
+ Dispatch(&fling_start); |
+} |
+ |
void EventGenerator::PressKey(ui::KeyboardCode key_code, int flags) { |
DispatchKeyEvent(true, key_code, flags); |
} |
@@ -298,35 +386,8 @@ void EventGenerator::ReleaseKey(ui::KeyboardCode key_code, int flags) { |
DispatchKeyEvent(false, key_code, flags); |
} |
-void EventGenerator::Dispatch(ui::Event& event) { |
- switch (event.type()) { |
- case ui::ET_KEY_PRESSED: |
- case ui::ET_KEY_RELEASED: |
- current_root_window_->AsRootWindowHostDelegate()->OnHostKeyEvent( |
- static_cast<ui::KeyEvent*>(&event)); |
- break; |
- case ui::ET_MOUSE_PRESSED: |
- case ui::ET_MOUSE_DRAGGED: |
- case ui::ET_MOUSE_RELEASED: |
- case ui::ET_MOUSE_MOVED: |
- case ui::ET_MOUSE_ENTERED: |
- case ui::ET_MOUSE_EXITED: |
- case ui::ET_MOUSEWHEEL: |
- current_root_window_->AsRootWindowHostDelegate()->OnHostMouseEvent( |
- static_cast<ui::MouseEvent*>(&event)); |
- break; |
- case ui::ET_TOUCH_RELEASED: |
- case ui::ET_TOUCH_PRESSED: |
- case ui::ET_TOUCH_MOVED: |
- case ui::ET_TOUCH_STATIONARY: |
- case ui::ET_TOUCH_CANCELLED: |
- current_root_window_->AsRootWindowHostDelegate()->OnHostTouchEvent( |
- static_cast<ui::TouchEvent*>(&event)); |
- break; |
- default: |
- NOTIMPLEMENTED(); |
- break; |
- } |
+void EventGenerator::Dispatch(ui::Event* event) { |
+ DoDispatchEvent(event, async_); |
} |
void EventGenerator::DispatchKeyEvent(bool is_press, |
@@ -338,7 +399,7 @@ void EventGenerator::DispatchKeyEvent(bool is_press, |
if (is_press && character) { |
MSG native_event = { NULL, WM_KEYDOWN, key_code, 0 }; |
TestKeyEvent keyev(native_event, flags, false); |
- Dispatch(keyev); |
+ Dispatch(&keyev); |
// On Windows, WM_KEYDOWN event is followed by WM_CHAR with a character |
// if the key event cooresponds to a real character. |
key_press = WM_CHAR; |
@@ -357,7 +418,7 @@ void EventGenerator::DispatchKeyEvent(bool is_press, |
ui::KeyEvent keyev(type, key_code, flags, false); |
#endif // USE_X11 |
#endif // OS_WIN |
- Dispatch(keyev); |
+ Dispatch(&keyev); |
} |
void EventGenerator::UpdateCurrentRootWindow(const gfx::Point& point) { |
@@ -370,7 +431,7 @@ void EventGenerator::PressButton(int flag) { |
grab_ = flags_ & kAllButtonMask; |
gfx::Point location = GetLocationInCurrentRoot(); |
ui::MouseEvent mouseev(ui::ET_MOUSE_PRESSED, location, location, flags_); |
- Dispatch(mouseev); |
+ Dispatch(&mouseev); |
} |
} |
@@ -379,7 +440,7 @@ void EventGenerator::ReleaseButton(int flag) { |
gfx::Point location = GetLocationInCurrentRoot(); |
ui::MouseEvent mouseev(ui::ET_MOUSE_RELEASED, location, |
location, flags_); |
- Dispatch(mouseev); |
+ Dispatch(&mouseev); |
flags_ ^= flag; |
} |
grab_ = flags_ & kAllButtonMask; |
@@ -419,5 +480,64 @@ gfx::Point EventGenerator::CenterOfWindow(const Window* window) const { |
return center; |
} |
+void EventGenerator::DoDispatchEvent(ui::Event* event, bool async) { |
+ if (async) { |
+ ui::Event* pending_event; |
+ if (event->IsKeyEvent()) { |
+ pending_event = new ui::KeyEvent(*static_cast<ui::KeyEvent*>(event)); |
+ } else if (event->IsMouseEvent()) { |
+ pending_event = new ui::MouseEvent(*static_cast<ui::MouseEvent*>(event)); |
+ } else if (event->IsTouchEvent()) { |
+ pending_event = new ui::TouchEvent(*static_cast<ui::TouchEvent*>(event)); |
+ } else if (event->IsScrollEvent()) { |
+ pending_event = |
+ new ui::ScrollEvent(*static_cast<ui::ScrollEvent*>(event)); |
+ } else { |
+ NOTREACHED() << "Invalid event type"; |
+ return; |
+ } |
+ if (pending_events_.empty()) { |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&EventGenerator::DispatchNextPendingEvent, |
+ base::Unretained(this))); |
+ } |
+ pending_events_.push_back(pending_event); |
+ } else { |
+ RootWindowHostDelegate* root_window_host_delegate = |
+ current_root_window_->AsRootWindowHostDelegate(); |
+ if (event->IsKeyEvent()) { |
+ root_window_host_delegate->OnHostKeyEvent( |
+ static_cast<ui::KeyEvent*>(event)); |
+ } else if (event->IsMouseEvent()) { |
+ root_window_host_delegate->OnHostMouseEvent( |
+ static_cast<ui::MouseEvent*>(event)); |
+ } else if (event->IsTouchEvent()) { |
+ root_window_host_delegate->OnHostTouchEvent( |
+ static_cast<ui::TouchEvent*>(event)); |
+ } else if (event->IsScrollEvent()) { |
+ root_window_host_delegate->OnHostScrollEvent( |
+ static_cast<ui::ScrollEvent*>(event)); |
+ } else { |
+ NOTREACHED() << "Invalid event type"; |
+ } |
+ } |
+} |
+ |
+void EventGenerator::DispatchNextPendingEvent() { |
+ DCHECK(!pending_events_.empty()); |
+ ui::Event* event = pending_events_.front(); |
+ DoDispatchEvent(event, false); |
+ pending_events_.pop_front(); |
+ delete event; |
+ if (!pending_events_.empty()) { |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&EventGenerator::DispatchNextPendingEvent, |
+ base::Unretained(this))); |
+ } |
+} |
+ |
+ |
} // namespace test |
} // namespace aura |