blob: 40f1648707e101d754abc293aef839cb4f22748b [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.
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_GRAPH_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_GRAPH_H_
#include <fuchsia/math/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl_test_base.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fidl/cpp/interface_request.h>
#include <zircon/types.h>
#include <algorithm>
#include <cstdint>
#include <optional>
#include <unordered_map>
#include <variant>
#include <vector>
#include "flutter/fml/macros.h"
inline bool operator==(const fuchsia::math::SizeU& a,
const fuchsia::math::SizeU& b) {
return a.width == b.width && a.height == b.height;
}
inline bool operator==(const fuchsia::math::Inset& a,
const fuchsia::math::Inset& b) {
return a.top == b.top && a.left == b.left && a.right == b.right &&
a.bottom == b.bottom;
}
inline bool operator==(const fuchsia::math::Vec& a,
const fuchsia::math::Vec& b) {
return a.x == b.x && a.y == b.y;
}
inline bool operator==(const fuchsia::math::VecF& a,
const fuchsia::math::VecF& b) {
return a.x == b.x && a.y == b.y;
}
inline bool operator==(const fuchsia::math::Rect& a,
const fuchsia::math::Rect& b) {
return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
}
inline bool operator==(const fuchsia::math::RectF& a,
const fuchsia::math::RectF& b) {
return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
}
inline bool operator==(const fuchsia::ui::composition::ContentId& a,
const fuchsia::ui::composition::ContentId& b) {
return a.value == b.value;
}
inline bool operator==(const fuchsia::ui::composition::TransformId& a,
const fuchsia::ui::composition::TransformId& b) {
return a.value == b.value;
}
inline bool operator==(const fuchsia::ui::composition::ViewportProperties& a,
const fuchsia::ui::composition::ViewportProperties& b) {
if (a.has_logical_size() != b.has_logical_size()) {
return false;
}
bool logical_size_equal = true;
if (a.has_logical_size()) {
const fuchsia::math::SizeU& a_logical_size = a.logical_size();
const fuchsia::math::SizeU& b_logical_size = b.logical_size();
logical_size_equal = (a_logical_size.width == b_logical_size.width &&
a_logical_size.height == b_logical_size.height);
}
return logical_size_equal;
}
inline bool operator==(const fuchsia::ui::composition::ImageProperties& a,
const fuchsia::ui::composition::ImageProperties& b) {
if (a.has_size() != b.has_size()) {
return false;
}
bool size_equal = true;
if (a.has_size()) {
const fuchsia::math::SizeU& a_size = a.size();
const fuchsia::math::SizeU& b_size = b.size();
size_equal =
(a_size.width == b_size.width && a_size.height == b_size.height);
}
return size_equal;
}
inline bool operator==(const fuchsia::ui::composition::HitRegion& a,
const fuchsia::ui::composition::HitRegion& b) {
return a.region == b.region && a.hit_test == b.hit_test;
}
inline bool operator!=(const fuchsia::ui::composition::HitRegion& a,
const fuchsia::ui::composition::HitRegion& b) {
return !(a == b);
}
inline bool operator==(
const std::vector<fuchsia::ui::composition::HitRegion>& a,
const std::vector<fuchsia::ui::composition::HitRegion>& b) {
if (a.size() != b.size())
return false;
for (size_t i = 0; i < a.size(); ++i) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
inline bool operator==(const std::optional<fuchsia::math::Rect>& a,
const std::optional<fuchsia::math::Rect>& b) {
if (a.has_value() != b.has_value()) {
return false;
}
if (!a.has_value()) {
}
return a.value() == b.value();
}
namespace flutter_runner::testing {
constexpr static fuchsia::ui::composition::TransformId kInvalidTransformId{0};
constexpr static fuchsia::ui::composition::ContentId kInvalidContentId{0};
// Convenience structure which allows clients to easily create a valid
// `ViewCreationToken` / `ViewportCreationToken` pair for use with Flatland
// `CreateView` and `CreateViewport`.
struct ViewTokenPair {
static ViewTokenPair New();
fuchsia::ui::views::ViewCreationToken view_token;
fuchsia::ui::views::ViewportCreationToken viewport_token;
};
// Convenience structure which allows clients to easily create a valid
// `BufferCollectionExportToken` / `BufferCollectionImportToken` pair for use
// with Flatland `RegisterBufferCollection` and `CreateImage`.
struct BufferCollectionTokenPair {
static BufferCollectionTokenPair New();
fuchsia::ui::composition::BufferCollectionExportToken export_token;
fuchsia::ui::composition::BufferCollectionImportToken import_token;
};
struct FakeView {
bool operator==(const FakeView& other) const;
zx_koid_t view_token{};
zx_koid_t view_ref{};
zx_koid_t view_ref_control{};
zx_koid_t view_ref_focused{};
zx_koid_t focuser{};
zx_koid_t touch_source{};
zx_koid_t mouse_source{};
zx_koid_t parent_viewport_watcher{};
};
struct FakeViewport {
bool operator==(const FakeViewport& other) const;
constexpr static fuchsia::math::SizeU kDefaultViewportLogicalSize{};
constexpr static fuchsia::math::Inset kDefaultViewportInset{};
fuchsia::ui::composition::ContentId id{kInvalidContentId};
fuchsia::ui::composition::ViewportProperties viewport_properties{};
zx_koid_t viewport_token{};
zx_koid_t child_view_watcher{};
};
struct FakeImage {
bool operator==(const FakeImage& other) const;
constexpr static fuchsia::math::SizeU kDefaultImageSize{};
constexpr static fuchsia::math::RectF kDefaultSampleRegion{};
constexpr static fuchsia::math::SizeU kDefaultDestinationSize{};
constexpr static float kDefaultOpacity{1.f};
constexpr static fuchsia::ui::composition::BlendMode kDefaultBlendMode{
fuchsia::ui::composition::BlendMode::SRC_OVER};
fuchsia::ui::composition::ContentId id{kInvalidContentId};
fuchsia::ui::composition::ImageProperties image_properties{};
fuchsia::math::RectF sample_region{kDefaultSampleRegion};
fuchsia::math::SizeU destination_size{kDefaultDestinationSize};
float opacity{kDefaultOpacity};
fuchsia::ui::composition::BlendMode blend_mode{kDefaultBlendMode};
zx_koid_t import_token{};
uint32_t vmo_index{0};
};
using FakeContent = std::variant<FakeViewport, FakeImage>;
struct FakeTransform {
bool operator==(const FakeTransform& other) const;
constexpr static fuchsia::math::Vec kDefaultTranslation{.x = 0, .y = 0};
constexpr static fuchsia::math::VecF kDefaultScale{.x = 1.0f, .y = 1.0f};
constexpr static fuchsia::ui::composition::Orientation kDefaultOrientation{
fuchsia::ui::composition::Orientation::CCW_0_DEGREES};
constexpr static float kDefaultOpacity = 1.0f;
fuchsia::ui::composition::TransformId id{kInvalidTransformId};
fuchsia::math::Vec translation{kDefaultTranslation};
fuchsia::math::VecF scale{kDefaultScale};
fuchsia::ui::composition::Orientation orientation{kDefaultOrientation};
std::optional<fuchsia::math::Rect> clip_bounds = std::nullopt;
float opacity = kDefaultOpacity;
std::vector<std::shared_ptr<FakeTransform>> children;
std::shared_ptr<FakeContent> content;
std::vector<fuchsia::ui::composition::HitRegion> hit_regions;
};
struct FakeGraph {
using ContentIdKey = decltype(fuchsia::ui::composition::ContentId::value);
using TransformIdKey = decltype(fuchsia::ui::composition::TransformId::value);
bool operator==(const FakeGraph& other) const;
void Clear();
FakeGraph Clone() const;
std::unordered_map<ContentIdKey, std::shared_ptr<FakeContent>> content_map;
std::unordered_map<TransformIdKey, std::shared_ptr<FakeTransform>>
transform_map;
std::shared_ptr<FakeTransform> root_transform;
std::optional<FakeView> view;
};
template <typename ZX>
std::pair<zx_koid_t, zx_koid_t> GetKoids(const ZX& kobj) {
zx_info_handle_basic_t info;
zx_status_t status =
kobj.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info),
/*actual_records*/ nullptr, /*avail_records*/ nullptr);
return status == ZX_OK ? std::make_pair(info.koid, info.related_koid)
: std::make_pair(zx_koid_t{}, zx_koid_t{});
}
template <typename F>
std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fidl::InterfaceHandle<F>& interface_handle) {
return GetKoids(interface_handle.channel());
}
template <typename F>
std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fidl::InterfaceRequest<F>& interface_request) {
return GetKoids(interface_request.channel());
}
template <typename F>
std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fidl::InterfacePtr<F>& interface_ptr) {
return GetKoids(interface_ptr.channel());
}
template <typename F>
std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fidl::Binding<F>& interface_binding) {
return GetKoids(interface_binding.channel());
}
inline std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fuchsia::ui::views::ViewCreationToken& view_token) {
return GetKoids(view_token.value);
}
inline std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fuchsia::ui::views::ViewportCreationToken& viewport_token) {
return GetKoids(viewport_token.value);
}
inline std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fuchsia::ui::views::ViewRef& view_ref) {
return GetKoids(view_ref.reference);
}
inline std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fuchsia::ui::views::ViewRefControl& view_ref_control) {
return GetKoids(view_ref_control.reference);
}
inline std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fuchsia::ui::composition::BufferCollectionExportToken&
buffer_collection_token) {
return GetKoids(buffer_collection_token.value);
}
inline std::pair<zx_koid_t, zx_koid_t> GetKoids(
const fuchsia::ui::composition::BufferCollectionImportToken&
buffer_collection_token) {
return GetKoids(buffer_collection_token.value);
}
}; // namespace flutter_runner::testing
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_GRAPH_H_