blob: 2964077c8f97bf1ea003f4720ca9c9d128cd3eba [file] [log] [blame] [edit]
// 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 "src/ui/scenic/tests/utils/utils.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/ui/scenic/cpp/id.h>
#include <cmath>
namespace integration_tests {
using InputCommand = fuchsia::ui::input::Command;
using fuchsia::ui::input::PointerEvent;
using fuchsia::ui::input::PointerEventPhase;
using fuchsia::ui::input::PointerEventType;
namespace {
std::ostream& operator<<(std::ostream& os, const PointerEventPhase& value) {
switch (value) {
case PointerEventPhase::ADD:
return os << "add";
case PointerEventPhase::HOVER:
return os << "hover";
case PointerEventPhase::DOWN:
return os << "down";
case PointerEventPhase::MOVE:
return os << "move";
case PointerEventPhase::UP:
return os << "up";
case PointerEventPhase::REMOVE:
return os << "remove";
case PointerEventPhase::CANCEL:
return os << "cancel";
default:
return os << "<invalid enum value: " << static_cast<uint32_t>(value) << ">";
}
}
std::ostream& operator<<(std::ostream& os, const PointerEventType& value) {
switch (value) {
case PointerEventType::TOUCH:
return os << "touch";
case PointerEventType::STYLUS:
return os << "stylus";
case PointerEventType::INVERTED_STYLUS:
return os << "inverted stylus";
case PointerEventType::MOUSE:
return os << "mouse";
default:
return os << "<invalid enum value: " << static_cast<uint32_t>(value) << ">";
}
}
} // namespace
// Used to compare whether two values are nearly equal.
// 1000 times machine limits to account for scaling from [0,1] to viewing volume [0,1000].
constexpr float kEpsilon = std::numeric_limits<float>::epsilon() * 1000;
bool PointerMatches(const PointerEvent& event, uint32_t pointer_id, PointerEventPhase phase,
float x, float y, PointerEventType type, uint32_t buttons) {
bool result = true;
if (event.type != type) {
FX_LOGS(ERROR) << " Actual type: " << event.type;
FX_LOGS(ERROR) << "Expected type: " << type;
result = false;
}
if (event.buttons != buttons) {
FX_LOGS(ERROR) << " Actual buttons: " << event.buttons;
FX_LOGS(ERROR) << "Expected buttons: " << buttons;
result = false;
}
if (event.pointer_id != pointer_id) {
FX_LOGS(ERROR) << " Actual id: " << event.pointer_id;
FX_LOGS(ERROR) << "Expected id: " << pointer_id;
result = false;
}
if (event.phase != phase) {
FX_LOGS(ERROR) << " Actual phase: " << event.phase;
FX_LOGS(ERROR) << "Expected phase: " << phase;
result = false;
}
if (fabs(event.x - x) > kEpsilon) {
FX_LOGS(ERROR) << " Actual x: " << event.x;
FX_LOGS(ERROR) << "Expected x: " << x;
result = false;
}
if (fabs(event.y - y) > kEpsilon) {
FX_LOGS(ERROR) << " Actual y: " << event.y;
FX_LOGS(ERROR) << "Expected y: " << y;
result = false;
}
return result;
}
bool CmpFloatingValues(float num1, float num2) {
auto diff = fabs(num1 - num2);
return diff < kEpsilon;
}
zx_koid_t ExtractKoid(const zx::object_base& object) {
zx_info_handle_basic_t info{};
if (object.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr) != ZX_OK) {
return ZX_KOID_INVALID; // no info
}
return info.koid;
}
zx_koid_t ExtractKoid(const fuchsia::ui::views::ViewRef& view_ref) {
return ExtractKoid(view_ref.reference);
}
Mat3 ArrayToMat3(std::array<float, 9> array) {
Mat3 mat;
for (size_t row = 0; row < mat.size(); row++) {
for (size_t col = 0; col < mat[0].size(); col++) {
mat[row][col] = array[mat.size() * row + col];
}
}
return mat;
}
Vec3 operator*(const Mat3& mat, const Vec3& vec) {
Vec3 result = {0, 0, 0};
for (size_t col = 0; col < mat[0].size(); col++) {
for (size_t row = 0; row < mat.size(); row++) {
result[col] += mat[row][col] * vec[row];
}
}
return result;
}
Vec3& operator/(Vec3& vec, float num) {
for (size_t i = 0; i < vec.size(); i++) {
vec[i] /= num;
}
return vec;
}
Vec4 angleAxis(float angle, const Vec3& vec) {
Vec4 result;
result[0] = vec[0] * sin(angle * 0.5f);
result[1] = vec[1] * sin(angle * 0.5f);
result[2] = vec[2] * sin(angle * 0.5f);
result[3] = cos(angle * 0.5f);
return result;
}
PointerCommandGenerator::PointerCommandGenerator(uint32_t compositor_id, uint32_t device_id,
uint32_t pointer_id, PointerEventType type,
uint32_t buttons)
: compositor_id_(compositor_id) {
blank_.device_id = device_id;
blank_.pointer_id = pointer_id;
blank_.type = type;
blank_.buttons = buttons;
}
InputCommand PointerCommandGenerator::Add(float x, float y) {
PointerEvent event;
fidl::Clone(blank_, &event);
event.phase = PointerEventPhase::ADD;
event.x = x;
event.y = y;
return MakeInputCommand(event);
}
InputCommand PointerCommandGenerator::Down(float x, float y) {
PointerEvent event;
fidl::Clone(blank_, &event);
event.phase = PointerEventPhase::DOWN;
event.x = x;
event.y = y;
return MakeInputCommand(event);
}
InputCommand PointerCommandGenerator::Move(float x, float y) {
PointerEvent event;
fidl::Clone(blank_, &event);
event.phase = PointerEventPhase::MOVE;
event.x = x;
event.y = y;
return MakeInputCommand(event);
}
InputCommand PointerCommandGenerator::Up(float x, float y) {
PointerEvent event;
fidl::Clone(blank_, &event);
event.phase = PointerEventPhase::UP;
event.x = x;
event.y = y;
return MakeInputCommand(event);
}
InputCommand PointerCommandGenerator::Remove(float x, float y) {
PointerEvent event;
fidl::Clone(blank_, &event);
event.phase = PointerEventPhase::REMOVE;
event.x = x;
event.y = y;
return MakeInputCommand(event);
}
InputCommand PointerCommandGenerator::MakeInputCommand(PointerEvent event) {
fuchsia::ui::input::SendPointerInputCmd pointer_cmd;
pointer_cmd.compositor_id = compositor_id_;
pointer_cmd.pointer_event = std::move(event);
InputCommand input_cmd;
input_cmd.set_send_pointer_input(std::move(pointer_cmd));
return input_cmd;
}
} // namespace integration_tests