ui-controls: Add client implementation for display protocol
Add client implementation for updating displays for lacros tests. The
client implementation uses ManagedDisplayInfo to parse display specs
and passed them to ash server. New API functions are added in
ui_controls to be use for interactive_ui_test.
Bug: 1408512, b:302179948
Change-Id: Ic67fd05ca64a2a3ed2e38325308bd22c4bde6f0a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4969287
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Vincent Chiang <vincentchiang@google.com>
Cr-Commit-Position: refs/heads/main@{#1251750}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 1d5b7e9f7..d31f8ad 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -11409,7 +11409,10 @@
sources -=
[ "../browser/notifications/notification_interactive_uitest.cc" ]
- deps += [ ":lacros_test_support_ui" ]
+ deps += [
+ ":lacros_test_support_ui",
+ "//ui/display:managed_display_info",
+ ]
}
if (is_win) {
diff --git a/ui/base/test/ui_controls.h b/ui/base/test/ui_controls.h
index ad95e7f..ef9a75df 100644
--- a/ui/base/test/ui_controls.h
+++ b/ui/base/test/ui_controls.h
@@ -5,6 +5,9 @@
#ifndef UI_BASE_TEST_UI_CONTROLS_H_
#define UI_BASE_TEST_UI_CONTROLS_H_
+#include <cstdint>
+#include <string>
+
#include "base/functional/callback_forward.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
@@ -204,6 +207,14 @@
bool IsFullKeyboardAccessEnabled();
#endif
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+// TODO(vincentchiang): Move to another test API file.
+// Update the test display configurations in accordance to the passed in
+// |display_specs| which is a comma separated list of display specs. See
+// ash::DisplayManagerTestApi::UpdateDisplay for detail.
+void UpdateDisplaySync(const std::string& display_specs);
+#endif
+
} // namespace ui_controls
#endif // UI_BASE_TEST_UI_CONTROLS_H_
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn
index 4711b70..9e75feaf 100644
--- a/ui/display/BUILD.gn
+++ b/ui/display/BUILD.gn
@@ -147,6 +147,36 @@
}
}
+if (is_chromeos_lacros) {
+ component("managed_display_info") {
+ testonly = true
+ sources = [
+ "manager/managed_display_info.cc",
+ "manager/managed_display_info.h",
+ "manager/util/display_manager_test_util.cc",
+ "manager/util/display_manager_test_util.h",
+ "manager/util/display_manager_util.cc",
+ "manager/util/display_manager_util.h",
+ ]
+
+ configs += [ "//build/config/compiler:wexit_time_destructors" ]
+
+ public_deps = [ "//ui/display" ]
+
+ deps = [
+ "//base",
+ "//build:chromeos_buildflags",
+ "//ui/base:base",
+ "//ui/display",
+ "//ui/display/types",
+ "//ui/display/util",
+ "//ui/display/util",
+ ]
+
+ defines = [ "DISPLAY_MANAGER_IMPLEMENTATION" ]
+ }
+}
+
if (is_chromeos_ash) {
component("display_manager_test_api") {
testonly = true
@@ -163,6 +193,7 @@
"//base",
"//build:chromeos_buildflags",
"//ui/display",
+ "//ui/display:test_support",
"//ui/display/types",
"//ui/display/util",
]
@@ -217,6 +248,10 @@
]
}
+ if (is_chromeos) {
+ sources += [ "test/display_test_util.cc" ]
+ }
+
if (is_chromeos_ash) {
sources += [
"manager/test/action_logger.cc",
@@ -239,6 +274,10 @@
configs += [ "//build/config/compiler:wexit_time_destructors" ]
public_deps += [ "//ui/display/manager" ]
}
+
+ if (is_chromeos_lacros) {
+ public_deps += [ "//ui/display:managed_display_info" ]
+ }
}
# This test covers all testable components in display.
diff --git a/ui/display/test/display_manager_test_api.cc b/ui/display/test/display_manager_test_api.cc
index ec7387a..6d1c3b9a 100644
--- a/ui/display/test/display_manager_test_api.cc
+++ b/ui/display/test/display_manager_test_api.cc
@@ -16,6 +16,7 @@
#include "ui/display/manager/managed_display_info.h"
#include "ui/display/manager/util/display_manager_test_util.h"
#include "ui/display/screen.h"
+#include "ui/display/test/display_test_util.h"
#include "ui/display/util/display_util.h"
namespace display {
@@ -28,24 +29,11 @@
DisplayInfoList CreateDisplayInfoListFromString(const std::string specs,
DisplayManager* display_manager,
bool generate_new_ids) {
- DisplayInfoList display_info_list;
- std::vector<std::string> parts = base::SplitString(
- specs, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- size_t index = 0;
-
Displays list = display_manager->IsInUnifiedMode()
? display_manager->software_mirroring_display_list()
: display_manager->active_display_list();
- for (std::vector<std::string>::const_iterator iter = parts.begin();
- iter != parts.end(); ++iter, ++index) {
- const int64_t id = (index < list.size() && !generate_new_ids)
- ? list[index].id()
- : kInvalidDisplayId;
- display_info_list.push_back(
- ManagedDisplayInfo::CreateFromSpecWithID(*iter, id));
- }
- return display_info_list;
+ return CreateDisplayInfoListFromSpecs(specs, list, generate_new_ids);
}
// Gets the display |mode| for |resolution|. Returns false if no display
diff --git a/ui/display/test/display_test_util.cc b/ui/display/test/display_test_util.cc
new file mode 100644
index 0000000..ba0fcf6
--- /dev/null
+++ b/ui/display/test/display_test_util.cc
@@ -0,0 +1,34 @@
+// 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.
+
+#include "ui/display/test/display_test_util.h"
+
+#include <cstdint>
+
+#include "base/strings/string_split.h"
+#include "ui/display/manager/managed_display_info.h"
+
+namespace display {
+
+std::vector<ManagedDisplayInfo> CreateDisplayInfoListFromSpecs(
+ const std::string& display_specs,
+ const std::vector<Display>& existing_displays,
+ bool generate_new_ids) {
+ auto display_info_list = std::vector<ManagedDisplayInfo>();
+ std::vector<std::string> parts = base::SplitString(
+ display_specs, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ size_t index = 0;
+
+ for (const auto& part : parts) {
+ int64_t id = (index < existing_displays.size() && !generate_new_ids)
+ ? existing_displays[index].id()
+ : kInvalidDisplayId;
+ display_info_list.push_back(
+ ManagedDisplayInfo::CreateFromSpecWithID(part, id));
+ ++index;
+ }
+ return display_info_list;
+}
+
+} // namespace display
diff --git a/ui/display/test/display_test_util.h b/ui/display/test/display_test_util.h
index 97662e7..7320945 100644
--- a/ui/display/test/display_test_util.h
+++ b/ui/display/test/display_test_util.h
@@ -5,9 +5,18 @@
#ifndef UI_DISPLAY_TEST_DISPLAY_TEST_UTIL_H_
#define UI_DISPLAY_TEST_DISPLAY_TEST_UTIL_H_
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
#include "ui/display/display.h"
#include "ui/display/util/display_util.h"
+#if BUILDFLAG(IS_CHROMEOS)
+#include "ui/display/manager/managed_display_info.h"
+#endif
+
namespace display {
// Use this class instead of calling `SetInternalDisplayIds()` in unit tests to
@@ -30,6 +39,15 @@
*os << display.ToString();
}
+#if BUILDFLAG(IS_CHROMEOS)
+// Create a list of ManagedDisplayInfo from the string specs.
+// If a list of existing displays are present, the function will
+// reuse the display ID.
+DISPLAY_EXPORT std::vector<ManagedDisplayInfo> CreateDisplayInfoListFromSpecs(
+ const std::string& display_specs,
+ const std::vector<Display>& existing_displays,
+ bool generate_new_ids);
+#endif
} // namespace display
#endif // UI_DISPLAY_TEST_DISPLAY_TEST_UTIL_H_
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index d3dc3c7..dfed9cc 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -707,6 +707,7 @@
"//third_party/wayland-protocols:ui_controls_protocol",
"//third_party/wayland-protocols:xdg_shell_protocol",
"//ui/base:test_support",
+ "//ui/display:test_support",
"//ui/events",
"//ui/events:dom_keycode_converter",
"//ui/events:test_support",
diff --git a/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc b/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc
index 089dba4..d2375250 100644
--- a/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc
+++ b/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc
@@ -7,8 +7,13 @@
#include <ui-controls-unstable-v1-client-protocol.h>
#include <wayland-client-protocol.h>
+#include <cstdint>
+#include <string>
+
#include "base/logging.h"
#include "ui/base/test/ui_controls.h"
+#include "ui/display/display.h"
+#include "ui/display/types/display_constants.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/ozone/platform/wayland/host/shell_toplevel_wrapper.h"
#include "ui/ozone/platform/wayland/host/wayland_popup.h"
@@ -18,8 +23,14 @@
#include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h"
#include "ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h"
+#if BUILDFLAG(IS_CHROMEOS)
+#include "ui/display/manager/managed_display_info.h"
+#include "ui/display/test/display_test_util.h"
+#endif
+
namespace {
+// TODO(b/302179948) Increment version once server change hits beta.
// send_key_events() is only available since version 2.
constexpr uint32_t kMinVersion = 2;
@@ -54,7 +65,7 @@
}
static constexpr wl_registry_listener kRegistryListener = {
- .global = &OnGlobal, .global_remove = nullptr};
+ .global = &OnGlobal, .global_remove = &OnGlobalRemove};
wl_registry_add_listener(registry_, &kRegistryListener, this);
// Roundtrip one time to get the ui_controls global.
@@ -225,11 +236,39 @@
zcr_ui_controls_v1_send_touch(
ui_controls_, action, touch_id, touch_screen_location.x(),
touch_screen_location.y(), /*surface=*/nullptr, request_id);
-
auto* wayland_proxy = wl::WaylandProxy::GetInstance();
wayland_proxy->FlushForTesting();
}
+#if BUILDFLAG(IS_CHROMEOS)
+void WaylandInputEmulate::EmulateUpdateDisplay(const std::string& display_specs,
+ uint32_t request_id) {
+ VLOG(1) << "Updating display specs to: " << display_specs;
+ if (zcr_ui_controls_v1_get_version(ui_controls_) >=
+ ZCR_UI_CONTROLS_V1_DISPLAY_INFO_LIST_DONE_SINCE_VERSION) {
+ auto info_list = display::CreateDisplayInfoListFromSpecs(
+ display_specs, std::vector<display::Display>(), false);
+
+ for (const auto& pending_display : info_list) {
+ zcr_ui_controls_v1_set_display_info_size(
+ ui_controls_, pending_display.bounds_in_native().width(),
+ pending_display.bounds_in_native().height());
+
+ float device_scale_factor = pending_display.device_scale_factor();
+ uint32_t scale_factor_value =
+ *reinterpret_cast<const uint32_t*>(&device_scale_factor);
+ zcr_ui_controls_v1_set_display_info_device_scale_factor(
+ ui_controls_, scale_factor_value);
+ zcr_ui_controls_v1_display_info_done(ui_controls_);
+ }
+
+ zcr_ui_controls_v1_display_info_list_done(ui_controls_, request_id);
+ auto* wayland_proxy = wl::WaylandProxy::GetInstance();
+ wayland_proxy->FlushForTesting();
+ }
+}
+#endif
+
#if BUILDFLAG(IS_LINUX)
void WaylandInputEmulate::ForceUseScreenCoordinatesOnce() {
force_use_screen_coordinates_once_ = true;
@@ -360,6 +399,11 @@
}
// static
+void WaylandInputEmulate::OnGlobalRemove(void* data,
+ wl_registry* registry,
+ uint32_t name) {}
+
+// static
void WaylandInputEmulate::OnFrameDone(void* data,
wl_callback* callback,
uint32_t time) {
diff --git a/ui/ozone/platform/wayland/emulate/wayland_input_emulate.h b/ui/ozone/platform/wayland/emulate/wayland_input_emulate.h
index 42aee7d..879a702 100644
--- a/ui/ozone/platform/wayland/emulate/wayland_input_emulate.h
+++ b/ui/ozone/platform/wayland/emulate/wayland_input_emulate.h
@@ -8,6 +8,7 @@
#include <wayland-util.h>
#include <memory>
+#include <string>
#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h"
@@ -61,6 +62,12 @@
int touch_id,
uint32_t request_id);
+#if BUILDFLAG(IS_CHROMEOS)
+ // |display_specs| is the spec for the display(s).
+ void EmulateUpdateDisplay(const std::string& display_specs,
+ uint32_t request_id);
+#endif
+
#if BUILDFLAG(IS_LINUX)
void ForceUseScreenCoordinatesOnce();
#endif
@@ -155,6 +162,9 @@
const char* interface,
uint32_t version);
+ // wl_registry_listener callbacks:
+ static void OnGlobalRemove(void* data, wl_registry* registry, uint32_t name);
+
// wl_callback_listener callbacks:
static void OnFrameDone(void* data, wl_callback* callback, uint32_t time);
diff --git a/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.cc b/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.cc
index d12710f..7e10e3b6 100644
--- a/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.cc
+++ b/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.cc
@@ -113,6 +113,14 @@
pending_closures_.insert_or_assign(request_id, std::move(closure));
input_emulate_->EmulateTouch(action, touch_loc, id, request_id);
}
+
+void WaylandOzoneUIControlsTestHelper::UpdateDisplay(
+ const std::string& display_specs,
+ base::OnceClosure closure) {
+ uint32_t request_id = GetNextRequestId();
+ pending_closures_.insert_or_assign(request_id, std::move(closure));
+ input_emulate_->EmulateUpdateDisplay(display_specs, request_id);
+}
#endif
void WaylandOzoneUIControlsTestHelper::RunClosureAfterAllPendingUIEvents(
diff --git a/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.h b/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.h
index 48eb056..58e807b6 100644
--- a/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.h
+++ b/ui/ozone/platform/wayland/test/wayland_ozone_ui_controls_test_helper.h
@@ -52,6 +52,8 @@
int id,
const gfx::Point& touch_loc,
base::OnceClosure closure) override;
+ void UpdateDisplay(const std::string& display_specs,
+ base::OnceClosure closure) override;
#endif
void RunClosureAfterAllPendingUIEvents(base::OnceClosure closure) override;
bool MustUseUiControlsForMoveCursorTo() override;
diff --git a/ui/ozone/public/ozone_ui_controls_test_helper.h b/ui/ozone/public/ozone_ui_controls_test_helper.h
index 9a197f9..93dd8220 100644
--- a/ui/ozone/public/ozone_ui_controls_test_helper.h
+++ b/ui/ozone/public/ozone_ui_controls_test_helper.h
@@ -61,6 +61,10 @@
int id,
const gfx::Point& touch_loc,
base::OnceClosure closure) = 0;
+
+ // Update display and executes |closure| when done.
+ virtual void UpdateDisplay(const std::string& display_specs,
+ base::OnceClosure closure) = 0;
#endif
// Executes closure after all pending ui events are sent.
diff --git a/ui/views/test/ui_controls_factory_desktop_aura_ozone.cc b/ui/views/test/ui_controls_factory_desktop_aura_ozone.cc
index 616efdce..9228af7 100644
--- a/ui/views/test/ui_controls_factory_desktop_aura_ozone.cc
+++ b/ui/views/test/ui_controls_factory_desktop_aura_ozone.cc
@@ -12,6 +12,7 @@
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/ranges/algorithm.h"
+#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
@@ -282,6 +283,17 @@
return true;
}
+
+// static
+void UpdateDisplaySync(const std::string& display_specs) {
+ DCHECK(g_ozone_ui_controls_test_helper);
+ base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
+
+ g_ozone_ui_controls_test_helper->UpdateDisplay(display_specs,
+ run_loop.QuitClosure());
+
+ run_loop.Run();
+}
#endif
#if BUILDFLAG(IS_LINUX)