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 |