blob: 9d2083235b2172b1aa96675ec187c1baf1be7e4b [file] [log] [blame]
// Copyright 2016 The Chromium 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 "services/ui/ws/test_utils.h"
#include <utility>
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "services/service_manager/public/mojom/connector.mojom.h"
#include "services/ui/common/image_cursors_set.h"
#include "services/ui/public/interfaces/cursor/cursor.mojom.h"
#include "services/ui/ws/cursor_location_manager.h"
#include "services/ui/ws/display_binding.h"
#include "services/ui/ws/display_creation_config.h"
#include "services/ui/ws/display_manager.h"
#include "services/ui/ws/test_gpu_host.h"
#include "services/ui/ws/threaded_image_cursors.h"
#include "services/ui/ws/threaded_image_cursors_factory.h"
#include "services/ui/ws/window_manager_access_policy.h"
#include "services/ui/ws/window_manager_window_tree_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/cursor/cursor.h"
#include "ui/gfx/geometry/dip_util.h"
namespace ui {
namespace ws {
namespace test {
namespace {
ClientWindowId NextUnusedClientWindowId(WindowTree* tree) {
for (ClientSpecificId id = kEmbedTreeWindowId;; ++id) {
// Used the id of the client in the upper bits to simplify things.
const ClientWindowId client_id = ClientWindowId(tree->id(), id);
if (!tree->GetWindowByClientId(client_id))
return client_id;
}
}
display::ViewportMetrics MakeViewportMetrics(const display::Display& display) {
gfx::Size pixel_size = gfx::ConvertSizeToPixel(display.device_scale_factor(),
display.bounds().size());
display::ViewportMetrics metrics;
metrics.bounds_in_pixels.set_size(pixel_size);
metrics.device_scale_factor = display.device_scale_factor();
metrics.ui_scale_factor = 1;
return metrics;
}
class TestThreadedImageCursorsFactory : public ThreadedImageCursorsFactory {
public:
TestThreadedImageCursorsFactory() {}
~TestThreadedImageCursorsFactory() override {}
// ThreadedImageCursorsFactory:
std::unique_ptr<ThreadedImageCursors> CreateCursors() override {
if (!resource_runner_) {
resource_runner_ = base::ThreadTaskRunnerHandle::Get();
image_cursors_set_ = std::make_unique<ui::ImageCursorsSet>();
}
return std::make_unique<ws::ThreadedImageCursors>(
resource_runner_, image_cursors_set_->GetWeakPtr());
}
private:
scoped_refptr<base::SingleThreadTaskRunner> resource_runner_;
std::unique_ptr<ui::ImageCursorsSet> image_cursors_set_;
DISALLOW_COPY_AND_ASSIGN(TestThreadedImageCursorsFactory);
};
} // namespace
// TestScreenManager -------------------------------------------------
TestScreenManager::TestScreenManager() {}
TestScreenManager::~TestScreenManager() {
display::Screen::SetScreenInstance(nullptr);
}
int64_t TestScreenManager::AddDisplay() {
return AddDisplay(
display::Display(display::kInvalidDisplayId, gfx::Rect(100, 100)));
}
int64_t TestScreenManager::AddDisplay(const display::Display& input_display) {
// Generate a unique display id.
int64_t display_id = display_ids_.empty() ? 1 : *display_ids_.rbegin() + 1;
display_ids_.insert(display_id);
display::Display display = input_display;
display.set_id(display_id);
// First display added will be the primary display.
display::DisplayList::Type type = display::DisplayList::Type::NOT_PRIMARY;
if (display_ids_.size() == 1)
type = display::DisplayList::Type::PRIMARY;
screen_->display_list().AddDisplay(display, type);
delegate_->OnDisplayAdded(display, MakeViewportMetrics(display));
if (type == display::DisplayList::Type::PRIMARY)
delegate_->OnPrimaryDisplayChanged(display_id);
return display_id;
}
void TestScreenManager::ModifyDisplay(
const display::Display& display,
const base::Optional<display::ViewportMetrics>& metrics) {
DCHECK(display_ids_.count(display.id()) == 1);
screen_->display_list().UpdateDisplay(display);
if (metrics)
delegate_->OnDisplayModified(display, *metrics);
else
delegate_->OnDisplayModified(display, MakeViewportMetrics(display));
}
void TestScreenManager::RemoveDisplay(int64_t display_id) {
DCHECK(display_ids_.count(display_id) == 1);
screen_->display_list().RemoveDisplay(display_id);
delegate_->OnDisplayRemoved(display_id);
display_ids_.erase(display_id);
}
void TestScreenManager::Init(display::ScreenManagerDelegate* delegate) {
delegate_ = delegate;
// Reset everything.
display_ids_.clear();
display::Screen::SetScreenInstance(nullptr);
screen_ = std::make_unique<display::ScreenBase>();
display::Screen::SetScreenInstance(screen_.get());
}
display::ScreenBase* TestScreenManager::GetScreen() {
return screen_.get();
}
// TestPlatformDisplayFactory -------------------------------------------------
TestPlatformDisplayFactory::TestPlatformDisplayFactory(
ui::CursorData* cursor_storage)
: cursor_storage_(cursor_storage) {}
TestPlatformDisplayFactory::~TestPlatformDisplayFactory() {}
std::unique_ptr<PlatformDisplay>
TestPlatformDisplayFactory::CreatePlatformDisplay(
ServerWindow* root_window,
const display::ViewportMetrics& metrics) {
return std::make_unique<TestPlatformDisplay>(metrics, cursor_storage_);
}
// WindowTreeTestApi ---------------------------------------------------------
WindowTreeTestApi::WindowTreeTestApi(WindowTree* tree) : tree_(tree) {}
WindowTreeTestApi::~WindowTreeTestApi() {}
void WindowTreeTestApi::StartPointerWatcher(bool want_moves) {
tree_->StartPointerWatcher(want_moves);
}
void WindowTreeTestApi::StopPointerWatcher() {
tree_->StopPointerWatcher();
}
// EventDispatcherTestApi ----------------------------------------------------
bool EventDispatcherTestApi::IsWindowPointerTarget(
const ServerWindow* window) const {
for (const auto& pair : ed_->pointer_targets_) {
if (pair.second.window == window)
return true;
}
return false;
}
int EventDispatcherTestApi::NumberPointerTargetsForWindow(
ServerWindow* window) {
int count = 0;
for (const auto& pair : ed_->pointer_targets_)
if (pair.second.window == window)
count++;
return count;
}
bool EventDispatcherTestApi::IsObservingWindow(ServerWindow* window) {
return ed_->observed_windows_.count(window) > 0;
}
// TestDisplayBinding ---------------------------------------------------------
WindowTree* TestDisplayBinding::CreateWindowTree(ServerWindow* root) {
const uint32_t embed_flags = 0;
WindowTree* tree = window_server_->EmbedAtWindow(
root, ui::mojom::WindowTreeClientPtr(), embed_flags,
base::WrapUnique(new WindowManagerAccessPolicy));
WindowTreeTestApi(tree).set_is_for_embedding(false);
tree->ConfigureWindowManager(automatically_create_display_roots_);
return tree;
}
// TestWindowManager ----------------------------------------------------------
TestWindowManager::TestWindowManager() {}
TestWindowManager::~TestWindowManager() {}
void TestWindowManager::OnConnect() {
connect_count_++;
}
void TestWindowManager::WmOnAcceleratedWidgetForDisplay(
int64_t display,
gpu::SurfaceHandle surface_handle) {}
void TestWindowManager::WmNewDisplayAdded(
const display::Display& display,
ui::mojom::WindowDataPtr root,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
display_added_count_++;
}
void TestWindowManager::WmDisplayRemoved(int64_t display_id) {
got_display_removed_ = true;
display_removed_id_ = display_id;
}
void TestWindowManager::WmSetModalType(Id window_id, ui::ModalType type) {
on_set_modal_type_called_ = true;
}
void TestWindowManager::WmCreateTopLevelWindow(
uint32_t change_id,
const viz::FrameSinkId& frame_sink_id,
const std::unordered_map<std::string, std::vector<uint8_t>>& properties) {
got_create_top_level_window_ = true;
change_id_ = change_id;
}
void TestWindowManager::WmClientJankinessChanged(ClientSpecificId client_id,
bool janky) {}
void TestWindowManager::WmBuildDragImage(const gfx::Point& screen_location,
const SkBitmap& drag_image,
const gfx::Vector2d& drag_image_offset,
ui::mojom::PointerKind source) {}
void TestWindowManager::WmMoveDragImage(const gfx::Point& screen_location,
WmMoveDragImageCallback callback) {
std::move(callback).Run();
}
void TestWindowManager::WmDestroyDragImage() {}
void TestWindowManager::WmPerformMoveLoop(uint32_t change_id,
Id window_id,
mojom::MoveLoopSource source,
const gfx::Point& cursor_location) {
on_perform_move_loop_called_ = true;
}
void TestWindowManager::WmCancelMoveLoop(uint32_t change_id) {}
void TestWindowManager::WmDeactivateWindow(Id window_id) {}
void TestWindowManager::WmStackAbove(uint32_t change_id,
Id above_id,
Id below_id) {}
void TestWindowManager::WmStackAtTop(uint32_t change_id, Id window_id) {}
void TestWindowManager::WmPerformWmAction(Id window_id,
const std::string& action) {
last_wm_action_ = action;
}
void TestWindowManager::OnAccelerator(uint32_t ack_id,
uint32_t accelerator_id,
std::unique_ptr<ui::Event> event) {
on_accelerator_called_ = true;
on_accelerator_id_ = accelerator_id;
}
void TestWindowManager::OnCursorTouchVisibleChanged(bool enabled) {}
void TestWindowManager::OnEventBlockedByModalWindow(Id window_id) {}
// TestWindowTreeClient -------------------------------------------------------
TestWindowTreeClient::TestWindowTreeClient()
: binding_(this), record_on_change_completed_(false) {}
TestWindowTreeClient::~TestWindowTreeClient() {}
void TestWindowTreeClient::Bind(
mojo::InterfaceRequest<mojom::WindowTreeClient> request) {
binding_.Bind(std::move(request));
}
void TestWindowTreeClient::OnEmbed(
mojom::WindowDataPtr root,
ui::mojom::WindowTreePtr tree,
int64_t display_id,
Id focused_window_id,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
// TODO(sky): add test coverage of |focused_window_id|.
tracker_.OnEmbed(std::move(root), drawn);
}
void TestWindowTreeClient::OnEmbeddedAppDisconnected(Id window) {
tracker_.OnEmbeddedAppDisconnected(window);
}
void TestWindowTreeClient::OnUnembed(Id window_id) {
tracker_.OnUnembed(window_id);
}
void TestWindowTreeClient::OnCaptureChanged(Id new_capture_window_id,
Id old_capture_window_id) {
tracker_.OnCaptureChanged(new_capture_window_id, old_capture_window_id);
}
void TestWindowTreeClient::OnFrameSinkIdAllocated(
Id window_id,
const viz::FrameSinkId& frame_sink_id) {
tracker_.OnFrameSinkIdAllocated(window_id, frame_sink_id);
}
void TestWindowTreeClient::OnTopLevelCreated(
uint32_t change_id,
mojom::WindowDataPtr data,
int64_t display_id,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
tracker_.OnTopLevelCreated(change_id, std::move(data), drawn);
}
void TestWindowTreeClient::OnWindowBoundsChanged(
Id window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
tracker_.OnWindowBoundsChanged(window, std::move(old_bounds),
std::move(new_bounds), local_surface_id);
}
void TestWindowTreeClient::OnWindowTransformChanged(
Id window,
const gfx::Transform& old_transform,
const gfx::Transform& new_transform) {}
void TestWindowTreeClient::OnClientAreaChanged(
Id window_id,
const gfx::Insets& new_client_area,
const std::vector<gfx::Rect>& new_additional_client_areas) {}
void TestWindowTreeClient::OnTransientWindowAdded(Id window_id,
Id transient_window_id) {}
void TestWindowTreeClient::OnTransientWindowRemoved(Id window_id,
Id transient_window_id) {}
void TestWindowTreeClient::OnWindowHierarchyChanged(
Id window,
Id old_parent,
Id new_parent,
std::vector<mojom::WindowDataPtr> windows) {
tracker_.OnWindowHierarchyChanged(window, old_parent, new_parent,
std::move(windows));
}
void TestWindowTreeClient::OnWindowReordered(Id window_id,
Id relative_window_id,
mojom::OrderDirection direction) {
tracker_.OnWindowReordered(window_id, relative_window_id, direction);
}
void TestWindowTreeClient::OnWindowDeleted(Id window) {
tracker_.OnWindowDeleted(window);
}
void TestWindowTreeClient::OnWindowVisibilityChanged(Id window, bool visible) {
tracker_.OnWindowVisibilityChanged(window, visible);
}
void TestWindowTreeClient::OnWindowOpacityChanged(Id window,
float old_opacity,
float new_opacity) {
tracker_.OnWindowOpacityChanged(window, new_opacity);
}
void TestWindowTreeClient::OnWindowParentDrawnStateChanged(Id window,
bool drawn) {
tracker_.OnWindowParentDrawnStateChanged(window, drawn);
}
void TestWindowTreeClient::OnWindowSharedPropertyChanged(
Id window,
const std::string& name,
const base::Optional<std::vector<uint8_t>>& new_data) {
tracker_.OnWindowSharedPropertyChanged(window, name, new_data);
}
void TestWindowTreeClient::OnWindowInputEvent(
uint32_t event_id,
Id window,
int64_t display_id,
Id display_root_window,
const gfx::PointF& event_location_in_screen_pixel_layout,
std::unique_ptr<ui::Event> event,
bool matches_pointer_watcher) {
tracker_.OnWindowInputEvent(window, *event.get(), display_id,
event_location_in_screen_pixel_layout,
matches_pointer_watcher);
}
void TestWindowTreeClient::OnPointerEventObserved(
std::unique_ptr<ui::Event> event,
Id window_id,
int64_t display_id) {
tracker_.OnPointerEventObserved(*event.get(), window_id);
}
void TestWindowTreeClient::OnWindowFocused(Id focused_window_id) {
tracker_.OnWindowFocused(focused_window_id);
}
void TestWindowTreeClient::OnWindowCursorChanged(Id window_id,
ui::CursorData cursor) {
tracker_.OnWindowCursorChanged(window_id, cursor);
}
void TestWindowTreeClient::OnWindowSurfaceChanged(
Id window_id,
const viz::SurfaceInfo& surface_info) {}
void TestWindowTreeClient::OnDragDropStart(
const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) {}
void TestWindowTreeClient::OnDragEnter(Id window,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
const OnDragEnterCallback& callback) {}
void TestWindowTreeClient::OnDragOver(Id window,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
const OnDragOverCallback& callback) {}
void TestWindowTreeClient::OnDragLeave(Id window) {}
void TestWindowTreeClient::OnCompleteDrop(
Id window,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
const OnCompleteDropCallback& callback) {}
void TestWindowTreeClient::OnPerformDragDropCompleted(uint32_t change_id,
bool success,
uint32_t action_taken) {}
void TestWindowTreeClient::OnDragDropDone() {}
void TestWindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
if (record_on_change_completed_)
tracker_.OnChangeCompleted(change_id, success);
}
void TestWindowTreeClient::RequestClose(Id window_id) {}
void TestWindowTreeClient::GetWindowManager(
mojo::AssociatedInterfaceRequest<mojom::WindowManager> internal) {}
// TestWindowTreeBinding ------------------------------------------------------
TestWindowTreeBinding::TestWindowTreeBinding(
WindowTree* tree,
std::unique_ptr<TestWindowTreeClient> client)
: WindowTreeBinding(client.get()),
tree_(tree),
client_(std::move(client)) {}
TestWindowTreeBinding::~TestWindowTreeBinding() {}
mojom::WindowManager* TestWindowTreeBinding::GetWindowManager() {
if (!window_manager_.get())
window_manager_ = std::make_unique<TestWindowManager>();
return window_manager_.get();
}
void TestWindowTreeBinding::SetIncomingMethodCallProcessingPaused(bool paused) {
is_paused_ = paused;
}
mojom::WindowTreeClient* TestWindowTreeBinding::CreateClientForShutdown() {
DCHECK(!client_after_reset_);
client_after_reset_ = std::make_unique<TestWindowTreeClient>();
return client_after_reset_.get();
}
// TestWindowServerDelegate ----------------------------------------------
TestWindowServerDelegate::TestWindowServerDelegate()
: threaded_image_cursors_factory_(
std::make_unique<TestThreadedImageCursorsFactory>()) {}
TestWindowServerDelegate::~TestWindowServerDelegate() {}
TestWindowTreeBinding* TestWindowServerDelegate::Embed(WindowTree* tree,
ServerWindow* window,
int flags) {
mojom::WindowTreeClientPtr client;
mojom::WindowTreeClientRequest client_request = mojo::MakeRequest(&client);
ClientWindowId client_window_id;
if (!tree->IsWindowKnown(window, &client_window_id))
return nullptr;
tree->Embed(client_window_id, std::move(client), flags);
last_client()->Bind(std::move(client_request));
return last_binding();
}
void TestWindowServerDelegate::StartDisplayInit() {}
void TestWindowServerDelegate::OnNoMoreDisplays() {
got_on_no_more_displays_ = true;
}
std::unique_ptr<WindowTreeBinding>
TestWindowServerDelegate::CreateWindowTreeBinding(
BindingType type,
ws::WindowServer* window_server,
ws::WindowTree* tree,
mojom::WindowTreeRequest* tree_request,
mojom::WindowTreeClientPtr* client) {
std::unique_ptr<TestWindowTreeBinding> binding =
std::make_unique<TestWindowTreeBinding>(tree);
bindings_.push_back(binding.get());
return std::move(binding);
}
bool TestWindowServerDelegate::IsTestConfig() const {
return true;
}
void TestWindowServerDelegate::OnWillCreateTreeForWindowManager(
bool automatically_create_display_roots) {
if (window_server_->display_creation_config() !=
DisplayCreationConfig::UNKNOWN) {
return;
}
window_server_->SetDisplayCreationConfig(
automatically_create_display_roots ? DisplayCreationConfig::AUTOMATIC
: DisplayCreationConfig::MANUAL);
}
ThreadedImageCursorsFactory*
TestWindowServerDelegate::GetThreadedImageCursorsFactory() {
return threaded_image_cursors_factory_.get();
}
// WindowServerTestHelper ---------------------------------------------------
WindowServerTestHelper::WindowServerTestHelper()
: cursor_(ui::CursorType::kNull), platform_display_factory_(&cursor_) {
// Some tests create their own message loop, for example to add a task runner.
if (!base::MessageLoop::current())
message_loop_ = std::make_unique<base::MessageLoop>();
PlatformDisplay::set_factory_for_testing(&platform_display_factory_);
window_server_ = std::make_unique<WindowServer>(&window_server_delegate_,
true /* should_host_viz */);
std::unique_ptr<GpuHost> gpu_host = std::make_unique<TestGpuHost>();
window_server_->SetGpuHost(std::move(gpu_host));
window_server_delegate_.set_window_server(window_server_.get());
}
WindowServerTestHelper::~WindowServerTestHelper() {
// Destroy |window_server_| while the message-loop is still alive.
window_server_.reset();
}
// WindowEventTargetingHelper ------------------------------------------------
WindowEventTargetingHelper::WindowEventTargetingHelper(
bool automatically_create_display_roots) {
display_ = new Display(window_server());
display_binding_ = new TestDisplayBinding(window_server(),
automatically_create_display_roots);
display_->Init(display::ViewportMetrics(),
base::WrapUnique(display_binding_));
wm_client_ = ws_test_helper_.window_server_delegate()->last_client();
wm_client_->tracker()->changes()->clear();
}
WindowEventTargetingHelper::~WindowEventTargetingHelper() {}
ServerWindow* WindowEventTargetingHelper::CreatePrimaryTree(
const gfx::Rect& root_window_bounds,
const gfx::Rect& window_bounds) {
WindowTree* wm_tree = window_server()->GetTreeWithId(kWindowManagerClientId);
const ClientWindowId embed_window_id(wm_tree->id(),
next_primary_tree_window_id_++);
EXPECT_TRUE(wm_tree->NewWindow(embed_window_id, ServerWindow::Properties()));
EXPECT_TRUE(wm_tree->SetWindowVisibility(embed_window_id, true));
EXPECT_TRUE(wm_tree->AddWindow(FirstRootId(wm_tree), embed_window_id));
display_->root_window()->SetBounds(root_window_bounds, base::nullopt);
mojom::WindowTreeClientPtr client;
ws_test_helper_.window_server_delegate()->last_client()->Bind(
mojo::MakeRequest(&client));
const uint32_t embed_flags = 0;
wm_tree->Embed(embed_window_id, std::move(client), embed_flags);
ServerWindow* embed_window = wm_tree->GetWindowByClientId(embed_window_id);
embed_window->set_event_targeting_policy(
mojom::EventTargetingPolicy::DESCENDANTS_ONLY);
WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window);
WindowTreeTestApi(tree1).set_is_for_embedding(false);
EXPECT_NE(nullptr, tree1);
EXPECT_NE(tree1, wm_tree);
embed_window->SetBounds(window_bounds, base::nullopt);
return embed_window;
}
void WindowEventTargetingHelper::CreateSecondaryTree(
ServerWindow* embed_window,
const gfx::Rect& window_bounds,
TestWindowTreeClient** out_client,
WindowTree** window_tree,
ServerWindow** window) {
WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window);
ASSERT_TRUE(tree1 != nullptr);
const ClientWindowId child1_id(tree1->id(), kEmbedTreeWindowId);
ASSERT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties()));
ServerWindow* child1 = tree1->GetWindowByClientId(child1_id);
ASSERT_TRUE(child1);
EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window),
child1_id));
embed_window->set_is_activation_parent(true);
child1->SetVisible(true);
child1->SetBounds(window_bounds, base::nullopt);
TestWindowTreeClient* embed_client =
ws_test_helper_.window_server_delegate()->last_client();
embed_client->tracker()->changes()->clear();
wm_client_->tracker()->changes()->clear();
*out_client = embed_client;
*window_tree = tree1;
*window = child1;
}
void WindowEventTargetingHelper::SetTaskRunner(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
base::MessageLoop::current()->SetTaskRunner(task_runner);
}
// ----------------------------------------------------------------------------
TestDisplayManagerObserver::TestDisplayManagerObserver() : binding_(this) {}
TestDisplayManagerObserver::~TestDisplayManagerObserver() = default;
mojom::DisplayManagerObserverPtr TestDisplayManagerObserver::GetPtr() {
mojom::DisplayManagerObserverPtr ptr;
binding_.Bind(mojo::MakeRequest(&ptr));
return ptr;
}
std::string TestDisplayManagerObserver::GetAndClearObserverCalls() {
std::string result;
std::swap(observer_calls_, result);
return result;
}
std::string TestDisplayManagerObserver::DisplayIdsToString(
const std::vector<mojom::WsDisplayPtr>& wm_displays) {
std::string display_ids;
for (const auto& wm_display : wm_displays) {
if (!display_ids.empty())
display_ids += " ";
display_ids += base::Int64ToString(wm_display->display.id());
}
return display_ids;
}
void TestDisplayManagerObserver::OnDisplaysChanged(
std::vector<mojom::WsDisplayPtr> displays,
int64_t primary_display_id,
int64_t internal_display_id) {
if (!observer_calls_.empty())
observer_calls_ += "\n";
observer_calls_ += "OnDisplaysChanged " + DisplayIdsToString(displays);
observer_calls_ += " " + base::Int64ToString(internal_display_id);
}
// -----------------------------------------------------------------------------
TestPlatformDisplay::TestPlatformDisplay(
const display::ViewportMetrics& metrics,
ui::CursorData* cursor_storage)
: metrics_(metrics), cursor_storage_(cursor_storage) {}
TestPlatformDisplay::~TestPlatformDisplay() = default;
// PlatformDisplay:
void TestPlatformDisplay::Init(PlatformDisplayDelegate* delegate) {
delegate->OnAcceleratedWidgetAvailable();
}
void TestPlatformDisplay::SetViewportSize(const gfx::Size& size) {}
void TestPlatformDisplay::SetTitle(const base::string16& title) {}
void TestPlatformDisplay::SetCapture() {
has_capture_ = true;
}
void TestPlatformDisplay::ReleaseCapture() {
has_capture_ = false;
}
void TestPlatformDisplay::SetCursor(const ui::CursorData& cursor) {
*cursor_storage_ = cursor;
}
void TestPlatformDisplay::SetCursorSize(const ui::CursorSize& cursor_size) {}
void TestPlatformDisplay::ConfineCursorToBounds(const gfx::Rect& pixel_bounds) {
confine_cursor_bounds_ = pixel_bounds;
}
void TestPlatformDisplay::MoveCursorTo(
const gfx::Point& window_pixel_location) {}
void TestPlatformDisplay::UpdateTextInputState(
const ui::TextInputState& state) {}
void TestPlatformDisplay::SetImeVisibility(bool visible) {}
void TestPlatformDisplay::UpdateViewportMetrics(
const display::ViewportMetrics& metrics) {
metrics_ = metrics;
}
const display::ViewportMetrics& TestPlatformDisplay::GetViewportMetrics() {
return metrics_;
}
gfx::AcceleratedWidget TestPlatformDisplay::GetAcceleratedWidget() const {
return gfx::kNullAcceleratedWidget;
}
FrameGenerator* TestPlatformDisplay::GetFrameGenerator() {
return nullptr;
}
EventSink* TestPlatformDisplay::GetEventSink() {
return nullptr;
}
void TestPlatformDisplay::SetCursorConfig(display::Display::Rotation rotation,
float scale) {
cursor_scale_ = scale;
}
// -----------------------------------------------------------------------------
CursorLocationManagerTestApi::CursorLocationManagerTestApi(
CursorLocationManager* cursor_location_manager)
: cursor_location_manager_(cursor_location_manager) {}
CursorLocationManagerTestApi::~CursorLocationManagerTestApi() = default;
base::subtle::Atomic32 CursorLocationManagerTestApi::current_cursor_location() {
return cursor_location_manager_->current_cursor_location_;
}
// -----------------------------------------------------------------------------
void AddWindowManager(WindowServer* window_server,
bool automatically_create_display_roots) {
window_server->window_manager_window_tree_factory()->CreateWindowTree(
nullptr, nullptr, automatically_create_display_roots);
}
display::Display MakeDisplay(int origin_x,
int origin_y,
int width_pixels,
int height_pixels,
float scale_factor) {
gfx::Size scaled_size = gfx::ConvertSizeToDIP(
scale_factor, gfx::Size(width_pixels, height_pixels));
gfx::Rect bounds(gfx::Point(origin_x, origin_y), scaled_size);
display::Display display;
display.set_bounds(bounds);
display.set_work_area(bounds);
display.set_device_scale_factor(scale_factor);
return display;
}
ServerWindow* FirstRoot(WindowTree* tree) {
return tree->roots().size() == 1u
? const_cast<ServerWindow*>(*(tree->roots().begin()))
: nullptr;
}
ClientWindowId FirstRootId(WindowTree* tree) {
ServerWindow* first_root = FirstRoot(tree);
return first_root ? ClientWindowIdForWindow(tree, first_root)
: ClientWindowId();
}
ClientWindowId ClientWindowIdForWindow(WindowTree* tree,
const ServerWindow* window) {
ClientWindowId client_window_id;
// If window isn't known we'll return 0, which should then error out.
tree->IsWindowKnown(window, &client_window_id);
return client_window_id;
}
ServerWindow* NewWindowInTree(WindowTree* tree, ClientWindowId* client_id) {
return NewWindowInTreeWithParent(tree, FirstRoot(tree), client_id);
}
ServerWindow* NewWindowInTreeWithParent(WindowTree* tree,
ServerWindow* parent,
ClientWindowId* client_id,
const gfx::Rect& bounds) {
if (!parent)
return nullptr;
ClientWindowId parent_client_id;
if (!tree->IsWindowKnown(parent, &parent_client_id))
return nullptr;
ClientWindowId client_window_id = NextUnusedClientWindowId(tree);
if (!tree->NewWindow(client_window_id, ServerWindow::Properties()))
return nullptr;
if (!tree->SetWindowVisibility(client_window_id, true))
return nullptr;
if (!tree->AddWindow(parent_client_id, client_window_id))
return nullptr;
ServerWindow* window = tree->GetWindowByClientId(client_window_id);
window->SetBounds(bounds);
if (client_id)
*client_id = client_window_id;
return window;
}
gfx::Point Atomic32ToPoint(base::subtle::Atomic32 atomic) {
return gfx::Point(static_cast<int16_t>(atomic >> 16),
static_cast<int16_t>(atomic & 0xFFFF));
}
} // namespace test
} // namespace ws
} // namespace ui