Commit 64356c22 authored by Ryan Daum's avatar Ryan Daum Committed by Commit Bot

[chromecast] Detect screen enter/exit and corner holds.

  - Adds detection and dispatch of screen entry/exit events.
  - Adds detection of a finger press and hold in the corner.
  - Better handling of multiple-finger events on the screen.

Bug: internal b/112073644
Bug: internal b/112314035
Test: unit test and manual
Change-Id: Id2155f8e432428ee63f3457274f1507ce1edee53
Reviewed-on: https://chromium-review.googlesource.com/1165795Reviewed-by: default avatarAlex Sakhartchouk <alexst@chromium.org>
Reviewed-by: default avatarKevin Schoedel <kpschoedel@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582196}
parent f2da3d75
......@@ -15,6 +15,7 @@ cast_source_set("graphics") {
deps = [
"//base",
"//ui/events:events",
"//ui/gfx",
]
......
......@@ -10,4 +10,8 @@ bool CastGestureHandler::CanHandleSwipe(CastSideSwipeOrigin swipe_origin) {
return false;
}
CastGestureHandler::Corner CastGestureHandler::HandledCornerHolds() const {
return NO_CORNERS;
}
} // namespace chromecast
......@@ -5,6 +5,8 @@
#ifndef CHROMECAST_GRAPHICS_CAST_GESTURE_HANDLER_H_
#define CHROMECAST_GRAPHICS_CAST_GESTURE_HANDLER_H_
#include "ui/events/event.h"
// TODO(rdaum): Move into chromecast/graphics/gestures, which will require some
// cross-repo maneuvers.
#include "base/macros.h"
......@@ -47,6 +49,37 @@ class CastGestureHandler {
// followed by a release, within the tap timeout window
virtual void HandleTapGesture(const gfx::Point& touch_location) {}
// Triggered when the finger enters a side margin from inside the screen.
// That is, the finger is leaving the screen.
virtual void HandleScreenExit(CastSideSwipeOrigin side,
const gfx::Point& touch_location) {}
// Triggered when the finger enters a side margin from outside the screen.
// That is, the finger is entering the screen.
virtual void HandleScreenEnter(CastSideSwipeOrigin side,
const gfx::Point& touch_location) {}
enum Corner {
NO_CORNERS = 0,
TOP_LEFT_CORNER = 1 << 0,
BOTTOM_LEFT_CORNER = 1 << 1,
TOP_RIGHT_CORNER = 1 << 2,
BOTTOM_RIGHT_CORNER = 1 << 3,
};
// Return a bitmask of the corners that this handler is interested in, if any.
virtual Corner HandledCornerHolds() const;
// Triggered when the finger has been held inside the corner for longer
// than the corner hold threshold time.
virtual void HandleCornerHold(Corner corner_origin,
const ui::TouchEvent& touch_event) {}
// Triggered when a corner hold is ended because the finger has left the
// corner or has been released.
virtual void HandleCornerHoldEnd(Corner corner_origin,
const ui::TouchEvent& touch_event) {}
private:
DISALLOW_COPY_AND_ASSIGN(CastGestureHandler);
};
......
......@@ -76,4 +76,47 @@ void CastSystemGestureDispatcher::HandleTapGesture(
}
}
} // namespace chromecast
\ No newline at end of file
void CastSystemGestureDispatcher::HandleScreenExit(
CastSideSwipeOrigin side,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
gesture_handler->HandleScreenExit(side, touch_location);
}
}
void CastSystemGestureDispatcher::HandleScreenEnter(
CastSideSwipeOrigin side,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
gesture_handler->HandleScreenEnter(side, touch_location);
}
}
CastGestureHandler::Corner CastSystemGestureDispatcher::HandledCornerHolds()
const {
int corner_hold_bitmask = CastGestureHandler::NO_CORNERS;
for (auto* gesture_handler : gesture_handlers_) {
corner_hold_bitmask |= gesture_handler->HandledCornerHolds();
}
return static_cast<CastGestureHandler::Corner>(corner_hold_bitmask);
}
void CastSystemGestureDispatcher::HandleCornerHold(
CastGestureHandler::Corner corner_origin,
const ui::TouchEvent& touch_event) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->HandledCornerHolds() & corner_origin) {
gesture_handler->HandleCornerHold(corner_origin, touch_event);
}
}
}
void CastSystemGestureDispatcher::HandleCornerHoldEnd(
CastGestureHandler::Corner corner_origin,
const ui::TouchEvent& touch_event) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->HandledCornerHolds() & corner_origin) {
gesture_handler->HandleCornerHoldEnd(corner_origin, touch_event);
}
}
}
} // namespace chromecast
......@@ -35,6 +35,15 @@ class CastSystemGestureDispatcher : public CastGestureHandler {
const gfx::Point& touch_location) override;
void HandleTapDownGesture(const gfx::Point& touch_location) override;
void HandleTapGesture(const gfx::Point& touch_location) override;
void HandleScreenExit(CastSideSwipeOrigin side,
const gfx::Point& touch_location) override;
void HandleScreenEnter(CastSideSwipeOrigin side,
const gfx::Point& touch_location) override;
Corner HandledCornerHolds() const override;
void HandleCornerHold(Corner corner_origin,
const ui::TouchEvent& touch_event) override;
void HandleCornerHoldEnd(Corner corner_origin,
const ui::TouchEvent& touch_event) override;
private:
base::flat_set<CastGestureHandler*> gesture_handlers_;
......
......@@ -6,8 +6,10 @@
#define CHROMECAST_GRAPHICS_GESTURES_SIDE_SWIPE_DETECTOR_H_
#include "base/timer/elapsed_timer.h"
#include "base/timer/timer.h"
#include "chromecast/graphics/cast_gesture_handler.h"
#include "ui/events/event_rewriter.h"
#include "ui/events/gesture_detection/gesture_detector.h"
namespace aura {
class Window;
......@@ -15,6 +17,10 @@ class Window;
namespace chromecast {
namespace test {
class SideSwipeDetectorTest;
} // namespace test
// An event rewriter for detecting system-wide gestures performed on the margins
// of the root window.
// Recognizes swipe gestures that originate from the top, left, bottom, and
......@@ -28,8 +34,10 @@ class SideSwipeDetector : public ui::EventRewriter {
~SideSwipeDetector() override;
CastSideSwipeOrigin GetDragPosition(const gfx::Point& point,
const gfx::Rect& screen_bounds) const;
bool GetMarginPosition(const gfx::Point& point,
const gfx::Rect& screen_bounds,
CastSideSwipeOrigin* side,
CastGestureHandler::Corner* corner) const;
// Overridden from ui::EventRewriter
ui::EventRewriteStatus RewriteEvent(
......@@ -40,7 +48,16 @@ class SideSwipeDetector : public ui::EventRewriter {
std::unique_ptr<ui::Event>* new_event) override;
private:
friend class test::SideSwipeDetectorTest;
void SetTimerForTesting(std::unique_ptr<base::OneShotTimer> mock_timer);
void StashEvent(const ui::TouchEvent& event);
void OnCornerHoldTimerFired();
void EndCornerHold(const ui::TouchEvent& event);
void CancelCornerHoldCheck();
ui::EventRewriteStatus StartNextDispatchStashedEvents(
std::unique_ptr<ui::Event>* new_event);
const int gesture_start_width_;
const int gesture_start_height_;
......@@ -48,14 +65,22 @@ class SideSwipeDetector : public ui::EventRewriter {
CastGestureHandler* gesture_handler_;
aura::Window* root_window_;
CastSideSwipeOrigin current_swipe_;
base::ElapsedTimer current_swipe_time_;
CastSideSwipeOrigin current_swipe_origin_;
int current_pointer_id_;
base::ElapsedTimer gesture_elapsed_timer_;
std::deque<ui::TouchEvent> stashed_events_;
// A default gesture detector config, so we can share the same
// longpress timeout for corner hold.
ui::GestureDetector::Config gesture_detector_config_;
std::unique_ptr<base::OneShotTimer> corner_hold_timer_;
std::unique_ptr<ui::Event> corner_hold_start_event_;
bool in_corner_hold_;
CastGestureHandler::Corner current_corner_origin_;
DISALLOW_COPY_AND_ASSIGN(SideSwipeDetector);
};
} // namespace chromecast
#endif // CHROMECAST_GRAPHICS_GESTURES_SIDE_SWIPE_DETECTOR_H_
\ No newline at end of file
#endif // CHROMECAST_GRAPHICS_GESTURES_SIDE_SWIPE_DETECTOR_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment