blob: 32be57a7628de450f36af4d3267a7e05834628a7 [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_UI_TEST_REALM_UI_TEST_REALM_H_
#define SRC_UI_TESTING_UI_TEST_REALM_UI_TEST_REALM_H_
#include <lib/sys/component/cpp/testing/realm_builder.h>
#include <lib/sys/component/cpp/testing/realm_builder_types.h>
#include <lib/sys/cpp/service_directory.h>
#include <memory>
#include <optional>
#include "src/lib/fxl/macros.h"
namespace ui_testing {
// DPR constants.
constexpr auto kDefaultDevicePixelRatio = 1.f;
constexpr auto kMediumResolutionDevicePixelRatio = 1.25f;
constexpr auto kHighResolutionDevicePixelRatio = 2.f;
// Library class to manage test realm on behalf of UI integration test clients.
class UITestRealm {
public:
enum class AccessibilityOwnerType {
// Use the fake a11y manager. Clients should prefer using the fake a11y
// manager for tests that require a11y services, but do not test a11y
// functionality (e.g. tests that run a chromium client).
FAKE = 1,
// Use the real a11y manager. Clients should only use the real a11y manager
// for tests that exercise accessibility-specific functionality.
REAL = 2,
};
struct Config {
// Specifies whether scene manager owns the root of the scene.
// If false, then no scene owner will be present in the test realm.
//
// UITestManager assumes that scene manager serves input via input pipeline
// in addition to managing scene ownership. Therefore it exposes the
// following services out of the test from the top-level realm:
// * fuchsia.input.injection.InputDeviceRegistry
// * fuchsia.ui.policy.DeviceListenerRegistry
// * fuchsia.ui.pointerinjector.configuration.Setup
//
// Furthermore, if |use_scene_owner| is true, the client promises to expose
// fuchsia.ui.app.ViewProvider from its subrealm.
//
// If |use_scene_owner| is false, the top-level realm exposes the raw scenic
// input API:
// * fuchsia.ui.pointerinjector.Registry
bool use_scene_owner = false;
// Specifies the entity that owns accessibility in the test realm, if any.
// If std::nullopt, then no a11y services will be present in the test realm.
std::optional<AccessibilityOwnerType> accessibility_owner;
// List of ui services required by components in the client subrealm.
// UITestManager will route these services from the ui layer component to the
// client subrealm.
std::vector<std::string> ui_to_client_services;
// List of capabilities to pass-through from the parent to the client subrealm.
std::vector<component_testing::Capability> passthrough_capabilities;
// List of non-ui services the test manager needs to expose to the test fixture.
// By specifying services here, the client promises to expose them from its subrealm.
std::vector<std::string> exposed_client_services;
// List of client realm services to route to the ui layer component.
//
// *** Use cases for this field are ~very~ rare.
// *** This optoin will NOT be available to OOT clients.
std::vector<std::string> client_to_ui_services;
// Clockwise display rotation, in degrees. Display rotation MUST be a multiple of 90 degrees.
int display_rotation = 0;
// Device pixel ratio for the fake display.
//
// Must result in integer logical display dimensions.
float device_pixel_ratio = kDefaultDevicePixelRatio;
};
explicit UITestRealm(Config config);
~UITestRealm() = default;
// Adds a child to the realm under construction, and returns the new child.
// Must NOT be called after BuildRealm().
component_testing::Realm AddSubrealm();
// Calls realm_builder_.Build();
void Build();
// Calls realm_builder_.Teardown();
void Teardown(component_testing::ScopedChild::TeardownCallback on_teardown_complete);
// Returns a clone of the realm's exposed services directory.
// Clients should call this method once, and retain the handle returned.
//
// MUST be called AFTER Build().
std::unique_ptr<sys::ServiceDirectory> CloneExposedServicesDirectory();
const std::optional<component_testing::RealmRoot>& realm_root() const { return realm_root_; }
const Config& config() { return config_; }
private:
// Helper methods to configure the test realm.
void ConfigureClientSubrealm();
void ConfigureAccessibility();
void RouteConfigData();
void ConfigureScenic();
void ConfigureSceneOwner();
// Helper method to route a set of services from the specified source to the
// spceified targets.
void RouteServices(std::vector<std::string> services, component_testing::Ref source,
std::vector<component_testing::Ref> targets);
// Helper method to determine the component url used to instantiate the base
// UI realm.
std::string CalculateBaseRealmUrl();
Config config_;
component_testing::RealmBuilder realm_builder_ =
component_testing::RealmBuilder::CreateFromRelativeUrl(CalculateBaseRealmUrl());
std::optional<component_testing::RealmRoot> realm_root_;
// Some tests may not need a dedicated subrealm. Those clients will not call
// AddSubrealm(), so UITestManager will crash if it tries to add routes
// to/from the missing subrealm.
//
// NOTE: This piece of state is temporary, and can be removed once the client
// owns a full RealmBuilder instance, as opposed to a child realm.
bool has_client_subrealm_ = false;
// Add state as necessary.
FXL_DISALLOW_COPY_ASSIGN_AND_MOVE(UITestRealm);
};
} // namespace ui_testing
#endif // SRC_UI_TESTING_UI_TEST_REALM_UI_TEST_REALM_H_