// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_DISPLAY_WIN_TEST_VIRTUAL_DISPLAY_UTIL_WIN_H_
#define UI_DISPLAY_WIN_TEST_VIRTUAL_DISPLAY_UTIL_WIN_H_
#include <vector>
#include "base/containers/flat_map.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "third_party/win_virtual_display/controller/display_driver_controller.h"
#include "third_party/win_virtual_display/driver/public/properties.h"
#include "ui/display/display_observer.h"
#include "ui/display/test/virtual_display_util.h"
#include "ui/gfx/geometry/size.h"
namespace display {
class Display;
class Screen;
namespace test {
struct DisplayParams;
// This interface creates system-level virtual displays to support the automated
// integration testing of display information and window management APIs in
// multi-screen device environments. It updates the displays that the normal
// windows screen impl sees.
class VirtualDisplayUtilWin : public display::DisplayObserver,
public VirtualDisplayUtil {
public:
explicit VirtualDisplayUtilWin(Screen* screen);
VirtualDisplayUtilWin(const VirtualDisplayUtilWin&) = delete;
VirtualDisplayUtilWin& operator=(const VirtualDisplayUtilWin&) = delete;
~VirtualDisplayUtilWin() override;
// Check whether the related drivers are available on the current system.
static bool IsAPIAvailable();
// VirtualDisplayUtil overrides:
int64_t AddDisplay(uint8_t id, const DisplayParams& display_params) override;
void RemoveDisplay(int64_t display_id) override;
void ResetDisplays() override;
static const DisplayParams k1920x1080;
static const DisplayParams k1024x768;
private:
// display::DisplayObserver:
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplaysRemoved(const display::Displays& removed_displays) override;
bool SetDriverProperties(DriverProperties properties);
void OnDisplayAddedOrRemoved(int64_t id);
// Start waiting for the detected displays to match `current_config_`.
void StartWaiting();
void StopWaiting();
raw_ptr<Screen> screen_;
// True if the environment was considered headless during initialization.
const bool is_headless_;
std::unique_ptr<base::RunLoop> run_loop_;
DisplayDriverController driver_controller_;
// Contains the last configuration that was set.
DriverProperties current_config_;
// Map of virtual display ID (product code) to corresponding display ID.
base::flat_map<unsigned short, int64_t> virtual_displays_;
// Copy of the display list when this utility was constructed.
std::vector<display::Display> initial_displays_;
};
// Utility that waits until desired display configs are observed.
// TODO(btriebw): Generalize this class and share it among VirtualDisplayUtil
// classes.
class DisplayConfigWaiter : public display::DisplayObserver {
public:
explicit DisplayConfigWaiter(Screen* screen);
DisplayConfigWaiter(const VirtualDisplayUtilWin&) = delete;
DisplayConfigWaiter& operator=(const VirtualDisplayUtilWin&) = delete;
~DisplayConfigWaiter() override;
// Waits until the display configuration equals the specified resolutions, in
// any arrangement.
void WaitForDisplaySizes(std::vector<gfx::Size> sizes);
private:
// display::DisplayObserver:
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplaysRemoved(const display::Displays& removed_displays) override;
// Checks if the wait condition is true that should end the wait loop.
bool IsWaitConditionMet();
raw_ptr<Screen> screen_;
std::unique_ptr<base::RunLoop> run_loop_;
std::vector<gfx::Size> wait_for_sizes_;
};
} // namespace test
} // namespace display
#endif // UI_DISPLAY_WIN_TEST_VIRTUAL_DISPLAY_UTIL_WIN_H_