blob: 73a87cd83ca4129e734e5a467bb2a4b979b3f21d [file] [log] [blame]
// Copyright 2020 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 <fuchsia/ui/input/cpp/fidl.h>
#include <lib/ui/scenic/cpp/session.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <zircon/status.h>
#include <gtest/gtest.h>
#include "src/ui/scenic/lib/input/input_system.h"
#include "src/ui/scenic/lib/input/tests/util.h"
namespace lib_ui_input_tests {
namespace {
class ViewTreeInputIntegrationTest : public InputSystemTest {
public:
ViewTreeInputIntegrationTest() = default;
protected:
uint32_t test_display_width_px() const override { return 5; }
uint32_t test_display_height_px() const override { return 5; }
};
// Scene layout:
// root
// |
// view1
// |
// view2
TEST_F(ViewTreeInputIntegrationTest, IsInputSuppressed_ShouldReturnFalseByDefault) {
auto [v1, vh1] = scenic::ViewTokenPair::New();
auto [v2, vh2] = scenic::ViewTokenPair::New();
auto [root_session, root_resources] = CreateScene();
scenic::Session* const session = root_session.session();
scenic::Scene* const scene = &root_resources.scene;
scenic::ViewHolder holder_1(session, std::move(vh1), "1");
scene->AddChild(holder_1);
RequestToPresent(session);
SessionWrapper client_1 = CreateClient("view_1", std::move(v1));
scenic::ViewHolder holder_2(client_1.session(), std::move(vh2), "2");
client_1.view()->AddChild(holder_2);
RequestToPresent(client_1.session());
SessionWrapper client_2 = CreateClient("view_2", std::move(v2));
RequestToPresent(client_2.session());
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_1.ViewKoid()));
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_2.ViewKoid()));
}
// Scene layout:
// root
// |
// view1
// |
// view2 - hit testing suppressed
TEST_F(ViewTreeInputIntegrationTest, IsInputSuppressed_ForSuppressedNode_ShouldReturnTrue) {
auto [v1, vh1] = scenic::ViewTokenPair::New();
auto [v2, vh2] = scenic::ViewTokenPair::New();
auto [root_session, root_resources] = CreateScene();
scenic::Session* const session = root_session.session();
scenic::Scene* const scene = &root_resources.scene;
scenic::ViewHolder holder_1(session, std::move(vh1), "1");
scene->AddChild(holder_1);
RequestToPresent(session);
SessionWrapper client_1 = CreateClient("view_1", std::move(v1));
scenic::ViewHolder holder_2(client_1.session(), std::move(vh2), "2");
holder_2.SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior::kSuppress);
client_1.view()->AddChild(holder_2);
RequestToPresent(client_1.session());
SessionWrapper client_2 = CreateClient("view_2", std::move(v2));
RequestToPresent(client_2.session());
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_1.ViewKoid()));
EXPECT_TRUE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_2.ViewKoid()));
}
// Scene layout:
// root
// |
// view1 - hit testing suppressed
// |
// view2
TEST_F(ViewTreeInputIntegrationTest,
IsInputSuppressed_ForDescendantOfSuppressedNode_ShouldReturnTrue) {
auto [v1, vh1] = scenic::ViewTokenPair::New();
auto [v2, vh2] = scenic::ViewTokenPair::New();
auto [root_session, root_resources] = CreateScene();
scenic::Session* const session = root_session.session();
scenic::Scene* const scene = &root_resources.scene;
scenic::ViewHolder holder_1(session, std::move(vh1), "1");
holder_1.SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior::kSuppress);
scene->AddChild(holder_1);
RequestToPresent(session);
SessionWrapper client_1 = CreateClient("view_1", std::move(v1));
scenic::ViewHolder holder_2(client_1.session(), std::move(vh2), "2");
client_1.view()->AddChild(holder_2);
RequestToPresent(client_1.session());
SessionWrapper client_2 = CreateClient("view_2", std::move(v2));
RequestToPresent(client_2.session());
EXPECT_TRUE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_1.ViewKoid()));
EXPECT_TRUE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_2.ViewKoid()));
}
// Scene layout:
// root
// |
// view1
// |
// view2 - hit testing suppressed, then not suppressed
TEST_F(ViewTreeInputIntegrationTest, IsInputSuppressed_AfterRemovingSuppression_ShouldReturnFalse) {
auto [v1, vh1] = scenic::ViewTokenPair::New();
auto [v2, vh2] = scenic::ViewTokenPair::New();
auto [root_session, root_resources] = CreateScene();
scenic::Session* const session = root_session.session();
scenic::Scene* const scene = &root_resources.scene;
scenic::ViewHolder holder_1(session, std::move(vh1), "1");
scene->AddChild(holder_1);
RequestToPresent(session);
SessionWrapper client_1 = CreateClient("view_1", std::move(v1));
scenic::ViewHolder holder_2(client_1.session(), std::move(vh2), "2");
holder_2.SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior::kSuppress);
client_1.view()->AddChild(holder_2);
RequestToPresent(client_1.session());
SessionWrapper client_2 = CreateClient("view_2", std::move(v2));
RequestToPresent(client_2.session());
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_1.ViewKoid()));
EXPECT_TRUE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_2.ViewKoid()));
// Remove hit testing suppression.
holder_2.SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior::kDefault);
RequestToPresent(client_1.session());
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_1.ViewKoid()));
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_2.ViewKoid()));
}
// Scene layout:
// root
// x <- disconnected
// view1
// |
// view2
TEST_F(ViewTreeInputIntegrationTest, IsInputSuppressed_AfterDisconnectFromScene_ShouldReturnFalse) {
auto [v1, vh1] = scenic::ViewTokenPair::New();
auto [v2, vh2] = scenic::ViewTokenPair::New();
auto [root_session, root_resources] = CreateScene();
scenic::Session* const session = root_session.session();
scenic::Scene* const scene = &root_resources.scene;
scenic::ViewHolder holder_1(session, std::move(vh1), "1");
scene->AddChild(holder_1);
RequestToPresent(session);
SessionWrapper client_1 = CreateClient("view_1", std::move(v1));
scenic::ViewHolder holder_2(client_1.session(), std::move(vh2), "2");
client_1.view()->AddChild(holder_2);
RequestToPresent(client_1.session());
SessionWrapper client_2 = CreateClient("view_2", std::move(v2));
RequestToPresent(client_2.session());
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_1.ViewKoid()));
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_2.ViewKoid()));
// Now disconnect.
scene->DetachChildren();
RequestToPresent(session);
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_1.ViewKoid()));
EXPECT_FALSE(engine()->scene_graph()->view_tree().IsInputSuppressed(client_2.ViewKoid()));
}
} // namespace
} // namespace lib_ui_input_tests