// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_GESTURES_BACK_GESTURE_BACK_GESTURE_EVENT_HANDLER_H_
#define ASH_WM_GESTURES_BACK_GESTURE_BACK_GESTURE_EVENT_HANDLER_H_
#include "ash/wm/gestures/back_gesture/back_gesture_metrics.h"
#include "base/containers/flat_set.h"
#include "ui/display/display_observer.h"
#include "ui/events/event_handler.h"
#include "ui/events/gestures/gesture_provider_aura.h"
namespace ash {
class BackGestureAffordance;
class BackGestureContextualNudgeControllerImpl;
class BackGestureEventHandler : public display::DisplayObserver,
public ui::EventHandler,
public ui::GestureConsumer,
public ui::GestureProviderAuraClient {
public:
// The threshold of the fling velocity while fling from left edge to go
// previous page.
static constexpr int kFlingVelocityForGoingBack = 1000;
// How many dips are reserved for gesture events to start swiping to previous
// page from the left edge of the screen in tablet mode.
static constexpr int kStartGoingBackLeftEdgeInset = 16;
BackGestureEventHandler();
BackGestureEventHandler(const BackGestureEventHandler&) = delete;
BackGestureEventHandler& operator=(const BackGestureEventHandler&) = delete;
~BackGestureEventHandler() override;
// display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override;
// ui::EventHandler:
void OnGestureEvent(ui::GestureEvent* event) override;
void OnTouchEvent(ui::TouchEvent* event) override;
// ui::GestureConsumer:
const std::string& GetName() const override;
// ui::GestureProviderAuraClient:
void OnGestureEvent(GestureConsumer* consumer,
ui::GestureEvent* event) override;
BackGestureContextualNudgeControllerImpl* nudge_controller_for_testing() {
return nudge_controller_.get();
}
private:
// Returns true if |event| was handled as a go-back gesture. |event| is
// generated by |gesture_provider_| from touch event, |screen_location| is
// location of the event in screen coordinates.
bool MaybeHandleBackGesture(ui::GestureEvent* event,
const gfx::Point& screen_location);
// True if we can start swiping from left edge of the display or splitview
// divider to go back.
bool CanStartGoingBack(const gfx::Point& screen_location);
void SendBackEvent(const gfx::Point& screen_location);
// Returns true if we should wait for touch press ack to decide whether to
// show back gesture. If true, BackGestureEventHandler should not handle touch
// press event in OnTouchEvent() but should wait after touch ack has been
// received.
bool ShouldWaitForTouchPressAck(const gfx::Point& screen_location);
// True if swiping from left edge to go to previous page is in progress.
bool going_back_started_ = false;
// Tracks the x-axis and y-axis drag amount through touch events. Used for
// back gesture affordance in tablet mode. The gesture movement of back
// gesture can't be recognized by GestureRecognizer, which leads to wrong
// gesture locations of back gesture. See crbug.com/1015464 for the details.
int x_drag_amount_ = 0;
int y_drag_amount_ = 0;
// True if back gesture dragging on the negative direction of x-axis.
bool during_reverse_dragging_ = false;
// Position of last touch event. Used to calculate |y_drag_amount_|. Note,
// only touch events from |first_touch_id_| will be recorded.
gfx::Point last_touch_point_;
ui::PointerId first_touch_id_ = ui::kPointerIdUnknown;
// Maintains the ids list of the touch events that are not generated from
// |first_touch_id_| when back gesture is performed. We need this so that we
// can ignore gesture events that are not generated from the first finger.
base::flat_set<uint32_t> other_touch_event_ids_list_;
// Used to show the affordance while swiping from left edge to go to the
// previous page.
std::unique_ptr<BackGestureAffordance> back_gesture_affordance_;
// Used to decide when to show/hide the back gesture contextual nudge.
std::unique_ptr<BackGestureContextualNudgeControllerImpl> nudge_controller_;
// True if back gesture dragged from splitview divider.
bool dragged_from_splitview_divider_ = false;
// Start location of the back gesture in screen coordinate. Used by
// ActivateUnderneathWindowInSplitViewMode() to determine the snapped window
// that should be activated for going back.
gfx::Point back_start_location_;
// A GestureProvider that is created for back gesture. Used to handle tap down
// and the possibly following gesture scroll sequence for back gesture in
// OnTouchEvent session. This is done to avoid tap down event be used by the
// window that is underneath to do other things (e.g, highlight a menu item)
// instead of going back.
ui::GestureProviderAura gesture_provider_{this, this};
// Register for DisplayObserver callbacks.
display::ScopedDisplayObserver display_observer_{this};
// False if BackGestureEventHandler should not handle touch events directly in
// OnTouchEvent(), but should wait after touch ack is received. This is needed
// as the window's touch action (if exist) will only be set after it sees the
// touch start event and we'll need the touch action information to decide
// whether back gesture should be shown.
bool should_wait_for_touch_ack_ = false;
// Start scenario type of the back gesture, used for related metrics.
BackGestureStartScenarioType back_gesture_start_scenario_type_ =
BackGestureStartScenarioType::kMaxValue;
};
} // namespace ash
#endif // ASH_WM_GESTURES_BACK_GESTURE_BACK_GESTURE_EVENT_HANDLER_H_