1 From 019d5dea79b9ac8ec17d5925546aab66473f67f5 Mon Sep 17 00:00:00 2001
2 From: Roger Zanoni <rzanoni@igalia.com>
3 Date: Mon, 15 May 2023 20:32:06 +0200
4 Subject: [PATCH 01/33] [agl][compositor] Add agl_shell_wrapper / AGL wayland
7 This is a backport of the chages we did on top of chromium webosose to
8 be able to communicate with the agl-compositor
10 Signed-off-by: Roger Zanoni <rzanoni@igalia.com>
12 ui/base/ui_base_switches.cc | 2 +
13 ui/base/ui_base_switches.h | 3 +
14 ui/ozone/platform/wayland/BUILD.gn | 7 +
15 .../platform/wayland/extensions/agl/BUILD.gn | 40 ++++
16 .../agl/common/wayland_object_agl.cc | 26 +++
17 .../agl/common/wayland_object_agl.h | 34 ++++
18 .../extensions/agl/host/agl_shell_wrapper.cc | 113 +++++++++++
19 .../extensions/agl/host/agl_shell_wrapper.h | 62 ++++++
20 .../agl/host/wayland_extensions_agl.h | 37 ++++
21 .../agl/host/wayland_extensions_agl_impl.cc | 93 +++++++++
22 .../agl/host/wayland_extensions_agl_impl.h | 54 ++++++
23 .../extensions/agl/protocol/agl-shell.xml | 179 ++++++++++++++++++
24 .../wayland/host/wayland_connection.cc | 12 +-
25 .../wayland/host/wayland_connection.h | 4 +
26 .../wayland/host/wayland_extensions.h | 56 ++++++
27 15 files changed, 720 insertions(+), 2 deletions(-)
28 create mode 100644 ui/ozone/platform/wayland/extensions/agl/BUILD.gn
29 create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
30 create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
31 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
32 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
33 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
34 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
35 create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
36 create mode 100644 ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
37 create mode 100644 ui/ozone/platform/wayland/host/wayland_extensions.h
39 diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
40 index 514bb3cdb580d..d94e2c5e78306 100644
41 --- a/ui/base/ui_base_switches.cc
42 +++ b/ui/base/ui_base_switches.cc
43 @@ -112,4 +112,6 @@ const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
44 // Enables the ozone x11 clipboard for linux-chromeos.
45 const char kUseSystemClipboard[] = "use-system-clipboard";
47 +const char kAglShellAppId[] = "agl-shell-appid";
49 } // namespace switches
50 diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
51 index ec664b866c5d2..cf483e0339072 100644
52 --- a/ui/base/ui_base_switches.h
53 +++ b/ui/base/ui_base_switches.h
54 @@ -53,6 +53,9 @@ COMPONENT_EXPORT(UI_BASE) extern const char kTopChromeTouchUiEnabled[];
55 COMPONENT_EXPORT(UI_BASE) extern const char kUIDisablePartialSwap[];
56 COMPONENT_EXPORT(UI_BASE) extern const char kUseSystemClipboard[];
59 +COMPONENT_EXPORT(UI_BASE) extern const char kAglShellAppId[];
62 COMPONENT_EXPORT(UI_BASE) extern const char kDisallowNonExactResourceReuse[];
63 COMPONENT_EXPORT(UI_BASE) extern const char kMangleLocalizedStrings[];
64 diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
65 index ae763d441d55c..8a436de0fafe3 100644
66 --- a/ui/ozone/platform/wayland/BUILD.gn
67 +++ b/ui/ozone/platform/wayland/BUILD.gn
68 @@ -397,6 +397,13 @@ source_set("wayland") {
71 configs += [ "//third_party/khronos:khronos_headers" ]
74 + "host/wayland_extensions.h",
75 + "host/wayland_extensions_stub.cc",
78 + deps += [ "extensions/agl" ]
81 source_set("test_support") {
82 diff --git a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
84 index 0000000000000..ce289bc5dbbca
86 +++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
88 +# Copyright 2021 LG Electronics, Inc.
90 +# Licensed under the Apache License, Version 2.0 (the "License");
91 +# you may not use this file except in compliance with the License.
92 +# You may obtain a copy of the License at
94 +# http://www.apache.org/licenses/LICENSE-2.0
96 +# Unless required by applicable law or agreed to in writing, software
97 +# distributed under the License is distributed on an "AS IS" BASIS,
98 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99 +# See the License for the specific language governing permissions and
100 +# limitations under the License.
102 +# SPDX-License-Identifier: Apache-2.0
104 +import("//third_party/wayland/wayland_protocol.gni")
106 +visibility = [ "//ui/ozone/*" ]
108 +wayland_protocol("agl_shell_protocol") {
109 + sources = [ "protocol/agl-shell.xml" ]
114 + "common/wayland_object_agl.cc",
115 + "common/wayland_object_agl.h",
116 + "host/agl_shell_wrapper.cc",
117 + "host/agl_shell_wrapper.h",
118 + "host/wayland_extensions_agl.h",
119 + "host/wayland_extensions_agl_impl.cc",
120 + "host/wayland_extensions_agl_impl.h",
124 + ":agl_shell_protocol",
125 + "//ui/ozone/platform/wayland/mojom",
128 diff --git a/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
130 index 0000000000000..9f3300766df2c
132 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
134 +// Copyright 2021 LG Electronics, Inc.
136 +// Licensed under the Apache License, Version 2.0 (the "License");
137 +// you may not use this file except in compliance with the License.
138 +// You may obtain a copy of the License at
140 +// http://www.apache.org/licenses/LICENSE-2.0
142 +// Unless required by applicable law or agreed to in writing, software
143 +// distributed under the License is distributed on an "AS IS" BASIS,
144 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145 +// See the License for the specific language governing permissions and
146 +// limitations under the License.
148 +// SPDX-License-Identifier: Apache-2.0
150 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
152 +#include <agl-shell-client-protocol.h>
156 +const wl_interface* ObjectTraits<agl_shell>::interface = &agl_shell_interface;
157 +void (*ObjectTraits<agl_shell>::deleter)(agl_shell*) = &agl_shell_destroy;
160 \ No newline at end of file
161 diff --git a/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
163 index 0000000000000..e91ac0da8d2fc
165 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
167 +// Copyright 2021 LG Electronics, Inc.
169 +// Licensed under the Apache License, Version 2.0 (the "License");
170 +// you may not use this file except in compliance with the License.
171 +// You may obtain a copy of the License at
173 +// http://www.apache.org/licenses/LICENSE-2.0
175 +// Unless required by applicable law or agreed to in writing, software
176 +// distributed under the License is distributed on an "AS IS" BASIS,
177 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
178 +// See the License for the specific language governing permissions and
179 +// limitations under the License.
181 +// SPDX-License-Identifier: Apache-2.0
183 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
184 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
186 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
193 +struct ObjectTraits<agl_shell> {
194 + static const wl_interface* interface;
195 + static void (*deleter)(agl_shell*);
200 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
201 \ No newline at end of file
202 diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
204 index 0000000000000..c74fa5d9cd221
206 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
208 +// Copyright 2021 LG Electronics, Inc.
210 +// Licensed under the Apache License, Version 2.0 (the "License");
211 +// you may not use this file except in compliance with the License.
212 +// You may obtain a copy of the License at
214 +// http://www.apache.org/licenses/LICENSE-2.0
216 +// Unless required by applicable law or agreed to in writing, software
217 +// distributed under the License is distributed on an "AS IS" BASIS,
218 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
219 +// See the License for the specific language governing permissions and
220 +// limitations under the License.
222 +// SPDX-License-Identifier: Apache-2.0
224 +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
226 +#include "agl_shell_wrapper.h"
227 +#include "base/logging.h"
228 +#include "ui/base/ui_base_switches.h"
229 +#include "ui/ozone/platform/wayland/host/wayland_connection.h"
230 +#include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
231 +#include "ui/ozone/platform/wayland/host/wayland_window.h"
235 +static const struct agl_shell_listener shell_listener = {
236 + &AglShellWrapper::AglShellBoundOk,
237 + &AglShellWrapper::AglShellBoundFail,
238 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
239 + &AglShellWrapper::AglAppState,
243 +AglShellWrapper::AglShellWrapper(agl_shell* agl_shell,
244 + WaylandConnection* wayland_connection)
245 + : agl_shell_(agl_shell), connection_(wayland_connection) {
246 + if (wl::get_version_of_object(agl_shell) >= AGL_SHELL_BOUND_OK_SINCE_VERSION)
247 + agl_shell_add_listener(agl_shell, &shell_listener, this);
250 +AglShellWrapper::~AglShellWrapper() = default;
252 +void AglShellWrapper::SetAglActivateApp(const std::string& app_id) {
253 + wl_output* output =
254 + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
255 + agl_shell_activate_app(agl_shell_.get(), app_id.c_str(), output);
258 +void AglShellWrapper::SetAglPanel(WaylandWindow* window, uint32_t edge) {
259 + wl_surface* surface = window->root_surface()->surface();
260 + wl_output* output =
261 + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
263 + agl_shell_set_panel(agl_shell_.get(), surface, output, edge);
266 +void AglShellWrapper::SetAglBackground(WaylandWindow* window) {
267 + wl_surface* surface = window->root_surface()->surface();
268 + wl_output* output =
269 + connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
271 + agl_shell_set_background(agl_shell_.get(), surface, output);
274 +void AglShellWrapper::SetAglReady() {
275 + agl_shell_ready(agl_shell_.get());
279 +void AglShellWrapper::AglShellBoundOk(void* data, struct agl_shell*) {
280 + AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
281 + wrapper->wait_for_bound_ = false;
282 + wrapper->bound_ok_ = true;
283 + LOG(INFO) << "Bound to agl_shell (bound_ok)";
287 +void AglShellWrapper::AglShellBoundFail(void* data, struct agl_shell*) {
288 + AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
289 + wrapper->wait_for_bound_ = false;
290 + wrapper->bound_ok_ = false;
291 + LOG(INFO) << "Failed to bind to agl_shell (bound_fail)";
294 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
296 +void AglShellWrapper::AglAppState(void* data,
298 + const char* app_id,
300 + AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
302 + LOG(INFO) << "State for app " << app_id << " changed to " << state;
304 + if (state == AGL_SHELL_APP_STATE_STARTED) {
305 + wrapper->SetAglActivateApp(app_id);
306 + LOG(INFO) << "Activating app " << app_id;
311 +bool AglShellWrapper::WaitUntilBoundOk() {
313 + while (ret != -1 && wait_for_bound_) {
314 + ret = wl_display_dispatch(connection_->display());
321 diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
323 index 0000000000000..2ab765883057e
325 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
327 +// Copyright 2021 LG Electronics, Inc.
329 +// Licensed under the Apache License, Version 2.0 (the "License");
330 +// you may not use this file except in compliance with the License.
331 +// You may obtain a copy of the License at
333 +// http://www.apache.org/licenses/LICENSE-2.0
335 +// Unless required by applicable law or agreed to in writing, software
336 +// distributed under the License is distributed on an "AS IS" BASIS,
337 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
338 +// See the License for the specific language governing permissions and
339 +// limitations under the License.
341 +// SPDX-License-Identifier: Apache-2.0
343 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
344 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
348 +#include <agl-shell-client-protocol.h>
350 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
354 +class WaylandConnection;
355 +class WaylandWindow;
357 +class AglShellWrapper {
359 + AglShellWrapper(agl_shell* agl_shell, WaylandConnection* wayland_connection);
360 + AglShellWrapper(const AglShellWrapper&) = delete;
361 + AglShellWrapper& operator=(const AglShellWrapper&) = delete;
362 + ~AglShellWrapper();
364 + void SetAglActivateApp(const std::string& app_id);
365 + void SetAglPanel(WaylandWindow* window, uint32_t edge);
366 + void SetAglBackground(WaylandWindow* window);
367 + void SetAglReady();
368 + bool WaitUntilBoundOk();
370 + static void AglShellBoundOk(void* data, struct agl_shell*);
371 + static void AglShellBoundFail(void* data, struct agl_shell*);
372 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
373 + static void AglAppState(void* data,
375 + const char* app_id,
380 + wl::Object<agl_shell> agl_shell_;
381 + WaylandConnection* connection_;
382 + bool wait_for_bound_ = true;
383 + bool bound_ok_ = false;
388 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
389 diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
391 index 0000000000000..df42fc00c84da
393 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
395 +// Copyright 2021 LG Electronics, Inc.
397 +// Licensed under the Apache License, Version 2.0 (the "License");
398 +// you may not use this file except in compliance with the License.
399 +// You may obtain a copy of the License at
401 +// http://www.apache.org/licenses/LICENSE-2.0
403 +// Unless required by applicable law or agreed to in writing, software
404 +// distributed under the License is distributed on an "AS IS" BASIS,
405 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
406 +// See the License for the specific language governing permissions and
407 +// limitations under the License.
409 +// SPDX-License-Identifier: Apache-2.0
411 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
412 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
416 +class AglShellWrapper;
418 +// AGL extensions implementation for webOS/Lite
419 +class WaylandExtensionsAgl {
421 + WaylandExtensionsAgl() = default;
422 + WaylandExtensionsAgl(const WaylandExtensionsAgl&) = delete;
423 + WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete;
424 + virtual ~WaylandExtensionsAgl() = default;
426 + virtual AglShellWrapper* GetAglShell() = 0;
431 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
432 \ No newline at end of file
433 diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
435 index 0000000000000..26a5f0550c302
437 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
439 +// Copyright 2021 LG Electronics, Inc.
441 +// Licensed under the Apache License, Version 2.0 (the "License");
442 +// you may not use this file except in compliance with the License.
443 +// You may obtain a copy of the License at
445 +// http://www.apache.org/licenses/LICENSE-2.0
447 +// Unless required by applicable law or agreed to in writing, software
448 +// distributed under the License is distributed on an "AS IS" BASIS,
449 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
450 +// See the License for the specific language governing permissions and
451 +// limitations under the License.
453 +// SPDX-License-Identifier: Apache-2.0
455 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h"
459 +#include "base/command_line.h"
460 +#include "base/logging.h"
461 +#include "ui/base/ui_base_switches.h"
462 +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
463 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
464 +#include "ui/ozone/platform/wayland/host/wayland_connection.h"
470 +constexpr uint32_t kMinAglShellExtensionVersion = 1;
471 +constexpr uint32_t kMaxAglShellExtensionVersion = 3;
475 +WaylandExtensionsAglImpl::WaylandExtensionsAglImpl(
476 + WaylandConnection* connection)
477 + : connection_(connection) {}
479 +WaylandExtensionsAglImpl::~WaylandExtensionsAglImpl() = default;
481 +bool WaylandExtensionsAglImpl::Bind(wl_registry* registry,
483 + const char* interface,
484 + uint32_t version) {
485 + bool should_use_agl_shell = base::CommandLine::ForCurrentProcess()->HasSwitch(
486 + switches::kAglShellAppId);
487 + bool can_bind = wl::CanBind(interface, version, kMinAglShellExtensionVersion,
488 + kMaxAglShellExtensionVersion);
489 + bool is_agl_shell_interface = (strcmp(interface, "agl_shell") == 0);
491 + if (!is_agl_shell_interface) {
495 + LOG(INFO) << "should_use_agl_shell: " << should_use_agl_shell <<
496 + " can_bind: " << can_bind;
498 + if (should_use_agl_shell && !agl_shell_ &&
499 + is_agl_shell_interface && can_bind) {
500 + wl::Object<agl_shell> aglshell = wl::Bind<agl_shell>(
501 + registry, name, std::min(version, kMaxAglShellExtensionVersion));
503 + LOG(ERROR) << "Failed to bind to agl_shell global";
507 + std::make_unique<AglShellWrapper>(aglshell.release(), connection_);
509 + LOG(INFO) << "Waiting until bound...";
510 + return agl_shell_->WaitUntilBoundOk();
512 + LOG(INFO) << "Cant bind.";
518 +bool WaylandExtensionsAglImpl::HasShellObject() const {
519 + return !!agl_shell_;
522 +AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() {
523 + return agl_shell_.get();
526 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
527 + WaylandConnection* connection) {
528 + return std::make_unique<WaylandExtensionsAglImpl>(connection);
532 diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
534 index 0000000000000..f6cbabe99ed0b
536 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
538 +// Copyright 2021 LG Electronics, Inc.
540 +// Licensed under the Apache License, Version 2.0 (the "License");
541 +// you may not use this file except in compliance with the License.
542 +// You may obtain a copy of the License at
544 +// http://www.apache.org/licenses/LICENSE-2.0
546 +// Unless required by applicable law or agreed to in writing, software
547 +// distributed under the License is distributed on an "AS IS" BASIS,
548 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
549 +// See the License for the specific language governing permissions and
550 +// limitations under the License.
552 +// SPDX-License-Identifier: Apache-2.0
554 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
555 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
557 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h"
558 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
562 +class AglShellWrapper;
564 +// AGL extension implementation for webOS/Lite
565 +class WaylandExtensionsAglImpl : public WaylandExtensions,
566 + public WaylandExtensionsAgl {
568 + explicit WaylandExtensionsAglImpl(WaylandConnection* connection);
569 + WaylandExtensionsAglImpl(const WaylandExtensionsAglImpl&) = delete;
570 + WaylandExtensionsAglImpl& operator=(const WaylandExtensionsAglImpl&) = delete;
571 + ~WaylandExtensionsAglImpl() override;
573 + // WaylandExtensions overrides
574 + bool Bind(wl_registry* registry,
576 + const char* interface,
577 + uint32_t version) override;
579 + bool HasShellObject() const override;
581 + // WaylandExtensionsAgl overrides
582 + AglShellWrapper* GetAglShell() override;
585 + std::unique_ptr<AglShellWrapper> agl_shell_;
586 + WaylandConnection* connection_;
591 +#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
592 diff --git a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
594 index 0000000000000..ad5553d61f189
596 +++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
598 +<?xml version="1.0" encoding="UTF-8"?>
599 +<protocol name="agl_shell">
601 + Copyright © 2019, 2022 Collabora, Ltd.
603 + Permission is hereby granted, free of charge, to any person obtaining a
604 + copy of this software and associated documentation files (the "Software"),
605 + to deal in the Software without restriction, including without limitation
606 + the rights to use, copy, modify, merge, publish, distribute, sublicense,
607 + and/or sell copies of the Software, and to permit persons to whom the
608 + Software is furnished to do so, subject to the following conditions:
610 + The above copyright notice and this permission notice (including the next
611 + paragraph) shall be included in all copies or substantial portions of the
614 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
615 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
616 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
617 + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
618 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
619 + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
620 + DEALINGS IN THE SOFTWARE.
622 + <interface name="agl_shell" version="3">
623 + <description summary="user interface for Automotive Grade Linux platform">
624 + Starting with version 2 of the protocol, the client is required to wait
625 + for the 'bound_ok' or 'bound_fail' events in order to proceed further.
627 + In case the client gets a 'bound_fail' event then it should consider that
628 + there's another client already bound to the agl_shell protocol.
629 + A client that receives a 'bound_ok' event should consider that there's
630 + no other client already bound to the interface and can proceed further.
632 + If the client uses an older version of the protocol it will receive
633 + automatically an error and the compositor will terminate the connection,
634 + if there's another client already bound the interface.
636 + If the client receives the 'bound_fail' event and attempts to use the
637 + interface further it will receive an error and the compositor will
638 + terminate the connection. After the 'bound_fail' event was received the
639 + client should call the destructor, which has been added with version 2
640 + of the protocol. The client is free to try at a later point in time to
641 + see if it will receive the 'bound_ok' event, but there's no explicit way
642 + of finding out when that event will be delivered.
643 + It is assumed that it can infer that information through other
644 + means/other channels.
647 + <enum name="error">
648 + <entry name="invalid_argument" value="0"/>
649 + <entry name="background_exists" value="1"/>
650 + <entry name="panel_exists" value="2"/>
654 + <entry name="top" value="0"/>
655 + <entry name="bottom" value="1"/>
656 + <entry name="left" value="2"/>
657 + <entry name="right" value="3"/>
660 + <enum name="app_state" since="3">
661 + <entry name="started" value="0"/>
662 + <entry name="terminated" value="1"/>
663 + <entry name="activated" value="2"/>
664 + <entry name="deactivated" value="3"/>
667 + <request name="ready">
668 + <description summary="client is ready to be shown">
669 + Tell the server that this client is ready to be shown. The server
670 + will delay presentation during start-up until all shell clients are
671 + ready to be shown, and will display a black screen instead.
672 + This gives the client an opportunity to set up and configure several
673 + surfaces into a coherent interface.
675 + The client that binds to this interface must send this request, otherwise
676 + they may stall the compositor unnecessarily.
678 + If this request is called after the compositor has already finished
679 + start-up, no operation is performed.
683 + <request name="set_background">
684 + <description summary="set surface as output's background">
685 + Set the surface to act as the background of an output. After this
686 + request, the server will immediately send a configure event with
687 + the dimensions the client should use to cover the entire output.
689 + The surface must have a "desktop" surface role, as supported by
692 + Only a single surface may be the background for any output. If a
693 + background surface already exists, a protocol error is raised.
695 + <arg name="surface" type="object" interface="wl_surface"/>
696 + <arg name="output" type="object" interface="wl_output"/>
699 + <request name="set_panel">
700 + <description summary="set surface as panel">
701 + Set the surface to act as a panel of an output. The 'edge' argument
702 + says what edge of the output the surface will be anchored to.
703 + After this request, the server will send a configure event with the
704 + corresponding width/height that the client should use, and 0 for the
705 + other dimension. E.g. if the edge is 'top', the width will be the
706 + output's width, and the height will be 0.
708 + The surface must have a "desktop" surface role, as supported by
711 + The compositor will take the panel's window geometry into account when
712 + positioning other windows, so the panels are not covered.
714 + XXX: What happens if e.g. both top and left are used at the same time?
715 + Who gets to have the corner?
717 + Only a single surface may be the panel for an output's edge. If a
718 + surface already exists on an edge, a protocol error is raised.
720 + <arg name="surface" type="object" interface="wl_surface"/>
721 + <arg name="output" type="object" interface="wl_output"/>
722 + <arg name="edge" type="uint" enum="edge"/>
725 + <request name="activate_app">
726 + <description summary="make client current window">
727 + Ask the compositor to make a toplevel to become the current/focused
728 + window for window management purposes.
730 + See xdg_toplevel.set_app_id from the xdg-shell protocol for a
731 + description of app_id.
733 + If multiple toplevels have the same app_id, the result is unspecified.
735 + XXX: Do we need feedback to say it didn't work? (e.g. client does
738 + <arg name="app_id" type="string"/>
739 + <arg name="output" type="object" interface="wl_output"/>
742 + <event name="bound_ok" since="2">
743 + <description summary="event sent if binding was ok">
744 + Informs the client that it was able to bind the agl_shell
745 + interface succesfully. Clients are required to wait for this
746 + event before continuing further.
750 + <event name="bound_fail" since="2">
751 + <description summary="event sent if binding was nok">
752 + Informs the client that binding to the agl_shell interface was
753 + unsuccesfull. Clients are required to wait for this event for
754 + continuing further.
758 + <request name="destroy" type="destructor" since="2">
759 + <description summary="destroys the factory object">
763 + <event name="app_state" since="3">
764 + <description summary="event sent when an application suffered state modification">
765 + Informs the client that an application has changed its state to another,
766 + specified by the app_state enum. Client can use this event to track
767 + current application state. For instance to know when the application has
768 + started, or when terminated/stopped.
770 + <arg name="app_id" type="string"/>
771 + <arg name="state" type="uint" enum="app_state"/>
777 diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
778 index ad3bbd6e37157..7a47d4a636998 100644
779 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc
780 +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
782 #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h"
783 #include "ui/platform_window/common/platform_window_defaults.h"
785 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
790 @@ -212,6 +214,10 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) {
791 use_threaded_polling = false;
794 + if (!extensions_) {
795 + extensions_ = CreateWaylandExtensions(this);
798 // Now that the connection with the display server has been properly
799 // estabilished, initialize the event source and input objects.
800 DCHECK(!event_source_);
801 @@ -243,7 +249,7 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) {
802 LOG(ERROR) << "No wl_shm object";
806 + if (!shell_ && !(extensions_ && extensions_->HasShellObject())) {
807 LOG(ERROR) << "No Wayland shell found";
810 @@ -538,7 +544,9 @@ void WaylandConnection::HandleGlobal(wl_registry* registry,
811 const char* interface,
813 auto factory_it = global_object_factories_.find(interface);
814 - if (factory_it != global_object_factories_.end()) {
815 + if (extensions_->Bind(registry, name, interface, version)) {
816 + DVLOG(1) << "Successfully bound to " << interface;
817 + } else if (factory_it != global_object_factories_.end()) {
818 (*factory_it->second)(this, registry, name, interface, version);
819 } else if (!compositor_ && strcmp(interface, "wl_compositor") == 0) {
820 compositor_ = wl::Bind<wl_compositor>(
821 diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
822 index 6659bc54bd475..ba293e5bcd088 100644
823 --- a/ui/ozone/platform/wayland/host/wayland_connection.h
824 +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
825 @@ -50,6 +50,7 @@ class WaylandBufferManagerHost;
827 class WaylandCursorBufferListener;
828 class WaylandEventSource;
829 +class WaylandExtensions;
830 class WaylandOutputManager;
832 class WaylandZAuraShell;
833 @@ -201,6 +202,8 @@ class WaylandConnection {
835 WaylandZAuraShell* zaura_shell() const { return zaura_shell_.get(); }
837 + WaylandExtensions* extensions() { return extensions_.get(); }
839 WaylandZcrColorManager* zcr_color_manager() const {
840 return zcr_color_manager_.get();
842 @@ -486,6 +489,7 @@ class WaylandConnection {
843 std::unique_ptr<OverlayPrioritizer> overlay_prioritizer_;
844 std::unique_ptr<SurfaceAugmenter> surface_augmenter_;
845 std::unique_ptr<SinglePixelBuffer> single_pixel_buffer_;
846 + std::unique_ptr<WaylandExtensions> extensions_;
848 // Clipboard-related objects. |clipboard_| must be declared after all
849 // DeviceManager instances it depends on, otherwise tests may crash with
850 diff --git a/ui/ozone/platform/wayland/host/wayland_extensions.h b/ui/ozone/platform/wayland/host/wayland_extensions.h
852 index 0000000000000..3bd2fd7a211ae
854 +++ b/ui/ozone/platform/wayland/host/wayland_extensions.h
856 +// Copyright 2019 LG Electronics, Inc.
858 +// Licensed under the Apache License, Version 2.0 (the "License");
859 +// you may not use this file except in compliance with the License.
860 +// You may obtain a copy of the License at
862 +// http://www.apache.org/licenses/LICENSE-2.0
864 +// Unless required by applicable law or agreed to in writing, software
865 +// distributed under the License is distributed on an "AS IS" BASIS,
866 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
867 +// See the License for the specific language governing permissions and
868 +// limitations under the License.
870 +// SPDX-License-Identifier: Apache-2.0
872 +#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
873 +#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
877 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
881 +class ShellToplevelWrapper;
882 +class ShellPopupWrapper;
883 +class WaylandConnection;
885 +// Wayland extensions abstract interface to support extending of the Wayland
886 +// protocol. Inherit it to provide your own Wayland extensions implementation.
887 +class WaylandExtensions {
889 + WaylandExtensions() = default;
890 + WaylandExtensions(const WaylandExtensions&) = delete;
891 + WaylandExtensions& operator=(const WaylandExtensions&) = delete;
892 + virtual ~WaylandExtensions() = default;
894 + // Binds to the extensions interface(s). Can encapsulate binding of several
895 + // interfaces, defined by |interface|.
896 + virtual bool Bind(wl_registry* registry,
898 + const char* interface,
899 + uint32_t version) = 0;
901 + // Checks whether the extensions have bound shell object(s).
902 + virtual bool HasShellObject() const = 0;
905 +// Creates Wayland extensions.
906 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
907 + WaylandConnection* connection);
911 +#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_