blob: 32bf9d4c4f87f06475b34415b6303824cb0d06f2 [file] [log] [blame]
// Copyright 2021 The Fuchsia 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 <lib/stdcompat/source_location.h>
#include <lib/syslog/cpp/macros.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "src/ui/a11y/lib/gesture_manager/tests/mocks/mock_gesture_handler.h"
#include "src/ui/a11y/lib/magnifier/magnifier_2.h"
namespace accessibility_test {
namespace {
using GestureType = a11y::GestureHandlerV2::GestureType;
using testing::ElementsAre;
/// Returns a string describing the provided source location.
static std::string ToString(const cpp20::source_location& location) {
std::string line = std::to_string(location.line());
return "line " + line;
}
class MockMagnifierDelegate : public a11y::Magnifier2::Delegate {
public:
MockMagnifierDelegate() = default;
~MockMagnifierDelegate() override = default;
void SetMagnificationTransform(float scale, float x, float y,
SetMagnificationTransformCallback callback) override {
scale_ = scale;
x_ = x;
y_ = y;
callback();
}
float scale() { return scale_; }
float x() { return x_; }
float y() { return y_; }
private:
// Current state of the transform.
float scale_ = 1.f;
float x_ = 0.f;
float y_ = 0.f;
};
class Magnifier2Test : public ::testing::Test {
public:
Magnifier2Test() = default;
~Magnifier2Test() override = default;
a11y::Magnifier2* magnifier() { return magnifier_.get(); }
MockMagnifierDelegate* mock_magnifier_delegate() { return mock_magnifier_delegate_; }
MockGestureHandlerV2* mock_gesture_handler() { return mock_gesture_handler_.get(); }
void SetUp() override {
mock_gesture_handler_ = std::make_unique<MockGestureHandlerV2>();
auto mock_magnifier_delegate = std::make_unique<MockMagnifierDelegate>();
mock_magnifier_delegate_ = mock_magnifier_delegate.get();
magnifier_ = std::make_unique<a11y::Magnifier2>(std::move(mock_magnifier_delegate));
magnifier_->BindGestures(mock_gesture_handler_.get());
}
void ExpectThatTransformIs(
float x, float y, float scale,
const cpp20::source_location caller = cpp20::source_location::current()) {
auto true_x = mock_magnifier_delegate_->x();
auto true_y = mock_magnifier_delegate_->y();
auto true_scale = mock_magnifier_delegate_->scale();
FX_LOGS(INFO) << "true_x: " << true_x << " true_y: " << true_y << " true_scale: " << true_scale;
FX_LOGS(INFO) << "expected_x: " << x << " expected_y: " << y << " expected_scale: " << scale;
FX_LOGS(INFO) << "Difference: " << std::abs(true_x - x) << " " << std::abs(true_y - y) << " "
<< std::abs(true_scale - scale) << " epsilon "
<< scale * std::numeric_limits<float>::epsilon();
EXPECT_FLOAT_EQ(mock_magnifier_delegate_->x(), x) << " from " << ToString(caller);
EXPECT_FLOAT_EQ(mock_magnifier_delegate_->y(), y) << " from " << ToString(caller);
EXPECT_FLOAT_EQ(mock_magnifier_delegate_->scale(), scale) << " from " << ToString(caller);
}
private:
std::unique_ptr<MockGestureHandlerV2> mock_gesture_handler_;
std::unique_ptr<a11y::Magnifier2> magnifier_;
// Owned by magnifier_.
MockMagnifierDelegate* mock_magnifier_delegate_;
};
TEST_F(Magnifier2Test, RegisterHandler) {
EXPECT_EQ(mock_magnifier_delegate()->x(), 0.f);
EXPECT_EQ(mock_magnifier_delegate()->y(), 0.f);
EXPECT_EQ(mock_magnifier_delegate()->scale(), 1.f);
}
TEST_F(Magnifier2Test, GestureHandlersAreRegisteredIntheRightOrder) {
// The order in which magnifier gestures are registered is relevant.
EXPECT_THAT(mock_gesture_handler()->bound_gestures(),
ElementsAre(GestureType::kOneFingerTripleTap, GestureType::kThreeFingerDoubleTap,
GestureType::kOneFingerTripleTapDrag,
GestureType::kThreeFingerDoubleTapDrag, GestureType::kTwoFingerDrag));
}
TEST_F(Magnifier2Test, OneFingerTripleTapTogglesMagnification) {
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.5f;
mock_gesture_handler()->TriggerGesture(GestureType::kOneFingerTripleTap, gesture_context);
ExpectThatTransformIs(-.4f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.5f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
mock_gesture_handler()->TriggerGesture(GestureType::kOneFingerTripleTap);
ExpectThatTransformIs(0 /* x */, 0 /* y */, 1 /* scale */);
}
TEST_F(Magnifier2Test, ThreeFingerDoubleTapTogglesMagnification) {
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.3f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.4f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.5f;
gesture_context.current_pointer_locations[3].ndc_point.x = 0.5f;
gesture_context.current_pointer_locations[3].ndc_point.y = 0.6f;
mock_gesture_handler()->TriggerGesture(GestureType::kThreeFingerDoubleTap, gesture_context);
ExpectThatTransformIs(-.4f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.5f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
mock_gesture_handler()->TriggerGesture(GestureType::kThreeFingerDoubleTap);
ExpectThatTransformIs(0 /* x */, 0 /* y */, 1 /* scale */);
}
TEST_F(Magnifier2Test, ThreeFingerDoubleTapDragTogglesTemporaryMagnification) {
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.3f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.4f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.5f;
gesture_context.current_pointer_locations[3].ndc_point.x = 0.5f;
gesture_context.current_pointer_locations[3].ndc_point.y = 0.6f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kThreeFingerDoubleTapDrag,
gesture_context);
ExpectThatTransformIs(-.4f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.5f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.1f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.2f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.2f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.3f;
gesture_context.current_pointer_locations[3].ndc_point.x = 0.3f;
gesture_context.current_pointer_locations[3].ndc_point.y = 0.4f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kThreeFingerDoubleTapDrag,
gesture_context);
ExpectThatTransformIs(-.2f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.3f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
mock_gesture_handler()->TriggerGestureComplete(GestureType::kThreeFingerDoubleTapDrag);
ExpectThatTransformIs(0 /* x */, 0 /* y */, 1 /* scale */);
}
TEST_F(Magnifier2Test, OneFingerTripleTapDragTogglesTemporaryMagnification) {
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.3f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.4f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kOneFingerTripleTapDrag,
gesture_context);
ExpectThatTransformIs(-.3f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.4f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.1f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.2f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kOneFingerTripleTapDrag,
gesture_context);
ExpectThatTransformIs(-.1f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.2f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
mock_gesture_handler()->TriggerGestureComplete(GestureType::kOneFingerTripleTapDrag);
ExpectThatTransformIs(0 /* x */, 0 /* y */, 1 /* scale */);
}
TEST_F(Magnifier2Test, TwoFingerDrag) {
// One-finger-triple-tap to enter persistent magnification mode.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.5f;
mock_gesture_handler()->TriggerGesture(GestureType::kOneFingerTripleTap, gesture_context);
ExpectThatTransformIs(-.4f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.5f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
// Begin two-finger drag at a point different from the current magnification
// focus to ensure that the transform does not change. Note that the fingers
// are placed far enough apart to exceed kZoomMinFingerDistance.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.22f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.22f;
gesture_context.current_pointer_locations[2].ndc_point.x = -0.22f;
gesture_context.current_pointer_locations[2].ndc_point.y = -0.22f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(-.4f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.5f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
// Scale.
{
a11y::gesture_util_v2::GestureContext gesture_context;
// Double average distance between the fingers and the centroid,
// while keeping the centroid fixed.
gesture_context.current_pointer_locations[1].ndc_point.x = 0.44f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.44f;
gesture_context.current_pointer_locations[2].ndc_point.x = -0.44f;
gesture_context.current_pointer_locations[2].ndc_point.y = -0.44f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
// The average distance between the fingers and the centroid doubled, so the
// scale should double. The translation should be scaled accordingly.
ExpectThatTransformIs(-2.4f, // x translation from above, simplified, and scaled 2x
-3.0f, // y translation from above, simplified, and scaled 2x
a11y::Magnifier2::kDefaultScale * 2);
}
// Pan horizontally.
{
a11y::gesture_util_v2::GestureContext gesture_context;
// Translate the centroid from (0, 0) to (-.1, 0).
gesture_context.current_pointer_locations[1].ndc_point.x = 0.34f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.44f;
gesture_context.current_pointer_locations[2].ndc_point.x = -0.54f;
gesture_context.current_pointer_locations[2].ndc_point.y = -0.44f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(-2.5f, // x translation from above, plus offset
-3.0f, // y translation from above
8.0f // scale from above, simplified
);
}
// Pan vertically.
{
a11y::gesture_util_v2::GestureContext gesture_context;
// Translate the centroid from (-.1, 0) to (-.1, -.1).
gesture_context.current_pointer_locations[1].ndc_point.x = 0.34f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.34f;
gesture_context.current_pointer_locations[2].ndc_point.x = -0.54f;
gesture_context.current_pointer_locations[2].ndc_point.y = -0.54f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(-2.5f, // x translation from above
-3.1f, // y translation from above, plus offset
8.0f // scale from above, simplified
);
}
// Intentional simultaneous pan and zoom.
{
a11y::gesture_util_v2::GestureContext gesture_context;
// Translate the centroid from (-.1, -.1) to (.1, .1), while zooming
// out 2x.
gesture_context.current_pointer_locations[1].ndc_point.x = 0.32f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.32f;
gesture_context.current_pointer_locations[2].ndc_point.x = -0.12f;
gesture_context.current_pointer_locations[2].ndc_point.y = -0.12f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
// Consider the pixel directly underneath the midpoint ("centroid") of the
// user's two fingers. As the centroid of the fingers moves, we want to
// maintain that the same pixel remains under the centroid.
//
// To do so, we
// 1. Start with the location of the previous centroid in the current
// coordinate system.
// 2. Reverse the current transformation, to determine the location of
// the same pixel in the original image.
// 3. Find a transform that will scale and translate the same pixel in
// the original image to the new centroid. Note that the scale is
// determined by the distance traveled by the fingers. We just solve
// for translation.
//
// Numerically:
// 1) Previous centroid was a (-.1, -.1)
// 2a) Previous transformation was |p' = 8p - (2.5, 3.1)|
// 2b) Reverse transform is |p = (p' + (2.5, 3.1)) / 8|
// 2c) Combing 1) and 2b), the centroid (-.1, -.1) represents original
// image pixel |(2.4, 3.0) / 8|, which simplifies to (0.3, 0.375)
// 3a) New transform is |p' = 4p + (dx, dy)|. (The distance between fingers decreased
// by half, so the new scale is half the old scale.)
// 3b) New transform must map (0.3, 0.375) to (.1, .1)
// 3c) Combining 3a) and 3b),
// |(.1, .1) = 4 * (0.3, 0.375) + (dx, dy)|
// => |(.1, .1) = (1.2, 1.5) + (dx, dy)|
// => |(-1.1, -1.4) = (dx, dy)|
ExpectThatTransformIs(-1.1f, // x translation computed in 3c
-1.4f, // y translation computed in 3c
4.0f // previous scale, zoomed out 2x
);
}
// Accidental simultaneous pan and zoom. Only the pan should be applied.
{
// End the previous drag, so that we can start a new drag with a
// chosen inter-finger distance.
a11y::gesture_util_v2::GestureContext gesture_context;
mock_gesture_handler()->TriggerGestureComplete(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(-1.1f, -1.4f, 4.0f); // previous transform
// Place two fingers on the screen, less than |kZoomMinFingerDistance| apart.
// Placing the fingers shouldn't adjust the transform.
gesture_context.current_pointer_locations[1].ndc_point.x = 0.0f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.0f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.2f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.2f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(-1.1f, -1.4f, 4.0f); // previous transform
// Move the fingers apart while also translating the centroid.
// Because the initial distance was small, this should just adjust
// the translation, and not the scale.
gesture_context.current_pointer_locations[1].ndc_point.x = 0.0f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.0f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.6f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.6f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(
-1.1f + 0.2f, // previous x translation, translated by (0.6-0.0)/2 - (0.2-0.0)/2
-1.4f + 0.2f, // previous y translation, translated by (0.6-0.0)/2 - (0.2-0.0)/2
4.0f // previous scale
);
}
}
TEST_F(Magnifier2Test, ZoomOutIfMagnified) {
// Magnify to some non-trivial transform state.
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.5f;
mock_gesture_handler()->TriggerGesture(GestureType::kOneFingerTripleTap, gesture_context);
ExpectThatTransformIs(-.4f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.5f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
// Call ZoomOutIfMagnified() to ensure that we return to "normal" zoom state.
magnifier()->ZoomOutIfMagnified();
ExpectThatTransformIs(0 /* x */, 0 /* y */, 1 /* scale */);
}
TEST_F(Magnifier2Test, ClampPan) {
// One-finger-triple-tap to enter persistent magnification mode.
// Focus on the top-right corner of the screen.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 1.f;
gesture_context.current_pointer_locations[1].ndc_point.y = 1.f;
mock_gesture_handler()->TriggerGesture(GestureType::kOneFingerTripleTap, gesture_context);
ExpectThatTransformIs(-1.f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-1.f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
// Begin a two-finger drag.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 1.f;
gesture_context.current_pointer_locations[1].ndc_point.y = 1.f;
gesture_context.current_pointer_locations[2].ndc_point.x = .9f;
gesture_context.current_pointer_locations[2].ndc_point.y = .9f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kTwoFingerDrag, gesture_context);
}
// Drag down and to the left. Since the focus is already on the top right
// corner, this gesture should have no effect on the transform.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.1f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.1f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.0f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.0f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(-1.f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-1.f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
}
TEST_F(Magnifier2Test, ClampZoom) {
// One-finger-triple-tap to enter persistent magnification mode.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0;
gesture_context.current_pointer_locations[1].ndc_point.y = 0;
mock_gesture_handler()->TriggerGesture(GestureType::kOneFingerTripleTap, gesture_context);
ExpectThatTransformIs(0 /* x */, 0 /* y */, a11y::Magnifier2::kDefaultScale);
}
// Begin a two-finger drag with fingers just far enough part to
// exceed |kZoonMinFingerDistance| of 0.3. Said differently,
// the value 0.22 for each coordinate is chosen so that
// sqrt((x1-x2)^2 + (y1-y2)^2)/2 > |kZoomFingerFingerDistance|.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = .22f;
gesture_context.current_pointer_locations[1].ndc_point.y = .22f;
gesture_context.current_pointer_locations[2].ndc_point.x = -.22f;
gesture_context.current_pointer_locations[2].ndc_point.y = -.22f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kTwoFingerDrag, gesture_context);
}
// Spread fingers as far apart as possible. This should increase
// the scale, but isn't far enough to exercise clamping.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 1.f;
gesture_context.current_pointer_locations[1].ndc_point.y = 1.f;
gesture_context.current_pointer_locations[2].ndc_point.x = -1.f;
gesture_context.current_pointer_locations[2].ndc_point.y = -1.f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
EXPECT_GT(mock_magnifier_delegate()->scale(), a11y::Magnifier2::kDefaultScale);
EXPECT_GT(mock_magnifier_delegate()->scale(), 18.0f);
EXPECT_LT(mock_magnifier_delegate()->scale(), a11y::Magnifier2::kMaxScale);
}
// Begin a two-finger drag with fingers just far enough part to
// exceed |kZoonMinFingerDistance| of 0.3. Said differently,
// the value 0.22 for each coordinate is chosen so that
// sqrt((x1-x2)^2 + (y1-y2)^2)/2 > |kZoomFingerFingerDistance|.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = .22f;
gesture_context.current_pointer_locations[1].ndc_point.y = .22f;
gesture_context.current_pointer_locations[2].ndc_point.x = -.22f;
gesture_context.current_pointer_locations[2].ndc_point.y = -.22f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kTwoFingerDrag, gesture_context);
}
// Spread fingers as far apart as possible. This should increase
// the scale and exercise clamping. Unclamped, the scale would be
// more than 18.0 * 18.0. (See previous |EXPECT_GT|.)
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 1.f;
gesture_context.current_pointer_locations[1].ndc_point.y = 1.f;
gesture_context.current_pointer_locations[2].ndc_point.x = -1.f;
gesture_context.current_pointer_locations[2].ndc_point.y = -1.f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(0 /* x */, 0 /* x */, a11y::Magnifier2::kMaxScale);
}
}
TEST_F(Magnifier2Test, TwoFingerDragOnlyWorksInPersistentMode) {
// The magnifier should only respond to two-finger drags when in PERSISTENT
// mode, so the magnification transform should not change during this test
// case.
//
// Begin two-finger drag at a point different from the current magnification
// focus to ensure that the transform does not change.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.2f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.3f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.5f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(0 /* x */, 0 /* x */, 1.f);
}
// Try to scale and pan, and again, verify that the transform does not change.
{
a11y::gesture_util_v2::GestureContext gesture_context;
// Double average distance between the fingers and the centroid, and
// translate the centroid from (.3, .4) to (.2, .3).
gesture_context.current_pointer_locations[1].ndc_point.x = 0.0f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.1f;
gesture_context.current_pointer_locations[2].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[2].ndc_point.y = 0.5f;
mock_gesture_handler()->TriggerGestureUpdate(GestureType::kTwoFingerDrag, gesture_context);
ExpectThatTransformIs(0 /* x */, 0 /* x */, 1.f);
}
}
TEST_F(Magnifier2Test, TapDragOnlyWorksInUnmagnifiedMode) {
// The magnifier should not respond to tap-drag gestures when in PERSISTENT
// mode, so the magnification transform should not change during this test
// case.
//
// Enter PERSISTENT mode with a one-finger-triple-tap.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.4f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.5f;
mock_gesture_handler()->TriggerGesture(GestureType::kOneFingerTripleTap, gesture_context);
ExpectThatTransformIs(-.4f * (a11y::Magnifier2::kDefaultScale - 1), // x translation
-.5f * (a11y::Magnifier2::kDefaultScale - 1), // y translation
a11y::Magnifier2::kDefaultScale);
}
// Attempt a one-finger-triple-tap-drag at a different location. The
// magnifier should ignore the gesture, so the transform should not change.
{
a11y::gesture_util_v2::GestureContext gesture_context;
gesture_context.current_pointer_locations[1].ndc_point.x = 0.3f;
gesture_context.current_pointer_locations[1].ndc_point.y = 0.4f;
mock_gesture_handler()->TriggerGestureRecognize(GestureType::kOneFingerTripleTapDrag,
gesture_context);
// Check that the translation has not changed. X and Y translations are
// updated together, so checking one of them is sufficient.
EXPECT_LT(std::abs(mock_magnifier_delegate()->x() - (-1.2f)),
a11y::Magnifier2::kDefaultScale * std::numeric_limits<float>::epsilon());
}
}
} // namespace
} // namespace accessibility_test