[cef][wam] Make the recipe work with official chromium release tarballs
[AGL/meta-agl-demo.git] / recipes-wam / cef / files / chromium / 0001-agl-compositor-Add-agl_shell_wrapper-AGL-wayland-ext.patch
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
5  extension
6
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
9
10 Signed-off-by: Roger Zanoni <rzanoni@igalia.com>
11 ---
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
38
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";
46  
47 +const char kAglShellAppId[] = "agl-shell-appid";
48 +
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[];
57  
58 +// Agl related
59 +COMPONENT_EXPORT(UI_BASE) extern const char kAglShellAppId[];
60 +
61  // Test related.
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") {
69    ]
70  
71    configs += [ "//third_party/khronos:khronos_headers" ]
72 +
73 +  sources += [
74 +   "host/wayland_extensions.h",
75 +   "host/wayland_extensions_stub.cc",
76 +  ]
77 +
78 +  deps += [ "extensions/agl" ]
79  }
80  
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
83 new file mode 100644
84 index 0000000000000..ce289bc5dbbca
85 --- /dev/null
86 +++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
87 @@ -0,0 +1,40 @@
88 +# Copyright 2021 LG Electronics, Inc.
89 +#
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
93 +#
94 +# http://www.apache.org/licenses/LICENSE-2.0
95 +#
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.
101 +#
102 +# SPDX-License-Identifier: Apache-2.0
103 +
104 +import("//third_party/wayland/wayland_protocol.gni")
105 +
106 +visibility = [ "//ui/ozone/*" ]
107 +
108 +wayland_protocol("agl_shell_protocol") {
109 +  sources = [ "protocol/agl-shell.xml" ]
110 +}
111 +
112 +source_set("agl") {
113 +  sources = [
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",
121 +  ]
122 +
123 +  deps = [
124 +    ":agl_shell_protocol",
125 +    "//ui/ozone/platform/wayland/mojom",
126 +  ]
127 +}
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
129 new file mode 100644
130 index 0000000000000..9f3300766df2c
131 --- /dev/null
132 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
133 @@ -0,0 +1,26 @@
134 +// Copyright 2021 LG Electronics, Inc.
135 +//
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
139 +//
140 +// http://www.apache.org/licenses/LICENSE-2.0
141 +//
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.
147 +//
148 +// SPDX-License-Identifier: Apache-2.0
149 +
150 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
151 +
152 +#include <agl-shell-client-protocol.h>
153 +
154 +namespace wl {
155 +
156 +const wl_interface* ObjectTraits<agl_shell>::interface = &agl_shell_interface;
157 +void (*ObjectTraits<agl_shell>::deleter)(agl_shell*) = &agl_shell_destroy;
158 +
159 +}  // namespace wl
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
162 new file mode 100644
163 index 0000000000000..e91ac0da8d2fc
164 --- /dev/null
165 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
166 @@ -0,0 +1,34 @@
167 +// Copyright 2021 LG Electronics, Inc.
168 +//
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
172 +//
173 +// http://www.apache.org/licenses/LICENSE-2.0
174 +//
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.
180 +//
181 +// SPDX-License-Identifier: Apache-2.0
182 +
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_
185 +
186 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
187 +
188 +struct agl_shell;
189 +
190 +namespace wl {
191 +
192 +template <>
193 +struct ObjectTraits<agl_shell> {
194 +  static const wl_interface* interface;
195 +  static void (*deleter)(agl_shell*);
196 +};
197 +
198 +}  // namespace wl
199 +
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
203 new file mode 100644
204 index 0000000000000..c74fa5d9cd221
205 --- /dev/null
206 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
207 @@ -0,0 +1,113 @@
208 +// Copyright 2021 LG Electronics, Inc.
209 +//
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
213 +//
214 +// http://www.apache.org/licenses/LICENSE-2.0
215 +//
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.
221 +//
222 +// SPDX-License-Identifier: Apache-2.0
223 +
224 +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
225 +
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"
232 +
233 +namespace ui {
234 +
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,
240 +#endif
241 +};
242 +
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);
248 +}
249 +
250 +AglShellWrapper::~AglShellWrapper() = default;
251 +
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);
256 +}
257 +
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();
262 +
263 +  agl_shell_set_panel(agl_shell_.get(), surface, output, edge);
264 +}
265 +
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();
270 +
271 +  agl_shell_set_background(agl_shell_.get(), surface, output);
272 +}
273 +
274 +void AglShellWrapper::SetAglReady() {
275 +  agl_shell_ready(agl_shell_.get());
276 +}
277 +
278 +// static
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)";
284 +}
285 +
286 +// static
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)";
292 +}
293 +
294 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
295 +// static
296 +void AglShellWrapper::AglAppState(void* data,
297 +                                  struct agl_shell*,
298 +                                  const char* app_id,
299 +                                  uint32_t state) {
300 +  AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
301 +
302 +  LOG(INFO) << "State for app " << app_id << " changed to " << state;
303 +
304 +  if (state == AGL_SHELL_APP_STATE_STARTED) {
305 +    wrapper->SetAglActivateApp(app_id);
306 +    LOG(INFO) << "Activating app " << app_id;
307 +  }
308 +}
309 +#endif
310 +
311 +bool AglShellWrapper::WaitUntilBoundOk() {
312 +  int ret = 0;
313 +  while (ret != -1 && wait_for_bound_) {
314 +    ret = wl_display_dispatch(connection_->display());
315 +  }
316 +
317 +  return bound_ok_;
318 +}
319 +
320 +}  // namespace ui
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
322 new file mode 100644
323 index 0000000000000..2ab765883057e
324 --- /dev/null
325 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
326 @@ -0,0 +1,62 @@
327 +// Copyright 2021 LG Electronics, Inc.
328 +//
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
332 +//
333 +// http://www.apache.org/licenses/LICENSE-2.0
334 +//
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.
340 +//
341 +// SPDX-License-Identifier: Apache-2.0
342 +
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_
345 +
346 +#include <string>
347 +
348 +#include <agl-shell-client-protocol.h>
349 +
350 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
351 +
352 +namespace ui {
353 +
354 +class WaylandConnection;
355 +class WaylandWindow;
356 +
357 +class AglShellWrapper {
358 + public:
359 +  AglShellWrapper(agl_shell* agl_shell, WaylandConnection* wayland_connection);
360 +  AglShellWrapper(const AglShellWrapper&) = delete;
361 +  AglShellWrapper& operator=(const AglShellWrapper&) = delete;
362 +  ~AglShellWrapper();
363 +
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();
369 +
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,
374 +                          struct agl_shell*,
375 +                          const char* app_id,
376 +                          uint32_t state);
377 +#endif
378 +
379 + private:
380 +  wl::Object<agl_shell> agl_shell_;
381 +  WaylandConnection* connection_;
382 +  bool wait_for_bound_ = true;
383 +  bool bound_ok_ = false;
384 +};
385 +
386 +}  // namespace ui
387 +
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
390 new file mode 100644
391 index 0000000000000..df42fc00c84da
392 --- /dev/null
393 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
394 @@ -0,0 +1,37 @@
395 +// Copyright 2021 LG Electronics, Inc.
396 +//
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
400 +//
401 +// http://www.apache.org/licenses/LICENSE-2.0
402 +//
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.
408 +//
409 +// SPDX-License-Identifier: Apache-2.0
410 +
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_
413 +
414 +namespace ui {
415 +
416 +class AglShellWrapper;
417 +
418 +// AGL extensions implementation for webOS/Lite
419 +class WaylandExtensionsAgl {
420 + public:
421 +  WaylandExtensionsAgl() = default;
422 +  WaylandExtensionsAgl(const WaylandExtensionsAgl&) = delete;
423 +  WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete;
424 +  virtual ~WaylandExtensionsAgl() = default;
425 +
426 +  virtual AglShellWrapper* GetAglShell() = 0;
427 +};
428 +
429 +}  // namespace ui
430 +
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
434 new file mode 100644
435 index 0000000000000..26a5f0550c302
436 --- /dev/null
437 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
438 @@ -0,0 +1,93 @@
439 +// Copyright 2021 LG Electronics, Inc.
440 +//
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
444 +//
445 +// http://www.apache.org/licenses/LICENSE-2.0
446 +//
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.
452 +//
453 +// SPDX-License-Identifier: Apache-2.0
454 +
455 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h"
456 +
457 +#include <cstring>
458 +
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"
465 +
466 +namespace ui {
467 +
468 +namespace {
469 +
470 +constexpr uint32_t kMinAglShellExtensionVersion = 1;
471 +constexpr uint32_t kMaxAglShellExtensionVersion = 3;
472 +
473 +}  // namespace
474 +
475 +WaylandExtensionsAglImpl::WaylandExtensionsAglImpl(
476 +    WaylandConnection* connection)
477 +    : connection_(connection) {}
478 +
479 +WaylandExtensionsAglImpl::~WaylandExtensionsAglImpl() = default;
480 +
481 +bool WaylandExtensionsAglImpl::Bind(wl_registry* registry,
482 +                                    uint32_t name,
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);
490 +
491 +  if (!is_agl_shell_interface) {
492 +      return false;
493 +  }
494 +
495 +  LOG(INFO) << "should_use_agl_shell: " << should_use_agl_shell <<
496 +               " can_bind: " << can_bind;
497 +
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));
502 +    if (!aglshell) {
503 +      LOG(ERROR) << "Failed to bind to agl_shell global";
504 +      return false;
505 +    }
506 +    agl_shell_ =
507 +        std::make_unique<AglShellWrapper>(aglshell.release(), connection_);
508 +
509 +    LOG(INFO) << "Waiting until bound...";
510 +    return agl_shell_->WaitUntilBoundOk();
511 +  } else {
512 +    LOG(INFO) << "Cant bind.";
513 +  }
514 +
515 +  return false;
516 +}
517 +
518 +bool WaylandExtensionsAglImpl::HasShellObject() const {
519 +  return !!agl_shell_;
520 +}
521 +
522 +AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() {
523 +  return agl_shell_.get();
524 +}
525 +
526 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
527 +    WaylandConnection* connection) {
528 +  return std::make_unique<WaylandExtensionsAglImpl>(connection);
529 +}
530 +
531 +}  // namespace ui
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
533 new file mode 100644
534 index 0000000000000..f6cbabe99ed0b
535 --- /dev/null
536 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
537 @@ -0,0 +1,54 @@
538 +// Copyright 2021 LG Electronics, Inc.
539 +//
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
543 +//
544 +// http://www.apache.org/licenses/LICENSE-2.0
545 +//
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.
551 +//
552 +// SPDX-License-Identifier: Apache-2.0
553 +
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_
556 +
557 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h"
558 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
559 +
560 +namespace ui {
561 +
562 +class AglShellWrapper;
563 +
564 +// AGL extension implementation for webOS/Lite
565 +class WaylandExtensionsAglImpl : public WaylandExtensions,
566 +                                 public WaylandExtensionsAgl {
567 + public:
568 +  explicit WaylandExtensionsAglImpl(WaylandConnection* connection);
569 +  WaylandExtensionsAglImpl(const WaylandExtensionsAglImpl&) = delete;
570 +  WaylandExtensionsAglImpl& operator=(const WaylandExtensionsAglImpl&) = delete;
571 +  ~WaylandExtensionsAglImpl() override;
572 +
573 +  // WaylandExtensions overrides
574 +  bool Bind(wl_registry* registry,
575 +            uint32_t name,
576 +            const char* interface,
577 +            uint32_t version) override;
578 +
579 +  bool HasShellObject() const override;
580 +
581 +  // WaylandExtensionsAgl overrides
582 +  AglShellWrapper* GetAglShell() override;
583 +
584 + private:
585 +  std::unique_ptr<AglShellWrapper> agl_shell_;
586 +  WaylandConnection* connection_;
587 +};
588 +
589 +}  // namespace ui
590 +
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
593 new file mode 100644
594 index 0000000000000..ad5553d61f189
595 --- /dev/null
596 +++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
597 @@ -0,0 +1,179 @@
598 +<?xml version="1.0" encoding="UTF-8"?>
599 +<protocol name="agl_shell">
600 +  <copyright>
601 +    Copyright Â© 2019, 2022 Collabora, Ltd.
602 +
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:
609 +
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
612 +    Software.
613 +
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.
621 +  </copyright>
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.
626 +
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.
631 +
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.
635 +
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.
645 +    </description>
646 +
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"/>
651 +    </enum>
652 +
653 +    <enum name="edge">
654 +      <entry name="top" value="0"/>
655 +      <entry name="bottom" value="1"/>
656 +      <entry name="left" value="2"/>
657 +      <entry name="right" value="3"/>
658 +    </enum>
659 +
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"/>
665 +    </enum>
666 +
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.
674 +
675 +        The client that binds to this interface must send this request, otherwise
676 +        they may stall the compositor unnecessarily.
677 +
678 +        If this request is called after the compositor has already finished
679 +        start-up, no operation is performed.
680 +      </description>
681 +    </request>
682 +
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.
688 +
689 +        The surface must have a "desktop" surface role, as supported by
690 +        libweston-desktop.
691 +
692 +        Only a single surface may be the background for any output. If a
693 +        background surface already exists, a protocol error is raised.
694 +      </description>
695 +      <arg name="surface" type="object" interface="wl_surface"/>
696 +      <arg name="output" type="object" interface="wl_output"/>
697 +    </request>
698 +
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.
707 +
708 +        The surface must have a "desktop" surface role, as supported by
709 +        libweston-desktop.
710 +
711 +        The compositor will take the panel's window geometry into account when
712 +        positioning other windows, so the panels are not covered.
713 +
714 +        XXX: What happens if e.g. both top and left are used at the same time?
715 +        Who gets to have the corner?
716 +
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.
719 +      </description>
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"/>
723 +    </request>
724 +
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.
729 +
730 +        See xdg_toplevel.set_app_id from the xdg-shell protocol for a
731 +        description of app_id.
732 +
733 +        If multiple toplevels have the same app_id, the result is unspecified.
734 +
735 +        XXX: Do we need feedback to say it didn't work? (e.g. client does
736 +        not exist)
737 +      </description>
738 +      <arg name="app_id" type="string"/>
739 +      <arg name="output" type="object" interface="wl_output"/>
740 +    </request>
741 +
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.
747 +     </description>
748 +    </event>
749 +
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.
755 +      </description>
756 +    </event>
757 +
758 +    <request name="destroy" type="destructor" since="2">
759 +      <description summary="destroys the factory object">
760 +      </description>
761 +    </request>
762 +
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.
769 +      </description>
770 +      <arg name="app_id" type="string"/>
771 +      <arg name="state" type="uint" enum="app_state"/>
772 +    </event>
773 +
774 +
775 +  </interface>
776 +</protocol>
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
781 @@ -68,6 +68,8 @@
782  #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h"
783  #include "ui/platform_window/common/platform_window_defaults.h"
784  
785 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
786 +
787  namespace ui {
788  
789  namespace {
790 @@ -212,6 +214,10 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) {
791      use_threaded_polling = false;
792    }
793  
794 +  if (!extensions_) {
795 +    extensions_ = CreateWaylandExtensions(this);
796 +  }
797 +
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";
803      return false;
804    }
805 -  if (!shell_) {
806 +  if (!shell_  && !(extensions_ && extensions_->HasShellObject())) {
807      LOG(ERROR) << "No Wayland shell found";
808      return false;
809    }
810 @@ -538,7 +544,9 @@ void WaylandConnection::HandleGlobal(wl_registry* registry,
811                                       const char* interface,
812                                       uint32_t version) {
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;
826  class WaylandCursor;
827  class WaylandCursorBufferListener;
828  class WaylandEventSource;
829 +class WaylandExtensions;
830  class WaylandOutputManager;
831  class WaylandSeat;
832  class WaylandZAuraShell;
833 @@ -201,6 +202,8 @@ class WaylandConnection {
834  
835    WaylandZAuraShell* zaura_shell() const { return zaura_shell_.get(); }
836  
837 +  WaylandExtensions* extensions() { return extensions_.get(); }
838 +
839    WaylandZcrColorManager* zcr_color_manager() const {
840      return zcr_color_manager_.get();
841    }
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_;
847  
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
851 new file mode 100644
852 index 0000000000000..3bd2fd7a211ae
853 --- /dev/null
854 +++ b/ui/ozone/platform/wayland/host/wayland_extensions.h
855 @@ -0,0 +1,56 @@
856 +// Copyright 2019 LG Electronics, Inc.
857 +//
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
861 +//
862 +// http://www.apache.org/licenses/LICENSE-2.0
863 +//
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.
869 +//
870 +// SPDX-License-Identifier: Apache-2.0
871 +
872 +#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
873 +#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
874 +
875 +#include <memory>
876 +
877 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
878 +
879 +namespace ui {
880 +
881 +class ShellToplevelWrapper;
882 +class ShellPopupWrapper;
883 +class WaylandConnection;
884 +
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 {
888 + public:
889 +  WaylandExtensions() = default;
890 +  WaylandExtensions(const WaylandExtensions&) = delete;
891 +  WaylandExtensions& operator=(const WaylandExtensions&) = delete;
892 +  virtual ~WaylandExtensions() = default;
893 +
894 +  // Binds to the extensions interface(s). Can encapsulate binding of several
895 +  // interfaces, defined by |interface|.
896 +  virtual bool Bind(wl_registry* registry,
897 +                    uint32_t name,
898 +                    const char* interface,
899 +                    uint32_t version) = 0;
900 +
901 +  // Checks whether the extensions have bound shell object(s).
902 +  virtual bool HasShellObject() const = 0;
903 +};
904 +
905 +// Creates Wayland extensions.
906 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
907 +  WaylandConnection* connection);
908 +
909 +}  // namespace ui
910 +
911 +#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
912 -- 
913 2.42.1
914