blob: bd7b0532d151223999d92606390c007f0eb5f8d8 [file] [log] [blame]
// Copyright 2018 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 <utility>
#include <fuchsia/accessibility/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include "garnet/bin/a11y/talkback/gesture_detector.h"
#include "garnet/bin/a11y/tests/mocks/mock_gesture_listener.h"
#include "garnet/bin/a11y/tests/mocks/mock_touch_dispatcher.h"
#include "gtest/gtest.h"
#include "lib/component/cpp/startup_context.h"
#include "lib/component/cpp/testing/test_with_context.h"
namespace talkback_test {
// Unit tests for garnet/bin/a11y/talkback/gesture_detector.h
class GestureDetectorTest : public component::testing::TestWithContext {
public:
void SetUp() override {
TestWithContext::SetUp();
controller().AddService<fuchsia::accessibility::TouchDispatcher>(
[this](fidl::InterfaceRequest<fuchsia::accessibility::TouchDispatcher>
request) { touch_dispatcher_.Bind(std::move(request)); });
context_ = TakeContext();
detector_ =
std::make_unique<talkback::GestureDetector>(context_.get(), &listener_);
RunLoopUntilIdle();
}
accessibility_test::MockTouchDispatcher touch_dispatcher_;
MockGestureListener listener_;
private:
std::unique_ptr<component::StartupContext> context_;
std::unique_ptr<talkback::GestureDetector> detector_;
};
TEST_F(GestureDetectorTest, TapTest) {
uint32_t gesture_count = 0;
listener_.SetCallback([&gesture_count](Gesture gesture) {
EXPECT_EQ(gesture, Gesture::kTap);
gesture_count++;
});
// Touch down
fuchsia::ui::input::PointerEvent touch;
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::DOWN;
touch.event_time = 0;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch move
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = 100;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch up
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::UP;
touch.event_time = 200;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Wait until tap is registered after delay
RunLoopFor(zx::msec(200));
EXPECT_EQ(1u, gesture_count);
}
TEST_F(GestureDetectorTest, DoubleTapTest) {
uint32_t gesture_count = 0;
listener_.SetCallback([&gesture_count](Gesture gesture) {
EXPECT_EQ(gesture, Gesture::kDoubleTap);
gesture_count++;
});
// Touch down
fuchsia::ui::input::PointerEvent touch;
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::DOWN;
touch.event_time = 0;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch move
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = 100;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch up
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::UP;
touch.event_time = 200;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Second touch down
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::DOWN;
touch.event_time = 300;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Second touch move
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = 400;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Second touch up
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::UP;
touch.event_time = 500;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Make sure a delayed tap does not happen because a double tap
// was registered.
RunLoopFor(zx::msec(200));
EXPECT_EQ(1u, gesture_count);
}
TEST_F(GestureDetectorTest, MoveTest) {
uint32_t gesture_count = 0;
listener_.SetCallback([&gesture_count](Gesture gesture) {
// Talkback needs to do a query from a11y manager on a move.
EXPECT_EQ(gesture, Gesture::kMove);
gesture_count++;
});
// Touch down
fuchsia::ui::input::PointerEvent touch;
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::DOWN;
touch.event_time = 0;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch move after 100 ns; a touch move should not register.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = 100;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch move after 130 ms; a touch move should register.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = (uint64_t)zx::msec(130).to_nsecs();
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch move after 140 ms; a touch move should not register.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = (uint64_t)zx::msec(140).to_nsecs();
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Touch move after 150 ms; a touch move should register.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = (uint64_t)zx::msec(150).to_nsecs();
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
RunLoopUntilIdle();
EXPECT_EQ(2u, gesture_count);
}
TEST_F(GestureDetectorTest, TwoFingerTest) {
uint32_t simulated_touch_count = 0;
// Finger #1 pointer_id = 0; finger #2 pointer_id = 1;
touch_dispatcher_.callback_ =
[&simulated_touch_count](fuchsia::ui::input::PointerEvent event) {
// We simulate events for finger #1 back to touch dispatcher.
EXPECT_EQ(0u, event.pointer_id);
simulated_touch_count++;
};
// Finger #1 touch down;
fuchsia::ui::input::PointerEvent touch;
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::DOWN;
touch.event_time = 0;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Finger #2 touch down; simulated ADD/DOWN events fired.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::DOWN;
touch.event_time = 100;
touch.pointer_id = 1;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Finger #1 move; simulated MOVE event.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = 200;
touch.pointer_id = 0;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Finger #2 move; simulated MOVE event.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::MOVE;
touch.event_time = 300;
touch.pointer_id = 1;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
// Second finger lift up; simulated UP/REMOVE events.
touch.type = fuchsia::ui::input::PointerEventType::TOUCH;
touch.phase = fuchsia::ui::input::PointerEventPhase::UP;
touch.event_time = 400;
touch.pointer_id = 1;
touch_dispatcher_.SendPointerEventToClient(std::move(touch));
RunLoopUntilIdle();
// Expect 5 simulated events, touch ADD, DOWN, MOVE, UP, REMOVE
EXPECT_EQ(5u, simulated_touch_count);
}
} // namespace talkback_test