blob: 39fd811616dbe137648f20952b2ca7ff220e1b9d [file] [log] [blame]
// Copyright 2022 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.
#ifndef SRC_UI_TESTING_UTIL_TEST_VIEW_H_
#define SRC_UI_TESTING_UTIL_TEST_VIEW_H_
#include <fuchsia/ui/app/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/component/cpp/testing/realm_builder.h>
#include <lib/sys/component/cpp/testing/realm_builder_types.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <optional>
#include <src/lib/fxl/memory/weak_ptr.h>
namespace ui_testing {
class TestView;
// Used to open up access to TestView internals, since LocalComponentImpl (and thus TestView) is not
// accessible directly to the test fixture.
class TestViewAccess {
public:
virtual ~TestViewAccess() = default;
// Must be called by TestView as soon as practical.
virtual void SetTestView(const fxl::WeakPtr<TestView>& view);
// Check that view access is possible. Since view creation is lazy, access may
// not be initially possible for a while.
bool HasView() const { return test_view_.get() != nullptr; }
// Since view component creation may be lazy, check first whether HasView()
// returns true before calling this.
TestView* view() const {
FX_CHECK(HasView());
return test_view_.get();
}
protected:
fxl::WeakPtr<TestView> test_view_{};
};
class TestView final : public fuchsia::ui::app::ViewProvider,
public component_testing::LocalComponentImpl {
public:
enum class ContentType {
// Draws a green rect in the view.
DEFAULT = 0,
// Draws the following coordinate test pattern in the view:
//
// ___________________________________
// | | |
// | BLACK | RED |
// | _____|_____ |
// |___________| GREEN |___________|
// | |_________| |
// | | |
// | BLUE | MAGENTA |
// |________________|________________|
COORDINATE_GRID = 1,
};
explicit TestView(async_dispatcher_t* dispatcher, ContentType content_type,
std::weak_ptr<TestViewAccess> access)
: dispatcher_(dispatcher),
content_type_(content_type),
access_(std::move(access)),
weak_ptr_factory_(this) {
if (auto a = access_.lock()) {
a->SetTestView(weak_ptr_factory_.GetWeakPtr());
}
}
~TestView() override = default;
// |component_testing::LocalComponentImpl|
void OnStart() override;
const std::optional<fuchsia::ui::views::ViewRef>& view_ref() { return view_ref_; }
std::optional<zx_koid_t> GetViewRefKoid();
// |fuchsia.ui.app.ViewProvider|
void CreateView2(fuchsia::ui::app::CreateView2Args args) override;
void CreateViewWithViewRef(zx::eventpair token,
fuchsia::ui::views::ViewRefControl view_ref_control,
fuchsia::ui::views::ViewRef view_ref) override {
ZX_PANIC("Not Implemented");
}
// Add a child view!
// The viewport will have side length of 1/4 our side length and will be centered in our view.
void NestChildView();
uint32_t width();
uint32_t height();
private:
// Helper methods to add content to the view.
void DrawSimpleBackground();
void DrawCoordinateGrid();
void DrawContent();
// Helper method to draw a rectangle.
// (x, y, z) specifies the top-left corner of the rect.
// (width, height) specifies the rect's dimensions.
// (red, green, blue, alpha) specifies the color.
virtual void DrawRectangle(int32_t x, int32_t y, int32_t z, uint32_t width, uint32_t height,
uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha);
virtual void PresentChanges();
void ResizeChildViewport();
async_dispatcher_t* dispatcher_ = nullptr;
std::optional<ContentType> content_type_;
std::weak_ptr<TestViewAccess> access_;
fidl::BindingSet<fuchsia::ui::app::ViewProvider> view_provider_bindings_;
std::optional<fuchsia::ui::views::ViewRef> view_ref_;
// Scene graph:
// root transform (id=1)
// --> rectangle holder transform (id=2)
// --> ... (optional) rectangles (id=100, 101, 102, ...)
// --> (optional) child viewport transform (id=3) {content: child viewport id=4}
const uint64_t kRootTransformId = 1;
const uint64_t kRectangleHolderTransform = 2;
const uint64_t kChildViewportTransformId = 3;
const uint64_t kChildViewportContentId = 4;
// We'll keep incrementing this to get the next resource id (100, 101, 102, ...)
uint64_t next_resource_id_ = 100;
bool child_view_is_nested = false;
// Scenic session resources.
fuchsia::ui::composition::FlatlandPtr flatland_;
// Used to retrieve a11y view layout info. These should not change over the
// lifetime of the view.
fuchsia::ui::composition::ParentViewportWatcherPtr parent_watcher_;
std::optional<fuchsia::ui::composition::LayoutInfo> layout_info_;
fxl::WeakPtrFactory<TestView> weak_ptr_factory_; // Keep last.
};
} // namespace ui_testing
#endif // SRC_UI_TESTING_UTIL_TEST_VIEW_H_