blob: 2346bc8f22569b1b552e4b468bcaf1b98b1657cc [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.
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <fuchsia/ui/display/singleton/cpp/fidl.h>
#include <lib/async-loop/testing/cpp/real_loop.h>
#include <lib/async/cpp/task.h>
#include <lib/sys/component/cpp/testing/realm_builder.h>
#include <lib/syslog/cpp/macros.h>
#include <memory>
#include <zxtest/zxtest.h>
#include "src/ui/scenic/tests/utils/scenic_realm_builder.h"
namespace integration_tests {
using fuc_FlatlandDisplay = fuchsia::ui::composition::FlatlandDisplay;
using fuds_Metrics = fuchsia::ui::display::singleton::Metrics;
using fuds_Info = fuchsia::ui::display::singleton::Info;
using fuds_InfoPtr = fuchsia::ui::display::singleton::InfoPtr;
using RealmRoot = component_testing::RealmRoot;
// Max timeout in failure cases.
// Set this as low as you can that still works across all test platforms.
static constexpr zx::duration kTimeout = zx::min(5);
class SingletonDisplayIntegrationTest : public zxtest::Test, public loop_fixture::RealLoop {
protected:
SingletonDisplayIntegrationTest() = default;
void SetUp() override {
// Post a "just in case" quit task, if the test hangs.
async::PostDelayedTask(
dispatcher(),
[] { FX_LOGS(FATAL) << "\n\n>> Test did not complete in time, terminating. <<\n\n"; },
kTimeout);
realm_ = std::make_unique<RealmRoot>(ScenicRealmBuilder()
.AddRealmProtocol(fuds_Info::Name_)
.AddRealmProtocol(fuc_FlatlandDisplay::Name_)
.Build());
singleton_display_ = realm_->component().Connect<fuds_Info>();
singleton_display_.set_error_handler([](zx_status_t status) {
FAIL("Lost connection to SingletonDisplay: %s", zx_status_get_string(status));
});
}
std::unique_ptr<RealmRoot> realm_;
fuds_InfoPtr singleton_display_;
};
TEST_F(SingletonDisplayIntegrationTest, GetMetrics) {
std::optional<fuds_Metrics> metrics;
singleton_display_->GetMetrics([&metrics](fuds_Metrics di) { metrics = std::move(di); });
RunLoopUntil([&metrics] { return metrics.has_value(); });
// All of the expected values below are hard-coded within the "Fake HDCP component", except for
// the recommended_device_pixel_ratio, which is computed heuristically based on the other values.
ASSERT_TRUE(metrics->has_extent_in_px());
ASSERT_TRUE(metrics->has_extent_in_mm());
ASSERT_TRUE(metrics->has_recommended_device_pixel_ratio());
EXPECT_EQ(1280, metrics->extent_in_px().width);
EXPECT_EQ(800, metrics->extent_in_px().height);
EXPECT_EQ(160, metrics->extent_in_mm().width);
EXPECT_EQ(90, metrics->extent_in_mm().height);
EXPECT_EQ(1.f, metrics->recommended_device_pixel_ratio().x);
EXPECT_EQ(1.f, metrics->recommended_device_pixel_ratio().y);
EXPECT_EQ(60000, metrics->maximum_refresh_rate_in_millihertz());
}
TEST_F(SingletonDisplayIntegrationTest, DevicePixelRatioChange) {
auto flatland_display = realm_->component().Connect<fuc_FlatlandDisplay>();
const float kDPRx = 1.25f;
const float kDPRy = 1.25f;
flatland_display->SetDevicePixelRatio({kDPRx, kDPRy});
// FlatlandDisplay lives on a Flatland thread and SingletonDisplay lives on the main thread, so
// the update may not be sequential.
RunLoopUntil([this, kDPRx, kDPRy] {
std::optional<fuds_Metrics> metrics;
singleton_display_->GetMetrics([&metrics](fuds_Metrics di) { metrics = std::move(di); });
RunLoopUntil([&metrics] { return metrics.has_value(); });
return metrics->has_recommended_device_pixel_ratio() &&
kDPRx == metrics->recommended_device_pixel_ratio().x &&
kDPRy == metrics->recommended_device_pixel_ratio().y;
});
}
} // namespace integration_tests