| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef UI_EVENTS_TEST_EVENT_GENERATOR_H_ | |
| 6 #define UI_EVENTS_TEST_EVENT_GENERATOR_H_ | |
| 7 | |
| 8 #include <list> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/callback.h" | |
| 13 #include "base/memory/scoped_ptr.h" | |
| 14 #include "base/time/time.h" | |
| 15 #include "ui/events/event_constants.h" | |
| 16 #include "ui/events/keycodes/keyboard_codes.h" | |
| 17 #include "ui/gfx/native_widget_types.h" | |
| 18 #include "ui/gfx/point.h" | |
| 19 | |
| 20 namespace base { | |
| 21 class TickClock; | |
| 22 } | |
| 23 | |
| 24 namespace ui { | |
| 25 class Event; | |
| 26 class EventProcessor; | |
| 27 class EventSource; | |
| 28 class EventTarget; | |
| 29 class KeyEvent; | |
| 30 class MouseEvent; | |
| 31 class ScrollEvent; | |
| 32 class TouchEvent; | |
| 33 | |
| 34 namespace test { | |
| 35 | |
| 36 typedef base::Callback<void(EventType, const gfx::Vector2dF&)> | |
| 37 ScrollStepCallback; | |
| 38 | |
| 39 class EventGenerator; | |
| 40 | |
| 41 // A delegate interface for EventGenerator to abstract platform-specific event | |
| 42 // targeting and coordinate conversion. | |
| 43 class EventGeneratorDelegate { | |
| 44 public: | |
| 45 virtual ~EventGeneratorDelegate() {} | |
| 46 | |
| 47 // Set the context of the delegate, whilst it is being used by an active | |
| 48 // EventGenerator. | |
| 49 virtual void SetContext(EventGenerator* owner, | |
| 50 gfx::NativeWindow root_window, | |
| 51 gfx::NativeWindow window) {} | |
| 52 | |
| 53 // The ui::EventTarget at the given |location|. | |
| 54 virtual EventTarget* GetTargetAt(const gfx::Point& location) = 0; | |
| 55 | |
| 56 // The ui::EventSource for the given |target|. | |
| 57 virtual EventSource* GetEventSource(EventTarget* target) = 0; | |
| 58 | |
| 59 // Helper functions to determine the center point of |target| or |window|. | |
| 60 virtual gfx::Point CenterOfTarget(const EventTarget* target) const = 0; | |
| 61 virtual gfx::Point CenterOfWindow(gfx::NativeWindow window) const = 0; | |
| 62 | |
| 63 // Convert a point between API's coordinates and |target|'s coordinates. | |
| 64 virtual void ConvertPointFromTarget(const EventTarget* target, | |
| 65 gfx::Point* point) const = 0; | |
| 66 virtual void ConvertPointToTarget(const EventTarget* target, | |
| 67 gfx::Point* point) const = 0; | |
| 68 | |
| 69 // Convert a point from the coordinate system in the host that contains | |
| 70 // |hosted_target| into the root window's coordinate system. | |
| 71 virtual void ConvertPointFromHost(const EventTarget* hosted_target, | |
| 72 gfx::Point* point) const = 0; | |
| 73 }; | |
| 74 | |
| 75 // ui::test::EventGenerator is a tool that generates and dispatches events. | |
| 76 // Unlike |ui_controls| package in ui/base/test, this does not use platform | |
| 77 // native message loops. Instead, it sends events to the event dispatcher | |
| 78 // synchronously. | |
| 79 // | |
| 80 // This class is not suited for the following cases: | |
| 81 // | |
| 82 // 1) If your test depends on native events (ui::Event::native_event()). | |
| 83 // This return is empty/NULL event with EventGenerator. | |
| 84 // 2) If your test involves nested message loop, such as | |
| 85 // menu or drag & drop. Because this class directly | |
| 86 // post an event to WindowEventDispatcher, this event will not be | |
| 87 // handled in the nested message loop. | |
| 88 // 3) Similarly, |base::MessagePumpObserver| will not be invoked. | |
| 89 // 4) Any other code that requires native message loops, such as | |
| 90 // tests for WindowTreeHostWin/WindowTreeHostX11. | |
| 91 // | |
| 92 // If one of these applies to your test, please use |ui_controls| | |
| 93 // package instead. | |
| 94 // | |
| 95 // Note: The coordinates of the points in API is determined by the | |
| 96 // EventGeneratorDelegate. | |
| 97 class EventGenerator { | |
| 98 public: | |
| 99 // Creates an EventGenerator with the mouse/touch location (0,0), | |
| 100 // which uses the |root_window|'s coordinates and the default delegate for | |
| 101 // this platform. | |
| 102 explicit EventGenerator(gfx::NativeWindow root_window); | |
| 103 | |
| 104 // Create an EventGenerator with EventGeneratorDelegate, | |
| 105 // which uses the coordinates conversions and targeting provided by | |
| 106 // |delegate|. | |
| 107 explicit EventGenerator(EventGeneratorDelegate* delegate); | |
| 108 | |
| 109 // Creates an EventGenerator with the mouse/touch location | |
| 110 // at |initial_location|, which uses the |root_window|'s coordinates. | |
| 111 EventGenerator(gfx::NativeWindow root_window, | |
| 112 const gfx::Point& initial_location); | |
| 113 | |
| 114 // Creates an EventGenerator with the mouse/touch location centered over | |
| 115 // |window|. This is currently the only constructor that works on Mac, since | |
| 116 // a specific window is required (and there is no root window). | |
| 117 EventGenerator(gfx::NativeWindow root_window, gfx::NativeWindow window); | |
| 118 | |
| 119 virtual ~EventGenerator(); | |
| 120 | |
| 121 // Explicitly sets the location used by mouse/touch events. This is set by the | |
| 122 // various methods that take a location but can be manipulated directly, | |
| 123 // typically for touch. | |
| 124 void set_current_location(const gfx::Point& location) { | |
| 125 current_location_ = location; | |
| 126 } | |
| 127 const gfx::Point& current_location() const { return current_location_; } | |
| 128 | |
| 129 void set_async(bool async) { async_ = async; } | |
| 130 bool async() const { return async_; } | |
| 131 | |
| 132 // Resets the event flags bitmask. | |
| 133 void set_flags(int flags) { flags_ = flags; } | |
| 134 int flags() const { return flags_; } | |
| 135 | |
| 136 // Generates a left button press event. | |
| 137 void PressLeftButton(); | |
| 138 | |
| 139 // Generates a left button release event. | |
| 140 void ReleaseLeftButton(); | |
| 141 | |
| 142 // Generates events to click (press, release) left button. | |
| 143 void ClickLeftButton(); | |
| 144 | |
| 145 // Generates a double click event using the left button. | |
| 146 void DoubleClickLeftButton(); | |
| 147 | |
| 148 // Generates a right button press event. | |
| 149 void PressRightButton(); | |
| 150 | |
| 151 // Generates a right button release event. | |
| 152 void ReleaseRightButton(); | |
| 153 | |
| 154 // Moves the mouse wheel by |delta_x|, |delta_y|. | |
| 155 void MoveMouseWheel(int delta_x, int delta_y); | |
| 156 | |
| 157 // Generates a mouse exit. | |
| 158 void SendMouseExit(); | |
| 159 | |
| 160 // Generates events to move mouse to be the given |point| in the | |
| 161 // |current_root_window_|'s host window coordinates. | |
| 162 void MoveMouseToInHost(const gfx::Point& point_in_host); | |
| 163 void MoveMouseToInHost(int x, int y) { | |
| 164 MoveMouseToInHost(gfx::Point(x, y)); | |
| 165 } | |
| 166 | |
| 167 // Generates events to move mouse to be the given |point| in screen | |
| 168 // coordinates. | |
| 169 void MoveMouseTo(const gfx::Point& point_in_screen, int count); | |
| 170 void MoveMouseTo(const gfx::Point& point_in_screen) { | |
| 171 MoveMouseTo(point_in_screen, 1); | |
| 172 } | |
| 173 void MoveMouseTo(int x, int y) { | |
| 174 MoveMouseTo(gfx::Point(x, y)); | |
| 175 } | |
| 176 | |
| 177 // Generates events to move mouse to be the given |point| in |window|'s | |
| 178 // coordinates. | |
| 179 void MoveMouseRelativeTo(const EventTarget* window, const gfx::Point& point); | |
| 180 void MoveMouseRelativeTo(const EventTarget* window, int x, int y) { | |
| 181 MoveMouseRelativeTo(window, gfx::Point(x, y)); | |
| 182 } | |
| 183 | |
| 184 void MoveMouseBy(int x, int y) { | |
| 185 MoveMouseTo(current_location_ + gfx::Vector2d(x, y)); | |
| 186 } | |
| 187 | |
| 188 // Generates events to drag mouse to given |point|. | |
| 189 void DragMouseTo(const gfx::Point& point); | |
| 190 | |
| 191 void DragMouseTo(int x, int y) { | |
| 192 DragMouseTo(gfx::Point(x, y)); | |
| 193 } | |
| 194 | |
| 195 void DragMouseBy(int dx, int dy) { | |
| 196 DragMouseTo(current_location_ + gfx::Vector2d(dx, dy)); | |
| 197 } | |
| 198 | |
| 199 // Generates events to move the mouse to the center of the window. | |
| 200 void MoveMouseToCenterOf(EventTarget* window); | |
| 201 | |
| 202 // Generates a touch press event. | |
| 203 void PressTouch(); | |
| 204 | |
| 205 // Generates a touch press event with |touch_id|. | |
| 206 void PressTouchId(int touch_id); | |
| 207 | |
| 208 // Generates a ET_TOUCH_MOVED event to |point|. | |
| 209 void MoveTouch(const gfx::Point& point); | |
| 210 | |
| 211 // Generates a ET_TOUCH_MOVED event to |point| with |touch_id|. | |
| 212 void MoveTouchId(const gfx::Point& point, int touch_id); | |
| 213 | |
| 214 // Generates a touch release event. | |
| 215 void ReleaseTouch(); | |
| 216 | |
| 217 // Generates a touch release event with |touch_id|. | |
| 218 void ReleaseTouchId(int touch_id); | |
| 219 | |
| 220 // Generates press, move and release event to move touch | |
| 221 // to be the given |point|. | |
| 222 void PressMoveAndReleaseTouchTo(const gfx::Point& point); | |
| 223 | |
| 224 void PressMoveAndReleaseTouchTo(int x, int y) { | |
| 225 PressMoveAndReleaseTouchTo(gfx::Point(x, y)); | |
| 226 } | |
| 227 | |
| 228 void PressMoveAndReleaseTouchBy(int x, int y) { | |
| 229 PressMoveAndReleaseTouchTo(current_location_ + gfx::Vector2d(x, y)); | |
| 230 } | |
| 231 | |
| 232 // Generates press, move and release events to move touch | |
| 233 // to the center of the window. | |
| 234 void PressMoveAndReleaseTouchToCenterOf(EventTarget* window); | |
| 235 | |
| 236 // Generates and dispatches a Win8 edge-swipe event (swipe up from bottom or | |
| 237 // swipe down from top). Note that it is not possible to distinguish between | |
| 238 // the two edges with this event. | |
| 239 void GestureEdgeSwipe(); | |
| 240 | |
| 241 // Generates and dispatches touch-events required to generate a TAP gesture. | |
| 242 // Note that this can generate a number of other gesture events at the same | |
| 243 // time (e.g. GESTURE_BEGIN, TAP_DOWN, END). | |
| 244 void GestureTapAt(const gfx::Point& point); | |
| 245 | |
| 246 // Generates press and release touch-events to generate a TAP_DOWN event, but | |
| 247 // without generating any scroll or tap events. This can also generate a few | |
| 248 // other gesture events (e.g. GESTURE_BEGIN, END). | |
| 249 void GestureTapDownAndUp(const gfx::Point& point); | |
| 250 | |
| 251 // Generates press, move, release touch-events to generate a sequence of | |
| 252 // scroll events. |duration| and |steps| affect the velocity of the scroll, | |
| 253 // and depending on these values, this may also generate FLING scroll | |
| 254 // gestures. If velocity/fling is irrelevant for the test, then any non-zero | |
| 255 // values for these should be sufficient. | |
| 256 void GestureScrollSequence(const gfx::Point& start, | |
| 257 const gfx::Point& end, | |
| 258 const base::TimeDelta& duration, | |
| 259 int steps); | |
| 260 | |
| 261 // The same as GestureScrollSequence(), with the exception that |callback| is | |
| 262 // called at each step of the scroll sequence. |callback| is called at the | |
| 263 // start of the sequence with ET_GESTURE_SCROLL_BEGIN, followed by one or more | |
| 264 // ET_GESTURE_SCROLL_UPDATE and ends with an ET_GESTURE_SCROLL_END. | |
| 265 void GestureScrollSequenceWithCallback(const gfx::Point& start, | |
| 266 const gfx::Point& end, | |
| 267 const base::TimeDelta& duration, | |
| 268 int steps, | |
| 269 const ScrollStepCallback& callback); | |
| 270 | |
| 271 // Generates press, move, release touch-events to generate a sequence of | |
| 272 // multi-finger scroll events. |count| specifies the number of touch-points | |
| 273 // that should generate the scroll events. |start| are the starting positions | |
| 274 // of all the touch points. |steps| and |event_separation_time_ms| are | |
| 275 // relevant when testing velocity/fling/swipe, otherwise these can be any | |
| 276 // non-zero value. |delta_x| and |delta_y| are the amount that each finger | |
| 277 // should be moved. Internally calls GestureMultiFingerScrollWithDelays | |
| 278 // with zeros as |delay_adding_finger_ms| forcing all touch down events to be | |
| 279 // immediate. | |
| 280 void GestureMultiFingerScroll(int count, | |
| 281 const gfx::Point start[], | |
| 282 int event_separation_time_ms, | |
| 283 int steps, | |
| 284 int move_x, | |
| 285 int move_y); | |
| 286 | |
| 287 // Generates press, move, release touch-events to generate a sequence of | |
| 288 // multi-finger scroll events. |count| specifies the number of touch-points | |
| 289 // that should generate the scroll events. |start| are the starting positions | |
| 290 // of all the touch points. |delay_adding_finger_ms| are delays in ms from the | |
| 291 // starting time till touching down of each finger. |delay_adding_finger_ms| | |
| 292 // is useful when testing complex gestures that start with 1 or 2 fingers and | |
| 293 // add fingers with a delay. |steps| and |event_separation_time_ms| are | |
| 294 // relevant when testing velocity/fling/swipe, otherwise these can be any | |
| 295 // non-zero value. |delta_x| and |delta_y| are the amount that each finger | |
| 296 // should be moved. | |
| 297 void GestureMultiFingerScrollWithDelays(int count, | |
| 298 const gfx::Point start[], | |
| 299 const int delay_adding_finger_ms[], | |
| 300 int event_separation_time_ms, | |
| 301 int steps, | |
| 302 int move_x, | |
| 303 int move_y); | |
| 304 | |
| 305 // Generates scroll sequences of a FlingCancel, Scrolls, FlingStart, with | |
| 306 // constant deltas to |x_offset| and |y_offset| in |steps|. | |
| 307 void ScrollSequence(const gfx::Point& start, | |
| 308 const base::TimeDelta& step_delay, | |
| 309 float x_offset, | |
| 310 float y_offset, | |
| 311 int steps, | |
| 312 int num_fingers); | |
| 313 | |
| 314 // Generates scroll sequences of a FlingCancel, Scrolls, FlingStart, sending | |
| 315 // scrolls of each of the values in |offsets|. | |
| 316 void ScrollSequence(const gfx::Point& start, | |
| 317 const base::TimeDelta& step_delay, | |
| 318 const std::vector<gfx::PointF>& offsets, | |
| 319 int num_fingers); | |
| 320 | |
| 321 // Generates a key press event. On platforms except Windows and X11, a key | |
| 322 // event without native_event() is generated. Note that ui::EF_ flags should | |
| 323 // be passed as |flags|, not the native ones like 'ShiftMask' in <X11/X.h>. | |
| 324 // TODO(yusukes): Support native_event() on all platforms. | |
| 325 void PressKey(KeyboardCode key_code, int flags); | |
| 326 | |
| 327 // Generates a key release event. On platforms except Windows and X11, a key | |
| 328 // event without native_event() is generated. Note that ui::EF_ flags should | |
| 329 // be passed as |flags|, not the native ones like 'ShiftMask' in <X11/X.h>. | |
| 330 // TODO(yusukes): Support native_event() on all platforms. | |
| 331 void ReleaseKey(KeyboardCode key_code, int flags); | |
| 332 | |
| 333 // Dispatch the event to the WindowEventDispatcher. | |
| 334 void Dispatch(Event* event); | |
| 335 | |
| 336 void set_current_target(EventTarget* target) { | |
| 337 current_target_ = target; | |
| 338 } | |
| 339 | |
| 340 // Specify an alternative tick clock to be used for simulating time in tests. | |
| 341 void SetTickClock(scoped_ptr<base::TickClock> tick_clock); | |
| 342 | |
| 343 // Get the current time from the tick clock. | |
| 344 base::TimeDelta Now(); | |
| 345 | |
| 346 // Default delegate set by a platform-specific GeneratorDelegate singleton. | |
| 347 static EventGeneratorDelegate* default_delegate; | |
| 348 | |
| 349 private: | |
| 350 // Set up the test context using the delegate. | |
| 351 void Init(gfx::NativeWindow root_window, gfx::NativeWindow window_context); | |
| 352 | |
| 353 // Dispatch a key event to the WindowEventDispatcher. | |
| 354 void DispatchKeyEvent(bool is_press, KeyboardCode key_code, int flags); | |
| 355 | |
| 356 void UpdateCurrentDispatcher(const gfx::Point& point); | |
| 357 void PressButton(int flag); | |
| 358 void ReleaseButton(int flag); | |
| 359 | |
| 360 gfx::Point GetLocationInCurrentRoot() const; | |
| 361 gfx::Point CenterOfWindow(const EventTarget* window) const; | |
| 362 | |
| 363 void DispatchNextPendingEvent(); | |
| 364 void DoDispatchEvent(Event* event, bool async); | |
| 365 | |
| 366 const EventGeneratorDelegate* delegate() const; | |
| 367 EventGeneratorDelegate* delegate(); | |
| 368 | |
| 369 scoped_ptr<EventGeneratorDelegate> delegate_; | |
| 370 gfx::Point current_location_; | |
| 371 EventTarget* current_target_; | |
| 372 int flags_; | |
| 373 bool grab_; | |
| 374 std::list<Event*> pending_events_; | |
| 375 // Set to true to cause events to be posted asynchronously. | |
| 376 bool async_; | |
| 377 scoped_ptr<base::TickClock> tick_clock_; | |
| 378 | |
| 379 DISALLOW_COPY_AND_ASSIGN(EventGenerator); | |
| 380 }; | |
| 381 | |
| 382 } // namespace test | |
| 383 } // namespace ui | |
| 384 | |
| 385 #endif // UI_EVENTS_TEST_EVENT_GENERATOR_H_ | |
| OLD | NEW |