| Index: ui/events/test/event_generator.h
|
| diff --git a/ui/events/test/event_generator.h b/ui/events/test/event_generator.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c2b95ffd57d6f33a19ac154c13a451f19e3dabaf
|
| --- /dev/null
|
| +++ b/ui/events/test/event_generator.h
|
| @@ -0,0 +1,402 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef UI_EVENTS_TEST_EVENT_GENERATOR_H_
|
| +#define UI_EVENTS_TEST_EVENT_GENERATOR_H_
|
| +
|
| +#include <list>
|
| +#include <vector>
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/callback.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/time/time.h"
|
| +#include "ui/events/event_constants.h"
|
| +#include "ui/events/keycodes/keyboard_codes.h"
|
| +#include "ui/gfx/geometry/point.h"
|
| +#include "ui/gfx/native_widget_types.h"
|
| +
|
| +namespace base {
|
| +class TickClock;
|
| +}
|
| +
|
| +namespace ui {
|
| +class Event;
|
| +class EventProcessor;
|
| +class EventSource;
|
| +class EventTarget;
|
| +class KeyEvent;
|
| +class MouseEvent;
|
| +class ScrollEvent;
|
| +class TouchEvent;
|
| +
|
| +namespace test {
|
| +
|
| +typedef base::Callback<void(EventType, const gfx::Vector2dF&)>
|
| + ScrollStepCallback;
|
| +
|
| +class EventGenerator;
|
| +
|
| +// A delegate interface for EventGenerator to abstract platform-specific event
|
| +// targeting and coordinate conversion.
|
| +class EventGeneratorDelegate {
|
| + public:
|
| + virtual ~EventGeneratorDelegate() {}
|
| +
|
| + // Set the context of the delegate, whilst it is being used by an active
|
| + // EventGenerator.
|
| + virtual void SetContext(EventGenerator* owner,
|
| + gfx::NativeWindow root_window,
|
| + gfx::NativeWindow window) {}
|
| +
|
| + // The ui::EventTarget at the given |location|.
|
| + virtual EventTarget* GetTargetAt(const gfx::Point& location) = 0;
|
| +
|
| + // The ui::EventSource for the given |target|.
|
| + virtual EventSource* GetEventSource(EventTarget* target) = 0;
|
| +
|
| + // Helper functions to determine the center point of |target| or |window|.
|
| + virtual gfx::Point CenterOfTarget(const EventTarget* target) const = 0;
|
| + virtual gfx::Point CenterOfWindow(gfx::NativeWindow window) const = 0;
|
| +
|
| + // Convert a point between API's coordinates and |target|'s coordinates.
|
| + virtual void ConvertPointFromTarget(const EventTarget* target,
|
| + gfx::Point* point) const = 0;
|
| + virtual void ConvertPointToTarget(const EventTarget* target,
|
| + gfx::Point* point) const = 0;
|
| +
|
| + // Convert a point from the coordinate system in the host that contains
|
| + // |hosted_target| into the root window's coordinate system.
|
| + virtual void ConvertPointFromHost(const EventTarget* hosted_target,
|
| + gfx::Point* point) const = 0;
|
| +};
|
| +
|
| +// ui::test::EventGenerator is a tool that generates and dispatches events.
|
| +// Unlike |ui_controls| package in ui/base/test, this does not use platform
|
| +// native message loops. Instead, it sends events to the event dispatcher
|
| +// synchronously.
|
| +//
|
| +// This class is not suited for the following cases:
|
| +//
|
| +// 1) If your test depends on native events (ui::Event::native_event()).
|
| +// This return is empty/NULL event with EventGenerator.
|
| +// 2) If your test involves nested message loop, such as
|
| +// menu or drag & drop. Because this class directly
|
| +// post an event to WindowEventDispatcher, this event will not be
|
| +// handled in the nested message loop.
|
| +// 3) Similarly, |base::MessagePumpObserver| will not be invoked.
|
| +// 4) Any other code that requires native message loops, such as
|
| +// tests for WindowTreeHostWin/WindowTreeHostX11.
|
| +//
|
| +// If one of these applies to your test, please use |ui_controls|
|
| +// package instead.
|
| +//
|
| +// Note: The coordinates of the points in API is determined by the
|
| +// EventGeneratorDelegate.
|
| +class EventGenerator {
|
| + public:
|
| + // Creates an EventGenerator with the mouse/touch location (0,0),
|
| + // which uses the |root_window|'s coordinates and the default delegate for
|
| + // this platform.
|
| + explicit EventGenerator(gfx::NativeWindow root_window);
|
| +
|
| + // Create an EventGenerator with EventGeneratorDelegate,
|
| + // which uses the coordinates conversions and targeting provided by
|
| + // |delegate|.
|
| + explicit EventGenerator(EventGeneratorDelegate* delegate);
|
| +
|
| + // Creates an EventGenerator with the mouse/touch location
|
| + // at |initial_location|, which uses the |root_window|'s coordinates.
|
| + EventGenerator(gfx::NativeWindow root_window,
|
| + const gfx::Point& initial_location);
|
| +
|
| + // Creates an EventGenerator with the mouse/touch location centered over
|
| + // |window|. This is currently the only constructor that works on Mac, since
|
| + // a specific window is required (and there is no root window).
|
| + EventGenerator(gfx::NativeWindow root_window, gfx::NativeWindow window);
|
| +
|
| + virtual ~EventGenerator();
|
| +
|
| + // Explicitly sets the location used by mouse/touch events. This is set by the
|
| + // various methods that take a location but can be manipulated directly,
|
| + // typically for touch.
|
| + void set_current_location(const gfx::Point& location) {
|
| + current_location_ = location;
|
| + }
|
| + const gfx::Point& current_location() const { return current_location_; }
|
| +
|
| + void set_async(bool async) { async_ = async; }
|
| + bool async() const { return async_; }
|
| +
|
| + // Dispatch events through the application instead of directly to the
|
| + // target window. Currently only supported on Mac.
|
| + void set_targeting_application(bool targeting_application) {
|
| + targeting_application_ = targeting_application;
|
| + }
|
| + bool targeting_application() const { return targeting_application_; }
|
| +
|
| + // Resets the event flags bitmask.
|
| + void set_flags(int flags) { flags_ = flags; }
|
| + int flags() const { return flags_; }
|
| +
|
| + // Generates a left button press event.
|
| + void PressLeftButton();
|
| +
|
| + // Generates a left button release event.
|
| + void ReleaseLeftButton();
|
| +
|
| + // Generates events to click (press, release) left button.
|
| + void ClickLeftButton();
|
| +
|
| + // Generates a double click event using the left button.
|
| + void DoubleClickLeftButton();
|
| +
|
| + // Generates a right button press event.
|
| + void PressRightButton();
|
| +
|
| + // Generates a right button release event.
|
| + void ReleaseRightButton();
|
| +
|
| + // Moves the mouse wheel by |delta_x|, |delta_y|.
|
| + void MoveMouseWheel(int delta_x, int delta_y);
|
| +
|
| + // Generates a mouse exit.
|
| + void SendMouseExit();
|
| +
|
| + // Generates events to move mouse to be the given |point| in the
|
| + // |current_root_window_|'s host window coordinates.
|
| + void MoveMouseToInHost(const gfx::Point& point_in_host);
|
| + void MoveMouseToInHost(int x, int y) {
|
| + MoveMouseToInHost(gfx::Point(x, y));
|
| + }
|
| +
|
| + // Generates events to move mouse to be the given |point| in screen
|
| + // coordinates.
|
| + void MoveMouseTo(const gfx::Point& point_in_screen, int count);
|
| + void MoveMouseTo(const gfx::Point& point_in_screen) {
|
| + MoveMouseTo(point_in_screen, 1);
|
| + }
|
| + void MoveMouseTo(int x, int y) {
|
| + MoveMouseTo(gfx::Point(x, y));
|
| + }
|
| +
|
| + // Generates events to move mouse to be the given |point| in |window|'s
|
| + // coordinates.
|
| + void MoveMouseRelativeTo(const EventTarget* window, const gfx::Point& point);
|
| + void MoveMouseRelativeTo(const EventTarget* window, int x, int y) {
|
| + MoveMouseRelativeTo(window, gfx::Point(x, y));
|
| + }
|
| +
|
| + void MoveMouseBy(int x, int y) {
|
| + MoveMouseTo(current_location_ + gfx::Vector2d(x, y));
|
| + }
|
| +
|
| + // Generates events to drag mouse to given |point|.
|
| + void DragMouseTo(const gfx::Point& point);
|
| +
|
| + void DragMouseTo(int x, int y) {
|
| + DragMouseTo(gfx::Point(x, y));
|
| + }
|
| +
|
| + void DragMouseBy(int dx, int dy) {
|
| + DragMouseTo(current_location_ + gfx::Vector2d(dx, dy));
|
| + }
|
| +
|
| + // Generates events to move the mouse to the center of the window.
|
| + void MoveMouseToCenterOf(EventTarget* window);
|
| +
|
| + // Generates a touch press event.
|
| + void PressTouch();
|
| +
|
| + // Generates a touch press event with |touch_id|.
|
| + void PressTouchId(int touch_id);
|
| +
|
| + // Generates a ET_TOUCH_MOVED event to |point|.
|
| + void MoveTouch(const gfx::Point& point);
|
| +
|
| + // Generates a ET_TOUCH_MOVED event to |point| with |touch_id|.
|
| + void MoveTouchId(const gfx::Point& point, int touch_id);
|
| +
|
| + // Generates a touch release event.
|
| + void ReleaseTouch();
|
| +
|
| + // Generates a touch release event with |touch_id|.
|
| + void ReleaseTouchId(int touch_id);
|
| +
|
| + // Generates press, move and release event to move touch
|
| + // to be the given |point|.
|
| + void PressMoveAndReleaseTouchTo(const gfx::Point& point);
|
| +
|
| + void PressMoveAndReleaseTouchTo(int x, int y) {
|
| + PressMoveAndReleaseTouchTo(gfx::Point(x, y));
|
| + }
|
| +
|
| + void PressMoveAndReleaseTouchBy(int x, int y) {
|
| + PressMoveAndReleaseTouchTo(current_location_ + gfx::Vector2d(x, y));
|
| + }
|
| +
|
| + // Generates press, move and release events to move touch
|
| + // to the center of the window.
|
| + void PressMoveAndReleaseTouchToCenterOf(EventTarget* window);
|
| +
|
| + // Generates and dispatches a Win8 edge-swipe event (swipe up from bottom or
|
| + // swipe down from top). Note that it is not possible to distinguish between
|
| + // the two edges with this event.
|
| + void GestureEdgeSwipe();
|
| +
|
| + // Generates and dispatches touch-events required to generate a TAP gesture.
|
| + // Note that this can generate a number of other gesture events at the same
|
| + // time (e.g. GESTURE_BEGIN, TAP_DOWN, END).
|
| + void GestureTapAt(const gfx::Point& point);
|
| +
|
| + // Generates press and release touch-events to generate a TAP_DOWN event, but
|
| + // without generating any scroll or tap events. This can also generate a few
|
| + // other gesture events (e.g. GESTURE_BEGIN, END).
|
| + void GestureTapDownAndUp(const gfx::Point& point);
|
| +
|
| + // Calculates a time duration that can be used with the given |start|, |end|,
|
| + // and |steps| values when calling GestureScrollSequence (or
|
| + // GestureScrollSequenceWithCallback) to achieve the given |velocity|.
|
| + base::TimeDelta CalculateScrollDurationForFlingVelocity(
|
| + const gfx::Point& start,
|
| + const gfx::Point& end,
|
| + float velocity,
|
| + int steps);
|
| +
|
| + // Generates press, move, release touch-events to generate a sequence of
|
| + // scroll events. |duration| and |steps| affect the velocity of the scroll,
|
| + // and depending on these values, this may also generate FLING scroll
|
| + // gestures. If velocity/fling is irrelevant for the test, then any non-zero
|
| + // values for these should be sufficient.
|
| + void GestureScrollSequence(const gfx::Point& start,
|
| + const gfx::Point& end,
|
| + const base::TimeDelta& duration,
|
| + int steps);
|
| +
|
| + // The same as GestureScrollSequence(), with the exception that |callback| is
|
| + // called at each step of the scroll sequence. |callback| is called at the
|
| + // start of the sequence with ET_GESTURE_SCROLL_BEGIN, followed by one or more
|
| + // ET_GESTURE_SCROLL_UPDATE and ends with an ET_GESTURE_SCROLL_END.
|
| + void GestureScrollSequenceWithCallback(const gfx::Point& start,
|
| + const gfx::Point& end,
|
| + const base::TimeDelta& duration,
|
| + int steps,
|
| + const ScrollStepCallback& callback);
|
| +
|
| + // Generates press, move, release touch-events to generate a sequence of
|
| + // multi-finger scroll events. |count| specifies the number of touch-points
|
| + // that should generate the scroll events. |start| are the starting positions
|
| + // of all the touch points. |steps| and |event_separation_time_ms| are
|
| + // relevant when testing velocity/fling/swipe, otherwise these can be any
|
| + // non-zero value. |delta_x| and |delta_y| are the amount that each finger
|
| + // should be moved. Internally calls GestureMultiFingerScrollWithDelays
|
| + // with zeros as |delay_adding_finger_ms| forcing all touch down events to be
|
| + // immediate.
|
| + void GestureMultiFingerScroll(int count,
|
| + const gfx::Point start[],
|
| + int event_separation_time_ms,
|
| + int steps,
|
| + int move_x,
|
| + int move_y);
|
| +
|
| + // Generates press, move, release touch-events to generate a sequence of
|
| + // multi-finger scroll events. |count| specifies the number of touch-points
|
| + // that should generate the scroll events. |start| are the starting positions
|
| + // of all the touch points. |delay_adding_finger_ms| are delays in ms from the
|
| + // starting time till touching down of each finger. |delay_adding_finger_ms|
|
| + // is useful when testing complex gestures that start with 1 or 2 fingers and
|
| + // add fingers with a delay. |steps| and |event_separation_time_ms| are
|
| + // relevant when testing velocity/fling/swipe, otherwise these can be any
|
| + // non-zero value. |delta_x| and |delta_y| are the amount that each finger
|
| + // should be moved.
|
| + void GestureMultiFingerScrollWithDelays(int count,
|
| + const gfx::Point start[],
|
| + const int delay_adding_finger_ms[],
|
| + int event_separation_time_ms,
|
| + int steps,
|
| + int move_x,
|
| + int move_y);
|
| +
|
| + // Generates scroll sequences of a FlingCancel, Scrolls, FlingStart, with
|
| + // constant deltas to |x_offset| and |y_offset| in |steps|.
|
| + void ScrollSequence(const gfx::Point& start,
|
| + const base::TimeDelta& step_delay,
|
| + float x_offset,
|
| + float y_offset,
|
| + int steps,
|
| + int num_fingers);
|
| +
|
| + // Generates scroll sequences of a FlingCancel, Scrolls, FlingStart, sending
|
| + // scrolls of each of the values in |offsets|.
|
| + void ScrollSequence(const gfx::Point& start,
|
| + const base::TimeDelta& step_delay,
|
| + const std::vector<gfx::PointF>& offsets,
|
| + int num_fingers);
|
| +
|
| + // Generates a key press event. On platforms except Windows and X11, a key
|
| + // event without native_event() is generated. Note that ui::EF_ flags should
|
| + // be passed as |flags|, not the native ones like 'ShiftMask' in <X11/X.h>.
|
| + // TODO(yusukes): Support native_event() on all platforms.
|
| + void PressKey(KeyboardCode key_code, int flags);
|
| +
|
| + // Generates a key release event. On platforms except Windows and X11, a key
|
| + // event without native_event() is generated. Note that ui::EF_ flags should
|
| + // be passed as |flags|, not the native ones like 'ShiftMask' in <X11/X.h>.
|
| + // TODO(yusukes): Support native_event() on all platforms.
|
| + void ReleaseKey(KeyboardCode key_code, int flags);
|
| +
|
| + // Dispatch the event to the WindowEventDispatcher.
|
| + void Dispatch(Event* event);
|
| +
|
| + void set_current_target(EventTarget* target) {
|
| + current_target_ = target;
|
| + }
|
| +
|
| + // Specify an alternative tick clock to be used for simulating time in tests.
|
| + void SetTickClock(scoped_ptr<base::TickClock> tick_clock);
|
| +
|
| + // Get the current time from the tick clock.
|
| + base::TimeDelta Now();
|
| +
|
| + // Default delegate set by a platform-specific GeneratorDelegate singleton.
|
| + static EventGeneratorDelegate* default_delegate;
|
| +
|
| + private:
|
| + // Set up the test context using the delegate.
|
| + void Init(gfx::NativeWindow root_window, gfx::NativeWindow window_context);
|
| +
|
| + // Dispatch a key event to the WindowEventDispatcher.
|
| + void DispatchKeyEvent(bool is_press, KeyboardCode key_code, int flags);
|
| +
|
| + void UpdateCurrentDispatcher(const gfx::Point& point);
|
| + void PressButton(int flag);
|
| + void ReleaseButton(int flag);
|
| +
|
| + gfx::Point GetLocationInCurrentRoot() const;
|
| + gfx::Point CenterOfWindow(const EventTarget* window) const;
|
| +
|
| + void DispatchNextPendingEvent();
|
| + void DoDispatchEvent(Event* event, bool async);
|
| +
|
| + const EventGeneratorDelegate* delegate() const;
|
| + EventGeneratorDelegate* delegate();
|
| +
|
| + scoped_ptr<EventGeneratorDelegate> delegate_;
|
| + gfx::Point current_location_;
|
| + EventTarget* current_target_;
|
| + int flags_;
|
| + bool grab_;
|
| + std::list<Event*> pending_events_;
|
| + // Set to true to cause events to be posted asynchronously.
|
| + bool async_;
|
| + bool targeting_application_;
|
| + scoped_ptr<base::TickClock> tick_clock_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(EventGenerator);
|
| +};
|
| +
|
| +} // namespace test
|
| +} // namespace ui
|
| +
|
| +#endif // UI_EVENTS_TEST_EVENT_GENERATOR_H_
|
|
|