Commit 3be86db2 authored by Ryan Daum's avatar Ryan Daum Committed by Commit Bot

[chromecast] Refactor system gesture dispatching.

A refactor to enable us to fix some bugs in the interaction between
screenreader mode (TouchExplorationController) and system gestures.

  - Break the SideSwipeDetector out and instantiate it separately from
    the CastSystemGestureEventHandler.
  - Make the CastSystemGestureEventHandler responsible only for
    TAP/TAP_DOWN gestures.
  - Provide a separate dispatcher class to allow classes other than
    CastSystemGestureEventHandler and SideSwipeDetector to call it
    (for internal b/112073530)
  - Move gesture handling (including triple-tap) into a separate
    directory for cleanliness.

Bug: internal b/112073530
Bug: internal b/112073644
Test: unit tests, manual on device

Change-Id: I6593851cd1a10ee287de2dc1feaf98a5caad21f1
Reviewed-on: https://chromium-review.googlesource.com/1158615Reviewed-by: default avatarKevin Schoedel <kpschoedel@chromium.org>
Reviewed-by: default avatarAlex Sakhartchouk <alexst@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580532}
parent 72153c86
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "chromecast/browser/accessibility/touch_exploration_manager.h" #include "chromecast/browser/accessibility/touch_exploration_manager.h"
#include "chromecast/graphics/accessibility/accessibility_focus_ring_controller.h" #include "chromecast/graphics/accessibility/accessibility_focus_ring_controller.h"
#include "chromecast/graphics/triple_tap_detector.h" #include "chromecast/graphics/gestures/triple_tap_detector.h"
namespace aura { namespace aura {
class WindowTreeHost; class WindowTreeHost;
......
...@@ -42,12 +42,16 @@ cast_source_set("graphics") { ...@@ -42,12 +42,16 @@ cast_source_set("graphics") {
"accessibility/partial_magnification_controller.h", "accessibility/partial_magnification_controller.h",
"cast_focus_client_aura.cc", "cast_focus_client_aura.cc",
"cast_focus_client_aura.h", "cast_focus_client_aura.h",
"cast_system_gesture_event_handler.cc",
"cast_system_gesture_event_handler.h",
"cast_window_manager_aura.cc", "cast_window_manager_aura.cc",
"cast_window_manager_aura.h", "cast_window_manager_aura.h",
"triple_tap_detector.cc", "gestures/cast_system_gesture_dispatcher.cc",
"triple_tap_detector.h", "gestures/cast_system_gesture_dispatcher.h",
"gestures/cast_system_gesture_event_handler.cc",
"gestures/cast_system_gesture_event_handler.h",
"gestures/side_swipe_detector.cc",
"gestures/side_swipe_detector.h",
"gestures/triple_tap_detector.cc",
"gestures/triple_tap_detector.h",
] ]
deps += [ deps += [
...@@ -108,11 +112,11 @@ if (use_aura && !is_cast_audio_only) { ...@@ -108,11 +112,11 @@ if (use_aura && !is_cast_audio_only) {
"accessibility/accessibility_focus_ring_controller_unittest.cc", "accessibility/accessibility_focus_ring_controller_unittest.cc",
"accessibility/partial_magnification_controller_unittest.cc", "accessibility/partial_magnification_controller_unittest.cc",
"cast_focus_client_aura_test.cc", "cast_focus_client_aura_test.cc",
"cast_system_gesture_event_handler_test.cc",
"cast_views_test.cc", "cast_views_test.cc",
"cast_window_manager_aura_test.cc", "cast_window_manager_aura_test.cc",
"gestures/side_swipe_detector_test.cc",
"gestures/triple_tap_detector_test.cc",
"run_all_unittests.cc", "run_all_unittests.cc",
"triple_tap_detector_test.cc",
] ]
deps = [ deps = [
":graphics", ":graphics",
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROMECAST_GRAPHICS_CAST_GESTURE_HANDLER_H_ #ifndef CHROMECAST_GRAPHICS_CAST_GESTURE_HANDLER_H_
#define CHROMECAST_GRAPHICS_CAST_GESTURE_HANDLER_H_ #define CHROMECAST_GRAPHICS_CAST_GESTURE_HANDLER_H_
// TODO(rdaum): Move into chromecast/graphics/gestures, which will require some
// cross-repo maneuvers.
#include "base/macros.h" #include "base/macros.h"
namespace gfx { namespace gfx {
......
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "chromecast/graphics/cast_focus_client_aura.h" #include "chromecast/graphics/cast_focus_client_aura.h"
#include "chromecast/graphics/cast_system_gesture_event_handler.h" #include "chromecast/graphics/gestures/cast_system_gesture_event_handler.h"
#include "chromecast/graphics/gestures/side_swipe_detector.h"
#include "ui/aura/client/default_capture_client.h" #include "ui/aura/client/default_capture_client.h"
#include "ui/aura/client/focus_change_observer.h" #include "ui/aura/client/focus_change_observer.h"
#include "ui/aura/client/screen_position_client.h" #include "ui/aura/client/screen_position_client.h"
...@@ -245,8 +246,12 @@ void CastWindowManagerAura::Setup() { ...@@ -245,8 +246,12 @@ void CastWindowManagerAura::Setup() {
screen_position_client_.get()); screen_position_client_.get());
window_tree_host_->Show(); window_tree_host_->Show();
system_gesture_dispatcher_ = std::make_unique<CastSystemGestureDispatcher>();
system_gesture_event_handler_ = system_gesture_event_handler_ =
std::make_unique<CastSystemGestureEventHandler>(root_window); std::make_unique<CastSystemGestureEventHandler>(
system_gesture_dispatcher_.get(), root_window);
side_swipe_detector_ = std::make_unique<SideSwipeDetector>(
system_gesture_dispatcher_.get(), root_window);
} }
CastWindowTreeHost* CastWindowManagerAura::window_tree_host() const { CastWindowTreeHost* CastWindowManagerAura::window_tree_host() const {
...@@ -258,6 +263,7 @@ void CastWindowManagerAura::TearDown() { ...@@ -258,6 +263,7 @@ void CastWindowManagerAura::TearDown() {
if (!window_tree_host_) { if (!window_tree_host_) {
return; return;
} }
side_swipe_detector_.reset();
capture_client_.reset(); capture_client_.reset();
aura::client::SetWindowParentingClient(window_tree_host_->window(), nullptr); aura::client::SetWindowParentingClient(window_tree_host_->window(), nullptr);
wm::SetActivationClient(window_tree_host_->window(), nullptr); wm::SetActivationClient(window_tree_host_->window(), nullptr);
...@@ -303,13 +309,13 @@ void CastWindowManagerAura::AddWindow(gfx::NativeView child) { ...@@ -303,13 +309,13 @@ void CastWindowManagerAura::AddWindow(gfx::NativeView child) {
void CastWindowManagerAura::AddGestureHandler(CastGestureHandler* handler) { void CastWindowManagerAura::AddGestureHandler(CastGestureHandler* handler) {
DCHECK(system_gesture_event_handler_); DCHECK(system_gesture_event_handler_);
system_gesture_event_handler_->AddGestureHandler(handler); system_gesture_dispatcher_->AddGestureHandler(handler);
} }
void CastWindowManagerAura::CastWindowManagerAura::RemoveGestureHandler( void CastWindowManagerAura::CastWindowManagerAura::RemoveGestureHandler(
CastGestureHandler* handler) { CastGestureHandler* handler) {
DCHECK(system_gesture_event_handler_); DCHECK(system_gesture_event_handler_);
system_gesture_event_handler_->RemoveGestureHandler(handler); system_gesture_dispatcher_->RemoveGestureHandler(handler);
} }
void CastWindowManagerAura::CastWindowManagerAura::SetColorInversion( void CastWindowManagerAura::CastWindowManagerAura::SetColorInversion(
......
...@@ -23,6 +23,8 @@ namespace chromecast { ...@@ -23,6 +23,8 @@ namespace chromecast {
class CastFocusClientAura; class CastFocusClientAura;
class CastSystemGestureEventHandler; class CastSystemGestureEventHandler;
class CastSystemGestureDispatcher;
class SideSwipeDetector;
// An aura::WindowTreeHost that correctly converts input events. // An aura::WindowTreeHost that correctly converts input events.
class CastWindowTreeHost : public aura::WindowTreeHostPlatform { class CastWindowTreeHost : public aura::WindowTreeHostPlatform {
...@@ -76,7 +78,9 @@ class CastWindowManagerAura : public CastWindowManager, ...@@ -76,7 +78,9 @@ class CastWindowManagerAura : public CastWindowManager,
std::unique_ptr<aura::client::DefaultCaptureClient> capture_client_; std::unique_ptr<aura::client::DefaultCaptureClient> capture_client_;
std::unique_ptr<CastFocusClientAura> focus_client_; std::unique_ptr<CastFocusClientAura> focus_client_;
std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_; std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_;
std::unique_ptr<CastSystemGestureDispatcher> system_gesture_dispatcher_;
std::unique_ptr<CastSystemGestureEventHandler> system_gesture_event_handler_; std::unique_ptr<CastSystemGestureEventHandler> system_gesture_event_handler_;
std::unique_ptr<SideSwipeDetector> side_swipe_detector_;
DISALLOW_COPY_AND_ASSIGN(CastWindowManagerAura); DISALLOW_COPY_AND_ASSIGN(CastWindowManagerAura);
}; };
......
// Copyright 2018 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.
#include "chromecast/graphics/gestures/cast_system_gesture_dispatcher.h"
#include "base/logging.h"
namespace chromecast {
CastSystemGestureDispatcher::CastSystemGestureDispatcher() {}
CastSystemGestureDispatcher::~CastSystemGestureDispatcher() {
DCHECK(gesture_handlers_.empty());
}
void CastSystemGestureDispatcher::AddGestureHandler(
CastGestureHandler* handler) {
gesture_handlers_.insert(handler);
}
void CastSystemGestureDispatcher::RemoveGestureHandler(
CastGestureHandler* handler) {
gesture_handlers_.erase(handler);
}
bool CastSystemGestureDispatcher::CanHandleSwipe(
CastSideSwipeOrigin swipe_origin) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
return true;
}
}
return false;
}
void CastSystemGestureDispatcher::HandleSideSwipeBegin(
CastSideSwipeOrigin swipe_origin,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
gesture_handler->HandleSideSwipeBegin(swipe_origin, touch_location);
}
}
}
void CastSystemGestureDispatcher::HandleSideSwipeContinue(
CastSideSwipeOrigin swipe_origin,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
gesture_handler->HandleSideSwipeContinue(swipe_origin, touch_location);
}
}
}
void CastSystemGestureDispatcher::HandleSideSwipeEnd(
CastSideSwipeOrigin swipe_origin,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
gesture_handler->HandleSideSwipeEnd(swipe_origin, touch_location);
}
}
}
void CastSystemGestureDispatcher::HandleTapDownGesture(
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
gesture_handler->HandleTapDownGesture(touch_location);
}
}
void CastSystemGestureDispatcher::HandleTapGesture(
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
gesture_handler->HandleTapGesture(touch_location);
}
}
} // namespace chromecast
\ No newline at end of file
...@@ -2,37 +2,21 @@ ...@@ -2,37 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROMECAST_GRAPHICS_CAST_SYSTEM_GESTURE_EVENT_HANDLER_H_ #ifndef CHROMECAST_GRAPHICS_GESTURES_CAST_SYSTEM_GESTURE_DISPATCHER_H_
#define CHROMECAST_GRAPHICS_CAST_SYSTEM_GESTURE_EVENT_HANDLER_H_ #define CHROMECAST_GRAPHICS_GESTURES_CAST_SYSTEM_GESTURE_DISPATCHER_H_
#include "base/containers/flat_set.h" #include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/timer/elapsed_timer.h"
#include "chromecast/graphics/cast_gesture_handler.h" #include "chromecast/graphics/cast_gesture_handler.h"
#include "ui/events/event_handler.h"
namespace aura {
class Window;
} // namespace aura
namespace gfx {
class Point;
} // namespace gfx
namespace chromecast { namespace chromecast {
class SideSwipeDetector; // A CastGestureHandler that fans system gesture events out to multiple
// consumers.
// Looks for root window cast system gestures, such as tap events and edge class CastSystemGestureDispatcher : public CastGestureHandler {
// swipes, and dispatches them to interested observers. Installs an event
// rewriter to examine touch events for side swipe gestures. Also installs
// itself as an event handler for observing gesture tap/press events.
class CastSystemGestureEventHandler : public ui::EventHandler,
public CastGestureHandler {
public: public:
explicit CastSystemGestureEventHandler(aura::Window* root_window); CastSystemGestureDispatcher();
~CastSystemGestureEventHandler() override; ~CastSystemGestureDispatcher() override;
// Register a new handler for gesture events, including side swipe and tap. // Register a new handler for gesture events, including side swipe and tap.
void AddGestureHandler(CastGestureHandler* handler); void AddGestureHandler(CastGestureHandler* handler);
...@@ -40,9 +24,6 @@ class CastSystemGestureEventHandler : public ui::EventHandler, ...@@ -40,9 +24,6 @@ class CastSystemGestureEventHandler : public ui::EventHandler,
// Remove the registration of a gesture handler. // Remove the registration of a gesture handler.
void RemoveGestureHandler(CastGestureHandler* handler); void RemoveGestureHandler(CastGestureHandler* handler);
// ui::EventHandler implementation.
void OnGestureEvent(ui::GestureEvent* event) override;
// Implementation of CastGestureHandler methods which fan out to our gesture // Implementation of CastGestureHandler methods which fan out to our gesture
// handlers. // handlers.
bool CanHandleSwipe(CastSideSwipeOrigin swipe_origin) override; bool CanHandleSwipe(CastSideSwipeOrigin swipe_origin) override;
...@@ -52,17 +33,12 @@ class CastSystemGestureEventHandler : public ui::EventHandler, ...@@ -52,17 +33,12 @@ class CastSystemGestureEventHandler : public ui::EventHandler,
const gfx::Point& touch_location) override; const gfx::Point& touch_location) override;
void HandleSideSwipeEnd(CastSideSwipeOrigin swipe_origin, void HandleSideSwipeEnd(CastSideSwipeOrigin swipe_origin,
const gfx::Point& touch_location) override; const gfx::Point& touch_location) override;
void HandleTapDownGesture(const gfx::Point& touch_location) override;
void HandleTapGesture(const gfx::Point& touch_location) override;
private: private:
void ProcessPressedEvent(ui::GestureEvent* event);
aura::Window* root_window_;
std::unique_ptr<SideSwipeDetector> side_swipe_detector_;
base::flat_set<CastGestureHandler*> gesture_handlers_; base::flat_set<CastGestureHandler*> gesture_handlers_;
DISALLOW_COPY_AND_ASSIGN(CastSystemGestureEventHandler);
}; };
} // namespace chromecast } // namespace chromecast
#endif // CHROMECAST_GRAPHICS_CAST_SYSTEM_GESTURE_EVENT_HANDLER_H_ #endif // CHROMECAST_GRAPHICS_GESTURES_CAST_SYSTEM_GESTURE_DISPATCHER_H_
\ No newline at end of file
// Copyright 2018 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.
#include "chromecast/graphics/gestures/cast_system_gesture_event_handler.h"
#include <deque>
#include "base/auto_reset.h"
#include "chromecast/base/chromecast_switches.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_rewriter.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/wm/core/coordinate_conversion.h"
namespace chromecast {
CastSystemGestureEventHandler::CastSystemGestureEventHandler(
CastSystemGestureDispatcher* dispatcher,
aura::Window* root_window)
: EventHandler(), dispatcher_(dispatcher), root_window_(root_window) {
DCHECK(dispatcher);
DCHECK(root_window);
root_window->AddPreTargetHandler(this);
}
CastSystemGestureEventHandler::~CastSystemGestureEventHandler() {
root_window_->RemovePreTargetHandler(this);
}
void CastSystemGestureEventHandler::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_TAP ||
event->type() == ui::ET_GESTURE_TAP_DOWN) {
ProcessPressedEvent(event);
}
}
void CastSystemGestureEventHandler::ProcessPressedEvent(
ui::GestureEvent* event) {
gfx::Point touch_location(event->location());
// Let the subscriber know about the gesture begin.
switch (event->type()) {
case ui::ET_GESTURE_TAP_DOWN:
dispatcher_->HandleTapDownGesture(touch_location);
break;
case ui::ET_GESTURE_TAP:
dispatcher_->HandleTapGesture(touch_location);
break;
default:
return;
}
}
} // namespace chromecast
// Copyright 2018 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 CHROMECAST_GRAPHICS_GESTURES_CAST_SYSTEM_GESTURE_EVENT_HANDLER_H_
#define CHROMECAST_GRAPHICS_GESTURES_CAST_SYSTEM_GESTURE_EVENT_HANDLER_H_
#include "base/macros.h"
#include "chromecast/graphics/gestures/cast_system_gesture_dispatcher.h"
#include "ui/events/event_handler.h"
namespace aura {
class Window;
} // namespace aura
namespace chromecast {
// Observes gesture events on the root window and dispatches them to the cast
// system gesture dispatcher.
class CastSystemGestureEventHandler : public ui::EventHandler {
public:
explicit CastSystemGestureEventHandler(
CastSystemGestureDispatcher* dispatcher,
aura::Window* root_window);
~CastSystemGestureEventHandler() override;
// ui::EventHandler implementation.
void OnGestureEvent(ui::GestureEvent* event) override;
private:
void ProcessPressedEvent(ui::GestureEvent* event);
CastSystemGestureDispatcher* dispatcher_;
aura::Window* root_window_;
DISALLOW_COPY_AND_ASSIGN(CastSystemGestureEventHandler);
};
} // namespace chromecast
#endif // CHROMECAST_GRAPHICS_GESTURES_CAST_SYSTEM_GESTURE_EVENT_HANDLER_H_
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chromecast/graphics/cast_system_gesture_event_handler.h" #include "chromecast/graphics/gestures/side_swipe_detector.h"
#include <deque> #include <deque>
...@@ -20,9 +20,7 @@ ...@@ -20,9 +20,7 @@
#include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/coordinate_conversion.h"
namespace chromecast { namespace chromecast {
namespace { namespace {
// The number of pixels from the very left or right of the screen to consider as // The number of pixels from the very left or right of the screen to consider as
// a valid origin for the left or right swipe gesture. // a valid origin for the left or right swipe gesture.
constexpr int kDefaultSideGestureStartWidth = 35; constexpr int kDefaultSideGestureStartWidth = 35;
...@@ -49,46 +47,6 @@ int BottomGestureStartHeight() { ...@@ -49,46 +47,6 @@ int BottomGestureStartHeight() {
} // namespace } // namespace
// An event rewriter for detecting system-wide gestures performed on the screen.
// Recognizes swipe gestures that originate from the top, left, bottom, and
// right of the root window. Stashes copies of touch events that occur during
// the side swipe, and replays them if the finger releases before leaving the
// margin area.
class SideSwipeDetector : public ui::EventRewriter {
public:
SideSwipeDetector(CastGestureHandler* gesture_handler,
aura::Window* root_window);
~SideSwipeDetector() override;
CastSideSwipeOrigin GetDragPosition(const gfx::Point& point,
const gfx::Rect& screen_bounds) const;
// Overridden from ui::EventRewriter
ui::EventRewriteStatus RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* rewritten_event) override;
ui::EventRewriteStatus NextDispatchEvent(
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) override;
private:
void StashEvent(const ui::TouchEvent& event);
const int gesture_start_width_;
const int gesture_start_height_;
const int bottom_gesture_start_height_;
CastGestureHandler* gesture_handler_;
aura::Window* root_window_;
CastSideSwipeOrigin current_swipe_;
base::ElapsedTimer current_swipe_time_;
std::deque<ui::TouchEvent> stashed_events_;
DISALLOW_COPY_AND_ASSIGN(SideSwipeDetector);
};
SideSwipeDetector::SideSwipeDetector(CastGestureHandler* gesture_handler, SideSwipeDetector::SideSwipeDetector(CastGestureHandler* gesture_handler,
aura::Window* root_window) aura::Window* root_window)
: gesture_start_width_(GetSwitchValueInt(switches::kSystemGestureStartWidth, : gesture_start_width_(GetSwitchValueInt(switches::kSystemGestureStartWidth,
...@@ -251,98 +209,4 @@ ui::EventRewriteStatus SideSwipeDetector::NextDispatchEvent( ...@@ -251,98 +209,4 @@ ui::EventRewriteStatus SideSwipeDetector::NextDispatchEvent(
return ui::EVENT_REWRITE_DISPATCH_ANOTHER; return ui::EVENT_REWRITE_DISPATCH_ANOTHER;
} }
CastSystemGestureEventHandler::CastSystemGestureEventHandler(
aura::Window* root_window)
: EventHandler(),
root_window_(root_window),
side_swipe_detector_(
std::make_unique<SideSwipeDetector>(this, root_window)) {
DCHECK(root_window);
root_window->AddPreTargetHandler(this);
}
CastSystemGestureEventHandler::~CastSystemGestureEventHandler() {
DCHECK(gesture_handlers_.empty());
root_window_->RemovePreTargetHandler(this);
}
void CastSystemGestureEventHandler::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_TAP ||
event->type() == ui::ET_GESTURE_TAP_DOWN) {
ProcessPressedEvent(event);
}
}
void CastSystemGestureEventHandler::ProcessPressedEvent(
ui::GestureEvent* event) {
if (gesture_handlers_.empty()) {
return;
}
gfx::Point touch_location(event->location());
// Let the subscriber know about the gesture begin.
switch (event->type()) {
case ui::ET_GESTURE_TAP_DOWN: {
for (auto* gesture_handler : gesture_handlers_) {
gesture_handler->HandleTapDownGesture(touch_location);
}
break;
}
case ui::ET_GESTURE_TAP: {
for (auto* gesture_handler : gesture_handlers_) {
gesture_handler->HandleTapGesture(touch_location);
}
break;
}
default: { return; }
}
}
void CastSystemGestureEventHandler::AddGestureHandler(
CastGestureHandler* handler) {
gesture_handlers_.insert(handler);
}
void CastSystemGestureEventHandler::RemoveGestureHandler(
CastGestureHandler* handler) {
gesture_handlers_.erase(handler);
}
bool CastSystemGestureEventHandler::CanHandleSwipe(
CastSideSwipeOrigin swipe_origin) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
return true;
}
}
return false;
}
void CastSystemGestureEventHandler::HandleSideSwipeBegin(
CastSideSwipeOrigin swipe_origin,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
gesture_handler->HandleSideSwipeBegin(swipe_origin, touch_location);
}
}
}
void CastSystemGestureEventHandler::HandleSideSwipeContinue(
CastSideSwipeOrigin swipe_origin,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
gesture_handler->HandleSideSwipeContinue(swipe_origin, touch_location);
}
}
}
void CastSystemGestureEventHandler::HandleSideSwipeEnd(
CastSideSwipeOrigin swipe_origin,
const gfx::Point& touch_location) {
for (auto* gesture_handler : gesture_handlers_) {
if (gesture_handler->CanHandleSwipe(swipe_origin)) {
gesture_handler->HandleSideSwipeEnd(swipe_origin, touch_location);
}
}
}
} // namespace chromecast } // namespace chromecast
// Copyright 2018 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 CHROMECAST_GRAPHICS_GESTURES_SIDE_SWIPE_DETECTOR_H_
#define CHROMECAST_GRAPHICS_GESTURES_SIDE_SWIPE_DETECTOR_H_
#include "base/timer/elapsed_timer.h"
#include "chromecast/graphics/cast_gesture_handler.h"
#include "ui/events/event_rewriter.h"
namespace aura {
class Window;
} // namespace aura
namespace chromecast {
// 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
// right of the root window. Stashes copies of touch events that occur during
// the side swipe, and replays them if the finger releases before leaving the
// margin area.
class SideSwipeDetector : public ui::EventRewriter {
public:
SideSwipeDetector(CastGestureHandler* gesture_handler,
aura::Window* root_window);
~SideSwipeDetector() override;
CastSideSwipeOrigin GetDragPosition(const gfx::Point& point,
const gfx::Rect& screen_bounds) const;
// Overridden from ui::EventRewriter
ui::EventRewriteStatus RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* rewritten_event) override;
ui::EventRewriteStatus NextDispatchEvent(
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) override;
private:
void StashEvent(const ui::TouchEvent& event);
const int gesture_start_width_;
const int gesture_start_height_;
const int bottom_gesture_start_height_;
CastGestureHandler* gesture_handler_;
aura::Window* root_window_;
CastSideSwipeOrigin current_swipe_;
base::ElapsedTimer current_swipe_time_;
std::deque<ui::TouchEvent> stashed_events_;
DISALLOW_COPY_AND_ASSIGN(SideSwipeDetector);
};
} // namespace chromecast
#endif // CHROMECAST_GRAPHICS_GESTURES_SIDE_SWIPE_DETECTOR_H_
\ No newline at end of file
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chromecast/graphics/cast_system_gesture_event_handler.h" #include "chromecast/graphics/gestures/side_swipe_detector.h"
#include <memory> #include <memory>
#include "base/run_loop.h"
#include "ui/aura/client/screen_position_client.h" #include "ui/aura/client/screen_position_client.h"
#include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/event_generator_delegate_aura.h" #include "ui/aura/test/event_generator_delegate_aura.h"
...@@ -107,9 +108,9 @@ class TestEventHandler : public ui::EventHandler { ...@@ -107,9 +108,9 @@ class TestEventHandler : public ui::EventHandler {
int num_touch_events_received_; int num_touch_events_received_;
}; };
class CastSystemGestureEventHandlerTest : public aura::test::AuraTestBase { class SideSwipeDetectorTest : public aura::test::AuraTestBase {
public: public:
~CastSystemGestureEventHandlerTest() override = default; ~SideSwipeDetectorTest() override = default;
void SetUp() override { void SetUp() override {
aura::test::AuraTestBase::SetUp(); aura::test::AuraTestBase::SetUp();
...@@ -118,17 +119,15 @@ class CastSystemGestureEventHandlerTest : public aura::test::AuraTestBase { ...@@ -118,17 +119,15 @@ class CastSystemGestureEventHandlerTest : public aura::test::AuraTestBase {
aura::client::SetScreenPositionClient(root_window(), aura::client::SetScreenPositionClient(root_window(),
screen_position_client_.get()); screen_position_client_.get());
gesture_event_handler_ =
std::make_unique<CastSystemGestureEventHandler>(root_window());
gesture_handler_ = std::make_unique<TestSideSwipeGestureHandler>(); gesture_handler_ = std::make_unique<TestSideSwipeGestureHandler>();
gesture_event_handler_->AddGestureHandler(gesture_handler_.get()); side_swipe_detector_ = std::make_unique<SideSwipeDetector>(
gesture_handler_.get(), root_window());
test_event_handler_ = std::make_unique<TestEventHandler>(); test_event_handler_ = std::make_unique<TestEventHandler>();
root_window()->AddPostTargetHandler(test_event_handler_.get()); root_window()->AddPostTargetHandler(test_event_handler_.get());
} }
void TearDown() override { void TearDown() override {
gesture_event_handler_->RemoveGestureHandler(gesture_handler_.get()); side_swipe_detector_.reset();
gesture_event_handler_.reset();
gesture_handler_.reset(); gesture_handler_.reset();
aura::test::AuraTestBase::TearDown(); aura::test::AuraTestBase::TearDown();
...@@ -152,13 +151,13 @@ class CastSystemGestureEventHandlerTest : public aura::test::AuraTestBase { ...@@ -152,13 +151,13 @@ class CastSystemGestureEventHandlerTest : public aura::test::AuraTestBase {
std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_; std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_;
std::unique_ptr<ui::test::EventGenerator> event_generator_; std::unique_ptr<ui::test::EventGenerator> event_generator_;
std::unique_ptr<CastSystemGestureEventHandler> gesture_event_handler_; std::unique_ptr<SideSwipeDetector> side_swipe_detector_;
std::unique_ptr<TestEventHandler> test_event_handler_; std::unique_ptr<TestEventHandler> test_event_handler_;
std::unique_ptr<TestSideSwipeGestureHandler> gesture_handler_; std::unique_ptr<TestSideSwipeGestureHandler> gesture_handler_;
}; };
// Test that initialization works and initial state is clean. // Test that initialization works and initial state is clean.
TEST_F(CastSystemGestureEventHandlerTest, Initialization) { TEST_F(SideSwipeDetectorTest, Initialization) {
EXPECT_EQ(CastSideSwipeOrigin::NONE, EXPECT_EQ(CastSideSwipeOrigin::NONE,
test_gesture_handler().begin_swipe_origin()); test_gesture_handler().begin_swipe_origin());
EXPECT_EQ(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(kZeroPoint, test_gesture_handler().begin_swipe_point());
...@@ -169,14 +168,15 @@ TEST_F(CastSystemGestureEventHandlerTest, Initialization) { ...@@ -169,14 +168,15 @@ TEST_F(CastSystemGestureEventHandlerTest, Initialization) {
} }
// A swipe in the middle of the screen should produce no system gesture. // A swipe in the middle of the screen should produce no system gesture.
TEST_F(CastSystemGestureEventHandlerTest, SwipeWithNoSystemGesture) { TEST_F(SideSwipeDetectorTest, SwipeWithNoSystemGesture) {
gfx::Point drag_point(root_window()->bounds().width() / 2, gfx::Point drag_point(root_window()->bounds().width() / 2,
root_window()->bounds().height() / 2); root_window()->bounds().height() / 2);
ui::test::EventGenerator& generator = GetEventGenerator(); ui::test::EventGenerator& generator = GetEventGenerator();
generator.GestureScrollSequence(drag_point, generator.GestureScrollSequence(drag_point,
drag_point - gfx::Vector2d(0, kSwipeDistance), drag_point - gfx::Vector2d(0, kSwipeDistance),
kTimeDelay, kNumSteps); kTimeDelay, kNumSteps);
RunAllPendingInMessageLoop(); base::RunLoop run_loop;
run_loop.RunUntilIdle();
EXPECT_EQ(CastSideSwipeOrigin::NONE, EXPECT_EQ(CastSideSwipeOrigin::NONE,
test_gesture_handler().begin_swipe_origin()); test_gesture_handler().begin_swipe_origin());
...@@ -187,13 +187,14 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeWithNoSystemGesture) { ...@@ -187,13 +187,14 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeWithNoSystemGesture) {
EXPECT_NE(0, test_event_handler().NumTouchEventsReceived()); EXPECT_NE(0, test_event_handler().NumTouchEventsReceived());
} }
TEST_F(CastSystemGestureEventHandlerTest, SwipeFromLeft) { TEST_F(SideSwipeDetectorTest, SwipeFromLeft) {
gfx::Point drag_point(0, root_window()->bounds().height() / 2); gfx::Point drag_point(0, root_window()->bounds().height() / 2);
ui::test::EventGenerator& generator = GetEventGenerator(); ui::test::EventGenerator& generator = GetEventGenerator();
generator.GestureScrollSequence(drag_point, generator.GestureScrollSequence(drag_point,
drag_point + gfx::Vector2d(kSwipeDistance, 0), drag_point + gfx::Vector2d(kSwipeDistance, 0),
kTimeDelay, kNumSteps); kTimeDelay, kNumSteps);
RunAllPendingInMessageLoop(); base::RunLoop run_loop;
run_loop.RunUntilIdle();
EXPECT_EQ(CastSideSwipeOrigin::LEFT, EXPECT_EQ(CastSideSwipeOrigin::LEFT,
test_gesture_handler().begin_swipe_origin()); test_gesture_handler().begin_swipe_origin());
...@@ -204,14 +205,15 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromLeft) { ...@@ -204,14 +205,15 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromLeft) {
EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived());
} }
TEST_F(CastSystemGestureEventHandlerTest, SwipeFromRight) { TEST_F(SideSwipeDetectorTest, SwipeFromRight) {
gfx::Point drag_point(root_window()->bounds().width(), gfx::Point drag_point(root_window()->bounds().width(),
root_window()->bounds().height() / 2); root_window()->bounds().height() / 2);
ui::test::EventGenerator& generator = GetEventGenerator(); ui::test::EventGenerator& generator = GetEventGenerator();
generator.GestureScrollSequence(drag_point, generator.GestureScrollSequence(drag_point,
drag_point - gfx::Vector2d(kSwipeDistance, 0), drag_point - gfx::Vector2d(kSwipeDistance, 0),
kTimeDelay, kNumSteps); kTimeDelay, kNumSteps);
RunAllPendingInMessageLoop(); base::RunLoop run_loop;
run_loop.RunUntilIdle();
EXPECT_EQ(CastSideSwipeOrigin::RIGHT, EXPECT_EQ(CastSideSwipeOrigin::RIGHT,
test_gesture_handler().begin_swipe_origin()); test_gesture_handler().begin_swipe_origin());
...@@ -222,13 +224,14 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromRight) { ...@@ -222,13 +224,14 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromRight) {
EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived());
} }
TEST_F(CastSystemGestureEventHandlerTest, SwipeFromTop) { TEST_F(SideSwipeDetectorTest, SwipeFromTop) {
gfx::Point drag_point(root_window()->bounds().width() / 2, 0); gfx::Point drag_point(root_window()->bounds().width() / 2, 0);
ui::test::EventGenerator& generator = GetEventGenerator(); ui::test::EventGenerator& generator = GetEventGenerator();
generator.GestureScrollSequence(drag_point, generator.GestureScrollSequence(drag_point,
drag_point + gfx::Vector2d(0, kSwipeDistance), drag_point + gfx::Vector2d(0, kSwipeDistance),
kTimeDelay, kNumSteps); kTimeDelay, kNumSteps);
RunAllPendingInMessageLoop(); base::RunLoop run_loop;
run_loop.RunUntilIdle();
EXPECT_EQ(CastSideSwipeOrigin::TOP, EXPECT_EQ(CastSideSwipeOrigin::TOP,
test_gesture_handler().begin_swipe_origin()); test_gesture_handler().begin_swipe_origin());
...@@ -239,14 +242,15 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromTop) { ...@@ -239,14 +242,15 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromTop) {
EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived());
} }
TEST_F(CastSystemGestureEventHandlerTest, SwipeFromBottom) { TEST_F(SideSwipeDetectorTest, SwipeFromBottom) {
gfx::Point drag_point(root_window()->bounds().width() / 2, gfx::Point drag_point(root_window()->bounds().width() / 2,
root_window()->bounds().height()); root_window()->bounds().height());
ui::test::EventGenerator& generator = GetEventGenerator(); ui::test::EventGenerator& generator = GetEventGenerator();
generator.GestureScrollSequence(drag_point, generator.GestureScrollSequence(drag_point,
drag_point - gfx::Vector2d(0, kSwipeDistance), drag_point - gfx::Vector2d(0, kSwipeDistance),
kTimeDelay, kNumSteps); kTimeDelay, kNumSteps);
RunAllPendingInMessageLoop(); base::RunLoop run_loop;
run_loop.RunUntilIdle();
EXPECT_EQ(CastSideSwipeOrigin::BOTTOM, EXPECT_EQ(CastSideSwipeOrigin::BOTTOM,
test_gesture_handler().begin_swipe_origin()); test_gesture_handler().begin_swipe_origin());
...@@ -259,7 +263,7 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromBottom) { ...@@ -259,7 +263,7 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeFromBottom) {
// Test that ignoring the gesture at its beginning will make it so the swipe // Test that ignoring the gesture at its beginning will make it so the swipe
// is not produced at the end. // is not produced at the end.
TEST_F(CastSystemGestureEventHandlerTest, SwipeUnhandledIgnored) { TEST_F(SideSwipeDetectorTest, SwipeUnhandledIgnored) {
test_gesture_handler().SetHandleSwipe(false); test_gesture_handler().SetHandleSwipe(false);
gfx::Point drag_point(root_window()->bounds().width() / 2, gfx::Point drag_point(root_window()->bounds().width() / 2,
...@@ -268,7 +272,8 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeUnhandledIgnored) { ...@@ -268,7 +272,8 @@ TEST_F(CastSystemGestureEventHandlerTest, SwipeUnhandledIgnored) {
generator.GestureScrollSequence(drag_point, generator.GestureScrollSequence(drag_point,
drag_point - gfx::Vector2d(0, kSwipeDistance), drag_point - gfx::Vector2d(0, kSwipeDistance),
kTimeDelay, kNumSteps); kTimeDelay, kNumSteps);
RunAllPendingInMessageLoop(); base::RunLoop run_loop;
run_loop.RunUntilIdle();
EXPECT_EQ(CastSideSwipeOrigin::NONE, EXPECT_EQ(CastSideSwipeOrigin::NONE,
test_gesture_handler().begin_swipe_origin()); test_gesture_handler().begin_swipe_origin());
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chromecast/graphics/triple_tap_detector.h" #include "chromecast/graphics/gestures/triple_tap_detector.h"
#include "base/auto_reset.h" #include "base/auto_reset.h"
#include "base/logging.h" #include "base/logging.h"
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROMECAST_GRAPHICS_TRIPLE_TAP_DETECTOR_H_ #ifndef CHROMECAST_GRAPHICS_GESTURES_TRIPLE_TAP_DETECTOR_H_
#define CHROMECAST_GRAPHICS_TRIPLE_TAP_DETECTOR_H_ #define CHROMECAST_GRAPHICS_GESTURES_TRIPLE_TAP_DETECTOR_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -38,6 +38,8 @@ enum class TripleTapState { ...@@ -38,6 +38,8 @@ enum class TripleTapState {
INTERVAL_WAIT, INTERVAL_WAIT,
}; };
// An event rewriter responsible for detecting triple-tap events on the root
// window.
class TripleTapDetector : public ui::EventRewriter { class TripleTapDetector : public ui::EventRewriter {
public: public:
TripleTapDetector(aura::Window* root_window, TripleTapDetector(aura::Window* root_window,
...@@ -89,4 +91,4 @@ class TripleTapDetector : public ui::EventRewriter { ...@@ -89,4 +91,4 @@ class TripleTapDetector : public ui::EventRewriter {
} // namespace chromecast } // namespace chromecast
#endif // CHROMECAST_GRAPHICS_TRIPLE_TAP_DETECTOR_H_ #endif // CHROMECAST_GRAPHICS_GESTURES_TRIPLE_TAP_DETECTOR_H_
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chromecast/graphics/triple_tap_detector.h" #include "chromecast/graphics/gestures/triple_tap_detector.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/simple_test_tick_clock.h" #include "base/test/simple_test_tick_clock.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