blob: bc858334e856bb0c1be7d935acf696103ac23e78 [file] [log] [blame]
// Copyright 2013 The Flutter 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 "flutter/lib/ui/window/pointer_data_packet_converter.h"
#include <cstring>
#include "gtest/gtest.h"
namespace flutter {
namespace testing {
void CreateSimulatedPointerData(PointerData& data, // NOLINT
PointerData::Change change,
int64_t device,
double dx,
double dy,
int64_t buttons) {
data.time_stamp = 0;
data.change = change;
data.kind = PointerData::DeviceKind::kTouch;
data.signal_kind = PointerData::SignalKind::kNone;
data.device = device;
data.pointer_identifier = 0;
data.physical_x = dx;
data.physical_y = dy;
data.physical_delta_x = 0.0;
data.physical_delta_y = 0.0;
data.buttons = buttons;
data.obscured = 0;
data.synthesized = 0;
data.pressure = 0.0;
data.pressure_min = 0.0;
data.pressure_max = 0.0;
data.distance = 0.0;
data.distance_max = 0.0;
data.size = 0.0;
data.radius_major = 0.0;
data.radius_minor = 0.0;
data.radius_min = 0.0;
data.radius_max = 0.0;
data.orientation = 0.0;
data.tilt = 0.0;
data.platformData = 0;
data.scroll_delta_x = 0.0;
data.scroll_delta_y = 0.0;
}
void CreateSimulatedMousePointerData(PointerData& data, // NOLINT
PointerData::Change change,
PointerData::SignalKind signal_kind,
int64_t device,
double dx,
double dy,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons) {
data.time_stamp = 0;
data.change = change;
data.kind = PointerData::DeviceKind::kMouse;
data.signal_kind = signal_kind;
data.device = device;
data.pointer_identifier = 0;
data.physical_x = dx;
data.physical_y = dy;
data.physical_delta_x = 0.0;
data.physical_delta_y = 0.0;
data.buttons = buttons;
data.obscured = 0;
data.synthesized = 0;
data.pressure = 0.0;
data.pressure_min = 0.0;
data.pressure_max = 0.0;
data.distance = 0.0;
data.distance_max = 0.0;
data.size = 0.0;
data.radius_major = 0.0;
data.radius_minor = 0.0;
data.radius_min = 0.0;
data.radius_max = 0.0;
data.orientation = 0.0;
data.tilt = 0.0;
data.platformData = 0;
data.scroll_delta_x = scroll_delta_x;
data.scroll_delta_y = scroll_delta_y;
}
void CreateSimulatedTrackpadGestureData(PointerData& data, // NOLINT
PointerData::Change change,
int64_t device,
double dx,
double dy,
double pan_x,
double pan_y,
double scale,
double rotation) {
data.time_stamp = 0;
data.change = change;
data.kind = PointerData::DeviceKind::kMouse;
data.signal_kind = PointerData::SignalKind::kNone;
data.device = device;
data.pointer_identifier = 0;
data.physical_x = dx;
data.physical_y = dy;
data.physical_delta_x = 0.0;
data.physical_delta_y = 0.0;
data.buttons = 0;
data.obscured = 0;
data.synthesized = 0;
data.pressure = 0.0;
data.pressure_min = 0.0;
data.pressure_max = 0.0;
data.distance = 0.0;
data.distance_max = 0.0;
data.size = 0.0;
data.radius_major = 0.0;
data.radius_minor = 0.0;
data.radius_min = 0.0;
data.radius_max = 0.0;
data.orientation = 0.0;
data.tilt = 0.0;
data.platformData = 0;
data.scroll_delta_x = 0.0;
data.scroll_delta_y = 0.0;
data.pan_x = pan_x;
data.pan_y = pan_y;
data.pan_delta_x = 0.0;
data.pan_delta_y = 0.0;
data.scale = scale;
data.rotation = rotation;
}
void UnpackPointerPacket(std::vector<PointerData>& output, // NOLINT
std::unique_ptr<PointerDataPacket> packet) {
size_t kBytesPerPointerData = kPointerDataFieldCount * kBytesPerField;
auto buffer = packet->data();
size_t buffer_length = buffer.size();
for (size_t i = 0; i < buffer_length / kBytesPerPointerData; i++) {
PointerData pointer_data;
memcpy(&pointer_data, &buffer[i * kBytesPerPointerData],
sizeof(PointerData));
output.push_back(pointer_data);
}
packet.reset();
}
TEST(PointerDataPacketConverterTest, CanConvetPointerDataPacket) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(6);
PointerData data;
CreateSimulatedPointerData(data, PointerData::Change::kAdd, 0, 0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedPointerData(data, PointerData::Change::kHover, 0, 3.0, 0.0, 0);
packet->SetPointerData(1, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 3.0, 0.0, 1);
packet->SetPointerData(2, data);
CreateSimulatedPointerData(data, PointerData::Change::kMove, 0, 3.0, 4.0, 1);
packet->SetPointerData(3, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 3.0, 4.0, 0);
packet->SetPointerData(4, data);
CreateSimulatedPointerData(data, PointerData::Change::kRemove, 0, 3.0, 4.0,
0);
packet->SetPointerData(5, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)6);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].synthesized, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kHover);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[1].physical_delta_x, 3.0);
ASSERT_EQ(result[1].physical_delta_y, 0.0);
ASSERT_EQ(result[2].change, PointerData::Change::kDown);
ASSERT_EQ(result[2].pointer_identifier, 1);
ASSERT_EQ(result[2].synthesized, 0);
ASSERT_EQ(result[3].change, PointerData::Change::kMove);
ASSERT_EQ(result[3].pointer_identifier, 1);
ASSERT_EQ(result[3].synthesized, 0);
ASSERT_EQ(result[3].physical_delta_x, 0.0);
ASSERT_EQ(result[3].physical_delta_y, 4.0);
ASSERT_EQ(result[4].change, PointerData::Change::kUp);
ASSERT_EQ(result[4].pointer_identifier, 1);
ASSERT_EQ(result[4].synthesized, 0);
ASSERT_EQ(result[5].change, PointerData::Change::kRemove);
ASSERT_EQ(result[5].synthesized, 0);
}
TEST(PointerDataPacketConverterTest, CanSynthesizeDownAndUp) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(4);
PointerData data;
CreateSimulatedPointerData(data, PointerData::Change::kAdd, 0, 0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 3.0, 0.0, 1);
packet->SetPointerData(1, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 3.0, 4.0, 0);
packet->SetPointerData(2, data);
CreateSimulatedPointerData(data, PointerData::Change::kRemove, 0, 3.0, 4.0,
0);
packet->SetPointerData(3, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)6);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].synthesized, 0);
// A hover should be synthesized.
ASSERT_EQ(result[1].change, PointerData::Change::kHover);
ASSERT_EQ(result[1].synthesized, 1);
ASSERT_EQ(result[1].physical_delta_x, 3.0);
ASSERT_EQ(result[1].physical_delta_y, 0.0);
ASSERT_EQ(result[1].buttons, 0);
ASSERT_EQ(result[2].change, PointerData::Change::kDown);
ASSERT_EQ(result[2].pointer_identifier, 1);
ASSERT_EQ(result[2].synthesized, 0);
ASSERT_EQ(result[2].buttons, 1);
// A move should be synthesized.
ASSERT_EQ(result[3].change, PointerData::Change::kMove);
ASSERT_EQ(result[3].pointer_identifier, 1);
ASSERT_EQ(result[3].synthesized, 1);
ASSERT_EQ(result[3].physical_delta_x, 0.0);
ASSERT_EQ(result[3].physical_delta_y, 4.0);
ASSERT_EQ(result[3].buttons, 1);
ASSERT_EQ(result[4].change, PointerData::Change::kUp);
ASSERT_EQ(result[4].pointer_identifier, 1);
ASSERT_EQ(result[4].synthesized, 0);
ASSERT_EQ(result[4].buttons, 0);
ASSERT_EQ(result[5].change, PointerData::Change::kRemove);
ASSERT_EQ(result[5].synthesized, 0);
}
TEST(PointerDataPacketConverterTest, CanUpdatePointerIdentifier) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(7);
PointerData data;
CreateSimulatedPointerData(data, PointerData::Change::kAdd, 0, 0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 0.0, 0.0, 1);
packet->SetPointerData(1, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 0.0, 0.0, 0);
packet->SetPointerData(2, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 0.0, 0.0, 1);
packet->SetPointerData(3, data);
CreateSimulatedPointerData(data, PointerData::Change::kMove, 0, 3.0, 0.0, 1);
packet->SetPointerData(4, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 3.0, 0.0, 0);
packet->SetPointerData(5, data);
CreateSimulatedPointerData(data, PointerData::Change::kRemove, 0, 3.0, 0.0,
0);
packet->SetPointerData(6, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)7);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].synthesized, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kDown);
ASSERT_EQ(result[1].pointer_identifier, 1);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[2].change, PointerData::Change::kUp);
ASSERT_EQ(result[2].pointer_identifier, 1);
ASSERT_EQ(result[2].synthesized, 0);
// Pointer count increase to 2.
ASSERT_EQ(result[3].change, PointerData::Change::kDown);
ASSERT_EQ(result[3].pointer_identifier, 2);
ASSERT_EQ(result[3].synthesized, 0);
ASSERT_EQ(result[4].change, PointerData::Change::kMove);
ASSERT_EQ(result[4].pointer_identifier, 2);
ASSERT_EQ(result[4].synthesized, 0);
ASSERT_EQ(result[4].physical_delta_x, 3.0);
ASSERT_EQ(result[4].physical_delta_y, 0.0);
ASSERT_EQ(result[5].change, PointerData::Change::kUp);
ASSERT_EQ(result[5].pointer_identifier, 2);
ASSERT_EQ(result[5].synthesized, 0);
ASSERT_EQ(result[6].change, PointerData::Change::kRemove);
ASSERT_EQ(result[6].synthesized, 0);
}
TEST(PointerDataPacketConverterTest, AlwaysForwardMoveEvent) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(4);
PointerData data;
CreateSimulatedPointerData(data, PointerData::Change::kAdd, 0, 0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 0.0, 0.0, 1);
packet->SetPointerData(1, data);
// Creates a move event without a location change.
CreateSimulatedPointerData(data, PointerData::Change::kMove, 0, 0.0, 0.0, 1);
packet->SetPointerData(2, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 0.0, 0.0, 0);
packet->SetPointerData(3, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)4);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].synthesized, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kDown);
ASSERT_EQ(result[1].pointer_identifier, 1);
ASSERT_EQ(result[1].synthesized, 0);
// Does not filter out the move event.
ASSERT_EQ(result[2].change, PointerData::Change::kMove);
ASSERT_EQ(result[2].pointer_identifier, 1);
ASSERT_EQ(result[2].synthesized, 0);
ASSERT_EQ(result[3].change, PointerData::Change::kUp);
ASSERT_EQ(result[3].pointer_identifier, 1);
ASSERT_EQ(result[3].synthesized, 0);
}
TEST(PointerDataPacketConverterTest, CanWorkWithDifferentDevices) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(12);
PointerData data;
CreateSimulatedPointerData(data, PointerData::Change::kAdd, 0, 0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 0.0, 0.0, 1);
packet->SetPointerData(1, data);
CreateSimulatedPointerData(data, PointerData::Change::kAdd, 1, 0.0, 0.0, 0);
packet->SetPointerData(2, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 1, 0.0, 0.0, 1);
packet->SetPointerData(3, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 0.0, 0.0, 0);
packet->SetPointerData(4, data);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 0.0, 0.0, 1);
packet->SetPointerData(5, data);
CreateSimulatedPointerData(data, PointerData::Change::kMove, 1, 0.0, 4.0, 1);
packet->SetPointerData(6, data);
CreateSimulatedPointerData(data, PointerData::Change::kMove, 0, 3.0, 0.0, 1);
packet->SetPointerData(7, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 1, 0.0, 4.0, 0);
packet->SetPointerData(8, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 3.0, 0.0, 0);
packet->SetPointerData(9, data);
CreateSimulatedPointerData(data, PointerData::Change::kRemove, 0, 3.0, 0.0,
0);
packet->SetPointerData(10, data);
CreateSimulatedPointerData(data, PointerData::Change::kRemove, 1, 0.0, 4.0,
0);
packet->SetPointerData(11, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)12);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].device, 0);
ASSERT_EQ(result[0].synthesized, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kDown);
ASSERT_EQ(result[1].device, 0);
ASSERT_EQ(result[1].pointer_identifier, 1);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[2].change, PointerData::Change::kAdd);
ASSERT_EQ(result[2].device, 1);
ASSERT_EQ(result[2].synthesized, 0);
ASSERT_EQ(result[3].change, PointerData::Change::kDown);
ASSERT_EQ(result[3].device, 1);
ASSERT_EQ(result[3].pointer_identifier, 2);
ASSERT_EQ(result[3].synthesized, 0);
ASSERT_EQ(result[4].change, PointerData::Change::kUp);
ASSERT_EQ(result[4].device, 0);
ASSERT_EQ(result[4].pointer_identifier, 1);
ASSERT_EQ(result[4].synthesized, 0);
ASSERT_EQ(result[5].change, PointerData::Change::kDown);
ASSERT_EQ(result[5].device, 0);
ASSERT_EQ(result[5].pointer_identifier, 3);
ASSERT_EQ(result[5].synthesized, 0);
ASSERT_EQ(result[6].change, PointerData::Change::kMove);
ASSERT_EQ(result[6].device, 1);
ASSERT_EQ(result[6].pointer_identifier, 2);
ASSERT_EQ(result[6].synthesized, 0);
ASSERT_EQ(result[6].physical_delta_x, 0.0);
ASSERT_EQ(result[6].physical_delta_y, 4.0);
ASSERT_EQ(result[7].change, PointerData::Change::kMove);
ASSERT_EQ(result[7].device, 0);
ASSERT_EQ(result[7].pointer_identifier, 3);
ASSERT_EQ(result[7].synthesized, 0);
ASSERT_EQ(result[7].physical_delta_x, 3.0);
ASSERT_EQ(result[7].physical_delta_y, 0.0);
ASSERT_EQ(result[8].change, PointerData::Change::kUp);
ASSERT_EQ(result[8].device, 1);
ASSERT_EQ(result[8].pointer_identifier, 2);
ASSERT_EQ(result[8].synthesized, 0);
ASSERT_EQ(result[9].change, PointerData::Change::kUp);
ASSERT_EQ(result[9].device, 0);
ASSERT_EQ(result[9].pointer_identifier, 3);
ASSERT_EQ(result[9].synthesized, 0);
ASSERT_EQ(result[10].change, PointerData::Change::kRemove);
ASSERT_EQ(result[10].device, 0);
ASSERT_EQ(result[10].synthesized, 0);
ASSERT_EQ(result[11].change, PointerData::Change::kRemove);
ASSERT_EQ(result[11].device, 1);
ASSERT_EQ(result[11].synthesized, 0);
}
TEST(PointerDataPacketConverterTest, CanSynthesizeAdd) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(2);
PointerData data;
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 330.0, 450.0,
1);
packet->SetPointerData(0, data);
CreateSimulatedPointerData(data, PointerData::Change::kUp, 0, 0.0, 0.0, 0);
packet->SetPointerData(1, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)4);
// A add should be synthesized.
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].physical_x, 330.0);
ASSERT_EQ(result[0].physical_y, 450.0);
ASSERT_EQ(result[0].synthesized, 1);
ASSERT_EQ(result[0].buttons, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kDown);
ASSERT_EQ(result[1].physical_x, 330.0);
ASSERT_EQ(result[1].physical_y, 450.0);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[1].buttons, 1);
// A move should be synthesized.
ASSERT_EQ(result[2].change, PointerData::Change::kMove);
ASSERT_EQ(result[2].physical_delta_x, -330.0);
ASSERT_EQ(result[2].physical_delta_y, -450.0);
ASSERT_EQ(result[2].physical_x, 0.0);
ASSERT_EQ(result[2].physical_y, 0.0);
ASSERT_EQ(result[2].synthesized, 1);
ASSERT_EQ(result[2].buttons, 1);
ASSERT_EQ(result[3].change, PointerData::Change::kUp);
ASSERT_EQ(result[3].physical_x, 0.0);
ASSERT_EQ(result[3].physical_y, 0.0);
ASSERT_EQ(result[3].synthesized, 0);
ASSERT_EQ(result[3].buttons, 0);
}
TEST(PointerDataPacketConverterTest, CanHandleThreeFingerGesture) {
// Regression test https://github.com/flutter/flutter/issues/20517.
PointerDataPacketConverter converter;
PointerData data;
std::vector<PointerData> result;
// First finger down.
auto packet = std::make_unique<PointerDataPacket>(1);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 0, 0.0, 0.0, 1);
packet->SetPointerData(0, data);
auto converted_packet = converter.Convert(std::move(packet));
UnpackPointerPacket(result, std::move(converted_packet));
// Second finger down.
packet = std::make_unique<PointerDataPacket>(1);
CreateSimulatedPointerData(data, PointerData::Change::kDown, 1, 33.0, 44.0,
1);
packet->SetPointerData(0, data);
converted_packet = converter.Convert(std::move(packet));
UnpackPointerPacket(result, std::move(converted_packet));
// Triggers three cancels.
packet = std::make_unique<PointerDataPacket>(3);
CreateSimulatedPointerData(data, PointerData::Change::kCancel, 1, 33.0, 44.0,
0);
packet->SetPointerData(0, data);
CreateSimulatedPointerData(data, PointerData::Change::kCancel, 0, 0.0, 0.0,
0);
packet->SetPointerData(1, data);
CreateSimulatedPointerData(data, PointerData::Change::kCancel, 2, 40.0, 50.0,
0);
packet->SetPointerData(2, data);
converted_packet = converter.Convert(std::move(packet));
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)6);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].device, 0);
ASSERT_EQ(result[0].physical_x, 0.0);
ASSERT_EQ(result[0].physical_y, 0.0);
ASSERT_EQ(result[0].synthesized, 1);
ASSERT_EQ(result[0].buttons, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kDown);
ASSERT_EQ(result[1].device, 0);
ASSERT_EQ(result[1].physical_x, 0.0);
ASSERT_EQ(result[1].physical_y, 0.0);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[1].buttons, 1);
ASSERT_EQ(result[2].change, PointerData::Change::kAdd);
ASSERT_EQ(result[2].device, 1);
ASSERT_EQ(result[2].physical_x, 33.0);
ASSERT_EQ(result[2].physical_y, 44.0);
ASSERT_EQ(result[2].synthesized, 1);
ASSERT_EQ(result[2].buttons, 0);
ASSERT_EQ(result[3].change, PointerData::Change::kDown);
ASSERT_EQ(result[3].device, 1);
ASSERT_EQ(result[3].physical_x, 33.0);
ASSERT_EQ(result[3].physical_y, 44.0);
ASSERT_EQ(result[3].synthesized, 0);
ASSERT_EQ(result[3].buttons, 1);
ASSERT_EQ(result[4].change, PointerData::Change::kCancel);
ASSERT_EQ(result[4].device, 1);
ASSERT_EQ(result[4].physical_x, 33.0);
ASSERT_EQ(result[4].physical_y, 44.0);
ASSERT_EQ(result[4].synthesized, 0);
ASSERT_EQ(result[5].change, PointerData::Change::kCancel);
ASSERT_EQ(result[5].device, 0);
ASSERT_EQ(result[5].physical_x, 0.0);
ASSERT_EQ(result[5].physical_y, 0.0);
ASSERT_EQ(result[5].synthesized, 0);
// Third cancel should be dropped
}
TEST(PointerDataPacketConverterTest, CanConvertPointerSignals) {
PointerData::SignalKind signal_kinds[] = {
PointerData::SignalKind::kScroll,
PointerData::SignalKind::kScrollInertiaCancel,
PointerData::SignalKind::kScale,
};
for (const PointerData::SignalKind& kind : signal_kinds) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(6);
PointerData data;
CreateSimulatedMousePointerData(data, PointerData::Change::kAdd,
PointerData::SignalKind::kNone, 0, 0.0, 0.0,
0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kAdd,
PointerData::SignalKind::kNone, 1, 0.0, 0.0,
0.0, 0.0, 0);
packet->SetPointerData(1, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kDown,
PointerData::SignalKind::kNone, 1, 0.0, 0.0,
0.0, 0.0, 1);
packet->SetPointerData(2, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover, kind, 0,
34.0, 34.0, 30.0, 0.0, 0);
packet->SetPointerData(3, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover, kind, 1,
49.0, 49.0, 50.0, 0.0, 0);
packet->SetPointerData(4, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover, kind, 2,
10.0, 20.0, 30.0, 40.0, 0);
packet->SetPointerData(5, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)9);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[0].device, 0);
ASSERT_EQ(result[0].physical_x, 0.0);
ASSERT_EQ(result[0].physical_y, 0.0);
ASSERT_EQ(result[0].synthesized, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kAdd);
ASSERT_EQ(result[1].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[1].device, 1);
ASSERT_EQ(result[1].physical_x, 0.0);
ASSERT_EQ(result[1].physical_y, 0.0);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[2].change, PointerData::Change::kDown);
ASSERT_EQ(result[2].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[2].device, 1);
ASSERT_EQ(result[2].physical_x, 0.0);
ASSERT_EQ(result[2].physical_y, 0.0);
ASSERT_EQ(result[2].synthesized, 0);
// Converter will synthesize a hover to position for device 0.
ASSERT_EQ(result[3].change, PointerData::Change::kHover);
ASSERT_EQ(result[3].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[3].device, 0);
ASSERT_EQ(result[3].physical_x, 34.0);
ASSERT_EQ(result[3].physical_y, 34.0);
ASSERT_EQ(result[3].physical_delta_x, 34.0);
ASSERT_EQ(result[3].physical_delta_y, 34.0);
ASSERT_EQ(result[3].buttons, 0);
ASSERT_EQ(result[3].synthesized, 1);
ASSERT_EQ(result[4].change, PointerData::Change::kHover);
ASSERT_EQ(result[4].signal_kind, kind);
ASSERT_EQ(result[4].device, 0);
ASSERT_EQ(result[4].physical_x, 34.0);
ASSERT_EQ(result[4].physical_y, 34.0);
ASSERT_EQ(result[4].scroll_delta_x, 30.0);
ASSERT_EQ(result[4].scroll_delta_y, 0.0);
// Converter will synthesize a move to position for device 1.
ASSERT_EQ(result[5].change, PointerData::Change::kMove);
ASSERT_EQ(result[5].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[5].device, 1);
ASSERT_EQ(result[5].physical_x, 49.0);
ASSERT_EQ(result[5].physical_y, 49.0);
ASSERT_EQ(result[5].physical_delta_x, 49.0);
ASSERT_EQ(result[5].physical_delta_y, 49.0);
ASSERT_EQ(result[5].buttons, 1);
ASSERT_EQ(result[5].synthesized, 1);
ASSERT_EQ(result[6].change, PointerData::Change::kHover);
ASSERT_EQ(result[6].signal_kind, kind);
ASSERT_EQ(result[6].device, 1);
ASSERT_EQ(result[6].physical_x, 49.0);
ASSERT_EQ(result[6].physical_y, 49.0);
ASSERT_EQ(result[6].scroll_delta_x, 50.0);
ASSERT_EQ(result[6].scroll_delta_y, 0.0);
// Converter will synthesize an add for device 2.
ASSERT_EQ(result[7].change, PointerData::Change::kAdd);
ASSERT_EQ(result[7].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[7].device, 2);
ASSERT_EQ(result[7].physical_x, 10.0);
ASSERT_EQ(result[7].physical_y, 20.0);
ASSERT_EQ(result[7].synthesized, 1);
ASSERT_EQ(result[8].change, PointerData::Change::kHover);
ASSERT_EQ(result[8].signal_kind, kind);
ASSERT_EQ(result[8].device, 2);
ASSERT_EQ(result[8].physical_x, 10.0);
ASSERT_EQ(result[8].physical_y, 20.0);
ASSERT_EQ(result[8].scroll_delta_x, 30.0);
ASSERT_EQ(result[8].scroll_delta_y, 40.0);
}
}
TEST(PointerDataPacketConverterTest, CanConvertTrackpadGesture) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(3);
PointerData data;
CreateSimulatedTrackpadGestureData(data, PointerData::Change::kPanZoomStart,
0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
packet->SetPointerData(0, data);
CreateSimulatedTrackpadGestureData(data, PointerData::Change::kPanZoomUpdate,
0, 0.0, 0.0, 3.0, 4.0, 1.0, 0.0);
packet->SetPointerData(1, data);
CreateSimulatedTrackpadGestureData(data, PointerData::Change::kPanZoomEnd, 0,
0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
packet->SetPointerData(2, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)4);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].device, 0);
ASSERT_EQ(result[0].synthesized, 1);
ASSERT_EQ(result[1].change, PointerData::Change::kPanZoomStart);
ASSERT_EQ(result[1].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[1].device, 0);
ASSERT_EQ(result[1].physical_x, 0.0);
ASSERT_EQ(result[1].physical_y, 0.0);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[2].change, PointerData::Change::kPanZoomUpdate);
ASSERT_EQ(result[2].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[2].device, 0);
ASSERT_EQ(result[2].physical_x, 0.0);
ASSERT_EQ(result[2].physical_y, 0.0);
ASSERT_EQ(result[2].pan_x, 3.0);
ASSERT_EQ(result[2].pan_y, 4.0);
ASSERT_EQ(result[2].pan_delta_x, 3.0);
ASSERT_EQ(result[2].pan_delta_y, 4.0);
ASSERT_EQ(result[2].scale, 1.0);
ASSERT_EQ(result[2].rotation, 0.0);
ASSERT_EQ(result[2].synthesized, 0);
ASSERT_EQ(result[3].change, PointerData::Change::kPanZoomEnd);
ASSERT_EQ(result[3].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[3].device, 0);
ASSERT_EQ(result[3].physical_x, 0.0);
ASSERT_EQ(result[3].physical_y, 0.0);
ASSERT_EQ(result[3].synthesized, 0);
}
} // namespace testing
} // namespace flutter