Commit a45859e2 authored by Aldo Culquicondor's avatar Aldo Culquicondor Committed by Commit Bot

VR: Separate gesture recognition from VrController

Bug: 847271
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_vr
Change-Id: I56edc54dcb24fd387944dc1dd937a66348ade484
Reviewed-on: https://chromium-review.googlesource.com/1077053Reviewed-by: default avatarAmirhossein Simjour <asimjour@chromium.org>
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563009}
parent 6be8acd7
This diff is collapsed.
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/android/vr/gvr_util.h" #include "chrome/browser/android/vr/gvr_util.h"
#include "chrome/browser/vr/gesture_detector.h"
#include "chrome/browser/vr/platform_controller.h" #include "chrome/browser/vr/platform_controller.h"
#include "device/vr/android/gvr/gvr_gamepad_data_provider.h" #include "device/vr/android/gvr/gvr_gamepad_data_provider.h"
#include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/vr_service.mojom.h"
...@@ -93,24 +94,6 @@ class VrController : public PlatformController { ...@@ -93,24 +94,6 @@ class VrController : public PlatformController {
bool GetRecentered() const override; bool GetRecentered() const override;
private: private:
enum GestureDetectorState {
WAITING, // waiting for user to touch down
TOUCHING, // touching the touch pad but not scrolling
SCROLLING, // scrolling on the touch pad
POST_SCROLL // scroll has finished and we are hallucinating events
};
struct TouchPoint {
gfx::Vector2dF position;
int64_t timestamp;
};
struct TouchInfo {
TouchPoint touch_point;
bool touch_up;
bool touch_down;
bool is_touching;
};
struct ButtonInfo { struct ButtonInfo {
gvr::ControllerButton button; gvr::ControllerButton button;
...@@ -120,40 +103,16 @@ class VrController : public PlatformController { ...@@ -120,40 +103,16 @@ class VrController : public PlatformController {
int64_t timestamp; int64_t timestamp;
}; };
void UpdateGestureFromTouchInfo(blink::WebGestureEvent* gesture);
void UpdateGestureWithScrollDelta(blink::WebGestureEvent* gesture);
bool GetButtonLongPressFromButtonInfo(); bool GetButtonLongPressFromButtonInfo();
void HandleWaitingState(blink::WebGestureEvent* gesture);
void HandleDetectingState(blink::WebGestureEvent* gesture);
void HandleScrollingState(blink::WebGestureEvent* gesture);
void HandlePostScrollingState(blink::WebGestureEvent* gesture);
void UpdateTouchInfo(); void UpdateTouchInfo();
// Returns true if the touch position is within the slop of the initial touch void UpdateCurrentTouchInfo();
// point, false otherwise.
bool InSlop(const gfx::Vector2dF touch_position);
// Returns true if the gesture is in horizontal direction.
bool IsHorizontalGesture();
void Reset();
void UpdateGestureParameters();
// If the user is touching the touch pad and the touch point is different from
// before, update the touch point and return true. Otherwise, return false.
bool UpdateCurrentTouchpoint();
void UpdateOverallVelocity(); void UpdateOverallVelocity();
void UpdateAlpha(); void UpdateAlpha();
// State of gesture detector.
GestureDetectorState state_;
std::unique_ptr<gvr::ControllerApi> controller_api_; std::unique_ptr<gvr::ControllerApi> controller_api_;
// The last controller state (updated once per frame). // The last controller state (updated once per frame).
...@@ -161,10 +120,10 @@ class VrController : public PlatformController { ...@@ -161,10 +120,10 @@ class VrController : public PlatformController {
std::unique_ptr<gvr::GvrApi> gvr_api_; std::unique_ptr<gvr::GvrApi> gvr_api_;
std::unique_ptr<GestureDetector> gesture_detector_;
float last_qx_; float last_qx_;
bool pinch_started_; bool pinch_started_;
bool zoom_in_progress_ = false;
bool touch_position_changed_ = false;
// TODO(https://crbug.com/824194): Remove this and associated logic once the // TODO(https://crbug.com/824194): Remove this and associated logic once the
// GVR-side bug is fixed and we don't need to keep track of click states // GVR-side bug is fixed and we don't need to keep track of click states
// ourselves. // ourselves.
...@@ -173,36 +132,14 @@ class VrController : public PlatformController { ...@@ -173,36 +132,14 @@ class VrController : public PlatformController {
// Handedness from user prefs. // Handedness from user prefs.
gvr::ControllerHandedness handedness_; gvr::ControllerHandedness handedness_;
// Current touch info after the extrapolation. // Current touch info from GVR.
std::unique_ptr<TouchInfo> touch_info_; TouchInfo touch_info_;
// A pointer storing the touch point from previous frame.
std::unique_ptr<TouchPoint> prev_touch_point_;
// A pointer storing the touch point from current frame.
std::unique_ptr<TouchPoint> cur_touch_point_;
// Initial touch point.
std::unique_ptr<TouchPoint> init_touch_point_;
// Overall velocity
gfx::Vector2dF overall_velocity_;
// Last velocity that is used for direction detection
gfx::Vector2dF last_velocity_;
// Displacement of the touch point from the previews to the current touch
gfx::Vector2dF displacement_;
// Head offset. Keeps the controller at the user's side with 6DoF headsets. // Head offset. Keeps the controller at the user's side with 6DoF headsets.
gfx::Point3F head_offset_; gfx::Point3F head_offset_;
int64_t last_touch_timestamp_ = 0;
int64_t last_timestamp_nanos_ = 0; int64_t last_timestamp_nanos_ = 0;
// Number of consecutively extrapolated touch points
int extrapolated_touch_ = 0;
float alpha_value_ = 1.0f; float alpha_value_ = 1.0f;
DISALLOW_COPY_AND_ASSIGN(VrController); DISALLOW_COPY_AND_ASSIGN(VrController);
......
...@@ -134,6 +134,8 @@ component("vr_common") { ...@@ -134,6 +134,8 @@ component("vr_common") {
"frame_lifecycle.h", "frame_lifecycle.h",
"ganesh_surface_provider.cc", "ganesh_surface_provider.cc",
"ganesh_surface_provider.h", "ganesh_surface_provider.h",
"gesture_detector.cc",
"gesture_detector.h",
"keyboard_delegate.h", "keyboard_delegate.h",
"keyboard_ui_interface.h", "keyboard_ui_interface.h",
"macros.h", "macros.h",
...@@ -304,6 +306,7 @@ test("vr_common_unittests") { ...@@ -304,6 +306,7 @@ test("vr_common_unittests") {
"elements/vector_icon_unittest.cc", "elements/vector_icon_unittest.cc",
"elements/viewport_aware_root_unittest.cc", "elements/viewport_aware_root_unittest.cc",
"fps_meter_unittest.cc", "fps_meter_unittest.cc",
"gesture_detector_unittest.cc",
"model/text_input_info_unittest.cc", "model/text_input_info_unittest.cc",
"pose_util_unittest.cc", "pose_util_unittest.cc",
"service/vr_device_manager_unittest.cc", "service/vr_device_manager_unittest.cc",
......
// 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 "chrome/browser/vr/gesture_detector.h"
#include "base/numerics/math_constants.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
namespace vr {
namespace {
constexpr float kDisplacementScaleFactor = 300.0f;
constexpr int kMaxNumOfExtrapolations = 2;
// Minimum time distance needed to call two timestamps
// not equal.
constexpr float kDelta = 1.0e-7f;
constexpr float kCutoffHz = 10.0f;
constexpr float kRC = 1.0f / (2.0f * base::kPiFloat * kCutoffHz);
// A slop represents a small rectangular region around the first touch point of
// a gesture.
// If the user does not move outside of the slop, no gesture is detected.
// Gestures start to be detected when the user moves outside of the slop.
// Vertical distance from the border to the center of slop.
constexpr float kSlopVertical = 0.165f;
// Horizontal distance from the border to the center of slop.
constexpr float kSlopHorizontal = 0.15f;
} // namespace
GestureDetector::GestureDetector() {
Reset();
}
GestureDetector::~GestureDetector() = default;
std::unique_ptr<GestureList> GestureDetector::DetectGestures(
const TouchInfo& input_touch_info,
bool force_cancel) {
touch_position_changed_ = UpdateCurrentTouchPoint(input_touch_info);
TouchInfo touch_info = input_touch_info;
ExtrapolateTouchInfo(&touch_info);
if (touch_position_changed_)
UpdateOverallVelocity(touch_info);
auto gesture_list = std::make_unique<GestureList>();
auto gesture = GetGestureFromTouchInfo(touch_info, force_cancel);
gesture->SetSourceDevice(blink::kWebGestureDeviceTouchpad);
if (gesture->GetType() == blink::WebInputEvent::kGestureScrollEnd)
Reset();
if (gesture->GetType() != blink::WebInputEvent::kUndefined)
gesture_list->push_back(std::move(gesture));
return gesture_list;
}
std::unique_ptr<blink::WebGestureEvent>
GestureDetector::GetGestureFromTouchInfo(const TouchInfo& touch_info,
bool force_cancel) {
auto gesture = std::make_unique<blink::WebGestureEvent>();
gesture->SetTimeStamp(touch_info.touch_point.timestamp);
switch (state_->label) {
// User has not put finger on touch pad.
case WAITING:
HandleWaitingState(touch_info, gesture.get());
break;
// User has not started a gesture (by moving out of slop).
case TOUCHING:
HandleDetectingState(touch_info, force_cancel, gesture.get());
break;
// User is scrolling on touchpad
case SCROLLING:
HandleScrollingState(touch_info, force_cancel, gesture.get());
break;
// The user has finished scrolling, but we'll hallucinate a few points
// before really finishing.
case POST_SCROLL:
HandlePostScrollingState(touch_info, force_cancel, gesture.get());
break;
default:
NOTREACHED();
break;
}
return gesture;
}
void GestureDetector::HandleWaitingState(const TouchInfo& touch_info,
blink::WebGestureEvent* gesture) {
// User puts finger on touch pad (or when the touch down for current gesture
// is missed, initiate gesture from current touch point).
if (touch_info.touch_down || touch_info.is_touching) {
// update initial touchpoint
state_->initial_touch_point = touch_info.touch_point;
// update current touchpoint
state_->cur_touch_point = touch_info.touch_point;
state_->label = TOUCHING;
gesture->SetType(blink::WebInputEvent::kGestureFlingCancel);
gesture->data.fling_cancel.prevent_boosting = false;
}
}
void GestureDetector::HandleDetectingState(const TouchInfo& touch_info,
bool force_cancel,
blink::WebGestureEvent* gesture) {
// User lifts up finger from touch pad.
if (touch_info.touch_up || !touch_info.is_touching) {
Reset();
return;
}
// Touch position is changed, the touch point moves outside of slop,
// and the Controller's button is not down.
if (touch_position_changed_ && touch_info.is_touching &&
!InSlop(touch_info.touch_point.position) && !force_cancel) {
state_->label = SCROLLING;
gesture->SetType(blink::WebInputEvent::kGestureScrollBegin);
UpdateGestureParameters(touch_info);
gesture->data.scroll_begin.delta_x_hint =
state_->displacement.x() * kDisplacementScaleFactor;
gesture->data.scroll_begin.delta_y_hint =
state_->displacement.y() * kDisplacementScaleFactor;
gesture->data.scroll_begin.delta_hint_units =
blink::WebGestureEvent::ScrollUnits::kPrecisePixels;
}
}
void GestureDetector::HandleScrollingState(const TouchInfo& touch_info,
bool force_cancel,
blink::WebGestureEvent* gesture) {
if (force_cancel) {
gesture->SetType(blink::WebInputEvent::kGestureScrollEnd);
UpdateGestureParameters(touch_info);
return;
}
if (touch_info.touch_up || !(touch_info.is_touching)) {
state_->label = POST_SCROLL;
}
if (touch_position_changed_) {
gesture->SetType(blink::WebInputEvent::kGestureScrollUpdate);
UpdateGestureParameters(touch_info);
UpdateGestureWithScrollDelta(gesture);
}
}
void GestureDetector::HandlePostScrollingState(
const TouchInfo& touch_info,
bool force_cancel,
blink::WebGestureEvent* gesture) {
if (extrapolated_touch_ == 0 || force_cancel) {
gesture->SetType(blink::WebInputEvent::kGestureScrollEnd);
UpdateGestureParameters(touch_info);
} else {
gesture->SetType(blink::WebInputEvent::kGestureScrollUpdate);
UpdateGestureParameters(touch_info);
UpdateGestureWithScrollDelta(gesture);
}
}
void GestureDetector::UpdateGestureWithScrollDelta(
blink::WebGestureEvent* gesture) {
gesture->data.scroll_update.delta_x =
state_->displacement.x() * kDisplacementScaleFactor;
gesture->data.scroll_update.delta_y =
state_->displacement.y() * kDisplacementScaleFactor;
}
bool GestureDetector::UpdateCurrentTouchPoint(const TouchInfo& touch_info) {
if (touch_info.is_touching || touch_info.touch_up) {
// Update the touch point when the touch position has changed.
if (state_->cur_touch_point.position != touch_info.touch_point.position) {
state_->prev_touch_point = state_->cur_touch_point;
state_->cur_touch_point = touch_info.touch_point;
return true;
}
}
return false;
}
void GestureDetector::ExtrapolateTouchInfo(TouchInfo* touch_info) {
base::TimeTicks current_timestamp = base::TimeTicks::Now();
const bool effectively_scrolling =
state_->label == SCROLLING || state_->label == POST_SCROLL;
if (effectively_scrolling && extrapolated_touch_ < kMaxNumOfExtrapolations &&
(touch_info->touch_point.timestamp == last_touch_timestamp_ ||
state_->cur_touch_point.position == state_->prev_touch_point.position)) {
extrapolated_touch_++;
touch_position_changed_ = true;
// Fill the touch_info
float duration = (current_timestamp - last_timestamp_).InSecondsF();
touch_info->touch_point.position.set_x(
state_->cur_touch_point.position.x() +
state_->overall_velocity.x() * duration);
touch_info->touch_point.position.set_y(
state_->cur_touch_point.position.y() +
state_->overall_velocity.y() * duration);
} else {
if (extrapolated_touch_ == kMaxNumOfExtrapolations) {
state_->overall_velocity = {0, 0};
}
extrapolated_touch_ = 0;
}
last_touch_timestamp_ = touch_info->touch_point.timestamp;
last_timestamp_ = current_timestamp;
}
void GestureDetector::UpdateOverallVelocity(const TouchInfo& touch_info) {
float duration =
(touch_info.touch_point.timestamp - state_->prev_touch_point.timestamp)
.InSecondsF();
// If the timestamp does not change, do not update velocity.
if (duration < kDelta)
return;
const gfx::Vector2dF& displacement =
touch_info.touch_point.position - state_->prev_touch_point.position;
const gfx::Vector2dF& velocity = ScaleVector2d(displacement, (1 / duration));
float weight = duration / (kRC + duration);
state_->overall_velocity =
ScaleVector2d(state_->overall_velocity, (1 - weight)) +
ScaleVector2d(velocity, weight);
}
void GestureDetector::UpdateGestureParameters(const TouchInfo& touch_info) {
state_->displacement =
touch_info.touch_point.position - state_->prev_touch_point.position;
}
bool GestureDetector::InSlop(const gfx::Vector2dF touch_position) const {
return (std::abs(touch_position.x() -
state_->initial_touch_point.position.x()) <
kSlopHorizontal) &&
(std::abs(touch_position.y() -
state_->initial_touch_point.position.y()) < kSlopVertical);
}
void GestureDetector::Reset() {
state_ = std::make_unique<GestureDetectorState>();
}
} // namespace vr
// 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 CHROME_BROWSER_VR_GESTURE_DETECTOR_H_
#define CHROME_BROWSER_VR_GESTURE_DETECTOR_H_
#include "base/macros.h"
#include "base/time/time.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace blink {
class WebGestureEvent;
}
namespace vr {
using GestureList = std::vector<std::unique_ptr<blink::WebGestureEvent>>;
struct TouchPoint {
gfx::Vector2dF position;
base::TimeTicks timestamp;
};
struct TouchInfo {
TouchPoint touch_point;
bool touch_up;
bool touch_down;
bool is_touching;
};
class GestureDetector {
public:
GestureDetector();
virtual ~GestureDetector();
std::unique_ptr<GestureList> DetectGestures(const TouchInfo& touch_info,
bool force_cancel);
private:
enum GestureDetectorStateLabel {
WAITING, // waiting for user to touch down
TOUCHING, // touching the touch pad but not scrolling
SCROLLING, // scrolling on the touch pad
POST_SCROLL // scroll has finished and we are hallucinating events
};
struct GestureDetectorState {
GestureDetectorStateLabel label = WAITING;
TouchPoint prev_touch_point;
TouchPoint cur_touch_point;
TouchPoint initial_touch_point;
gfx::Vector2dF overall_velocity;
// Displacement of the touch point from the previews to the current touch
gfx::Vector2dF displacement;
};
std::unique_ptr<blink::WebGestureEvent> GetGestureFromTouchInfo(
const TouchInfo& input_touch_info,
bool force_cancel);
void HandleWaitingState(const TouchInfo& touch_info,
blink::WebGestureEvent* gesture);
void HandleDetectingState(const TouchInfo& touch_info,
bool force_cancel,
blink::WebGestureEvent* gesture);
void HandleScrollingState(const TouchInfo& touch_info,
bool force_cancel,
blink::WebGestureEvent* gesture);
void HandlePostScrollingState(const TouchInfo& touch_info,
bool force_cancel,
blink::WebGestureEvent* gesture);
void UpdateGestureWithScrollDelta(blink::WebGestureEvent* gesture);
// If the user is touching the touch pad and the touch point is different from
// before, update the touch point and return true. Otherwise, return false.
bool UpdateCurrentTouchPoint(const TouchInfo& touch_info);
void ExtrapolateTouchInfo(TouchInfo* touch_info);
void UpdateOverallVelocity(const TouchInfo& touch_info);
void UpdateGestureParameters(const TouchInfo& touch_info);
bool InSlop(const gfx::Vector2dF touch_position) const;
void Reset();
std::unique_ptr<GestureDetectorState> state_;
// Number of consecutively extrapolated touch points
int extrapolated_touch_ = 0;
base::TimeTicks last_touch_timestamp_;
base::TimeTicks last_timestamp_;
bool touch_position_changed_;
DISALLOW_COPY_AND_ASSIGN(GestureDetector);
};
} // namespace vr
#endif // CHROME_BROWSER_VR_GESTURE_DETECTOR_H_
// 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 "chrome/browser/vr/gesture_detector.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
namespace {
constexpr float kDelta = 0.001f;
}
namespace vr {
TEST(GestureDetector, NotTouching) {
GestureDetector detector;
TouchInfo touch_info{
.touch_up = false, .touch_down = false, .is_touching = false};
auto gestures = detector.DetectGestures(touch_info, false);
EXPECT_TRUE(gestures->empty());
}
TEST(GestureDetector, StartTouchWithoutMoving) {
GestureDetector detector;
base::TimeTicks timestamp;
TouchInfo touch_info{
.touch_point = {.position = {0, 0}, .timestamp = timestamp},
.touch_up = false,
.touch_down = true,
.is_touching = true,
};
auto gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureFlingCancel);
// A small move doesn't trigger scrolling yet.
timestamp += base::TimeDelta::FromMilliseconds(1);
touch_info = TouchInfo{
.touch_point = {.position = {kDelta, kDelta}, .timestamp = timestamp},
.touch_up = false,
.touch_down = true,
.is_touching = true,
};
gestures = detector.DetectGestures(touch_info, false);
EXPECT_TRUE(gestures->empty());
}
TEST(GestureDetector, StartTouchMoveAndRelease) {
GestureDetector detector;
base::TimeTicks timestamp;
TouchInfo touch_info{
.touch_point = {.position = {0.0f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = true,
.is_touching = true,
};
detector.DetectGestures(touch_info, false);
// Move to the right.
timestamp += base::TimeDelta::FromMilliseconds(1);
touch_info = TouchInfo{
.touch_point = {.position = {0.3f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = false,
.is_touching = true,
};
auto gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollBegin);
auto* gesture = gestures->front().get();
EXPECT_GT(gesture->data.scroll_update.delta_x, 0.0f);
EXPECT_EQ(gesture->data.scroll_update.delta_y, 0.0f);
// Move slightly up.
timestamp += base::TimeDelta::FromMilliseconds(1);
touch_info = TouchInfo{
.touch_point = {.position = {0.3f, 0.01f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = false,
.is_touching = true,
};
gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollUpdate);
gesture = gestures->front().get();
EXPECT_EQ(gesture->data.scroll_update.delta_x, 0.0f);
EXPECT_GT(gesture->data.scroll_update.delta_y, 0.0f);
// Release touch. Scroll is extrapolated for 2 frames.
touch_info.touch_up = true;
touch_info.is_touching = false;
gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollUpdate);
gesture = gestures->front().get();
EXPECT_GT(gesture->data.scroll_update.delta_x, 0.0f);
EXPECT_GT(gesture->data.scroll_update.delta_y, 0.0f);
touch_info.touch_up = false;
gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollUpdate);
gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollEnd);
}
TEST(GestureDetector, CancelDuringScrolling) {
GestureDetector detector;
base::TimeTicks timestamp;
TouchInfo touch_info{
.touch_point = {.position = {0.0f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = true,
.is_touching = true,
};
detector.DetectGestures(touch_info, false);
// Move to the right.
timestamp += base::TimeDelta::FromMilliseconds(1);
touch_info = TouchInfo{
.touch_point = {.position = {0.3f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = false,
.is_touching = true,
};
auto gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollBegin);
// Cancel.
gestures = detector.DetectGestures(touch_info, true);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollEnd);
}
TEST(GestureDetector, CancelDuringPostScrolling) {
GestureDetector detector;
base::TimeTicks timestamp;
TouchInfo touch_info{
.touch_point = {.position = {0.0f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = true,
.is_touching = true,
};
detector.DetectGestures(touch_info, false);
// Move to the right.
timestamp += base::TimeDelta::FromMilliseconds(1);
touch_info = TouchInfo{
.touch_point = {.position = {0.3f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = false,
.is_touching = true,
};
auto gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollBegin);
// Release touch. We should see extrapolated scrolling.
touch_info.touch_up = true;
touch_info.is_touching = false;
gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollUpdate);
// Cancel.
touch_info.touch_up = false;
gestures = detector.DetectGestures(touch_info, true);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollEnd);
}
TEST(GestureDetector, CancelAndTouchDuringPostScrolling) {
GestureDetector detector;
base::TimeTicks timestamp;
TouchInfo touch_info{
.touch_point = {.position = {0.0f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = true,
.is_touching = true,
};
detector.DetectGestures(touch_info, false);
// Move to the right.
timestamp += base::TimeDelta::FromMilliseconds(1);
touch_info = TouchInfo{
.touch_point = {.position = {0.3f, 0.0f}, .timestamp = timestamp},
.touch_up = false,
.touch_down = false,
.is_touching = true,
};
auto gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollBegin);
// Release touch. We should see extrapolated scrolling.
touch_info.touch_up = true;
touch_info.is_touching = false;
gestures = detector.DetectGestures(touch_info, false);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollUpdate);
// Cancel and touch.
touch_info.touch_up = false;
touch_info.touch_down = true;
touch_info.is_touching = true;
gestures = detector.DetectGestures(touch_info, true);
EXPECT_EQ(gestures->front()->GetType(),
blink::WebInputEvent::kGestureScrollEnd);
}
} // namespace vr
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