[wam][cef] Add the CEF recipe
[AGL/meta-agl-demo.git] / recipes-wam / cef / files / chromium / 0005-Add-the-essential-parts-of-wayland-extensions-and-ag.patch
1 From 7e927a21ecaa70c14873d5f06667dfc3bdaa4d25 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 5/9] Add the essential parts of wayland extensions and
5  agl_shell
6
7 ---
8  ui/base/ui_base_switches.cc                   |   2 +
9  ui/base/ui_base_switches.h                    |   3 +
10  ui/ozone/platform/wayland/BUILD.gn            |   7 +
11  .../platform/wayland/extensions/agl/BUILD.gn  |  40 ++++
12  .../agl/common/wayland_object_agl.cc          |  26 +++
13  .../agl/common/wayland_object_agl.h           |  34 ++++
14  .../extensions/agl/host/agl_shell_wrapper.cc  | 113 +++++++++++
15  .../extensions/agl/host/agl_shell_wrapper.h   |  62 ++++++
16  .../agl/host/wayland_extensions_agl.h         |  37 ++++
17  .../agl/host/wayland_extensions_agl_impl.cc   |  93 +++++++++
18  .../agl/host/wayland_extensions_agl_impl.h    |  54 ++++++
19  .../extensions/agl/protocol/agl-shell.xml     | 179 ++++++++++++++++++
20  .../wayland/host/wayland_connection.cc        |  12 +-
21  .../wayland/host/wayland_connection.h         |   6 +
22  .../wayland/host/wayland_extensions.h         |  56 ++++++
23  15 files changed, 722 insertions(+), 2 deletions(-)
24  create mode 100644 ui/ozone/platform/wayland/extensions/agl/BUILD.gn
25  create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
26  create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
27  create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
28  create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
29  create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
30  create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
31  create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
32  create mode 100644 ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
33  create mode 100644 ui/ozone/platform/wayland/host/wayland_extensions.h
34
35 diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
36 index f8556679a79d8..e72ae83737c04 100644
37 --- a/ui/base/ui_base_switches.cc
38 +++ b/ui/base/ui_base_switches.cc
39 @@ -100,4 +100,6 @@ const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
40  // Enables the ozone x11 clipboard for linux-chromeos.
41  const char kUseSystemClipboard[] = "use-system-clipboard";
42  
43 +const char kAglShellAppId[] = "agl-shell-appid";
44 +
45  }  // namespace switches
46 diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
47 index d35e544f2bc2f..019ba0e5151e5 100644
48 --- a/ui/base/ui_base_switches.h
49 +++ b/ui/base/ui_base_switches.h
50 @@ -45,6 +45,9 @@ COMPONENT_EXPORT(UI_BASE) extern const char kTopChromeTouchUiEnabled[];
51  COMPONENT_EXPORT(UI_BASE) extern const char kUIDisablePartialSwap[];
52  COMPONENT_EXPORT(UI_BASE) extern const char kUseSystemClipboard[];
53  
54 +// Agl related
55 +COMPONENT_EXPORT(UI_BASE) extern const char kAglShellAppId[];
56 +
57  // Test related.
58  COMPONENT_EXPORT(UI_BASE) extern const char kDisallowNonExactResourceReuse[];
59  COMPONENT_EXPORT(UI_BASE) extern const char kMangleLocalizedStrings[];
60 diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
61 index e0f0d7dea3747..1a2f889dc8947 100644
62 --- a/ui/ozone/platform/wayland/BUILD.gn
63 +++ b/ui/ozone/platform/wayland/BUILD.gn
64 @@ -407,6 +407,13 @@ source_set("wayland") {
65      ]
66    }
67  
68 +  sources += [
69 +   "host/wayland_extensions.h",
70 +   "host/wayland_extensions_stub.cc",
71 +  ]
72 +
73 +  deps += [ "extensions/agl" ]
74 +
75    configs += [ "//third_party/khronos:khronos_headers" ]
76  }
77  
78 diff --git a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
79 new file mode 100644
80 index 0000000000000..ce289bc5dbbca
81 --- /dev/null
82 +++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
83 @@ -0,0 +1,40 @@
84 +# Copyright 2021 LG Electronics, Inc.
85 +#
86 +# Licensed under the Apache License, Version 2.0 (the "License");
87 +# you may not use this file except in compliance with the License.
88 +# You may obtain a copy of the License at
89 +#
90 +# http://www.apache.org/licenses/LICENSE-2.0
91 +#
92 +# Unless required by applicable law or agreed to in writing, software
93 +# distributed under the License is distributed on an "AS IS" BASIS,
94 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95 +# See the License for the specific language governing permissions and
96 +# limitations under the License.
97 +#
98 +# SPDX-License-Identifier: Apache-2.0
99 +
100 +import("//third_party/wayland/wayland_protocol.gni")
101 +
102 +visibility = [ "//ui/ozone/*" ]
103 +
104 +wayland_protocol("agl_shell_protocol") {
105 +  sources = [ "protocol/agl-shell.xml" ]
106 +}
107 +
108 +source_set("agl") {
109 +  sources = [
110 +    "common/wayland_object_agl.cc",
111 +    "common/wayland_object_agl.h",
112 +    "host/agl_shell_wrapper.cc",
113 +    "host/agl_shell_wrapper.h",
114 +    "host/wayland_extensions_agl.h",
115 +    "host/wayland_extensions_agl_impl.cc",
116 +    "host/wayland_extensions_agl_impl.h",
117 +  ]
118 +
119 +  deps = [
120 +    ":agl_shell_protocol",
121 +    "//ui/ozone/platform/wayland/mojom",
122 +  ]
123 +}
124 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
125 new file mode 100644
126 index 0000000000000..9f3300766df2c
127 --- /dev/null
128 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
129 @@ -0,0 +1,26 @@
130 +// Copyright 2021 LG Electronics, Inc.
131 +//
132 +// Licensed under the Apache License, Version 2.0 (the "License");
133 +// you may not use this file except in compliance with the License.
134 +// You may obtain a copy of the License at
135 +//
136 +// http://www.apache.org/licenses/LICENSE-2.0
137 +//
138 +// Unless required by applicable law or agreed to in writing, software
139 +// distributed under the License is distributed on an "AS IS" BASIS,
140 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141 +// See the License for the specific language governing permissions and
142 +// limitations under the License.
143 +//
144 +// SPDX-License-Identifier: Apache-2.0
145 +
146 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
147 +
148 +#include <agl-shell-client-protocol.h>
149 +
150 +namespace wl {
151 +
152 +const wl_interface* ObjectTraits<agl_shell>::interface = &agl_shell_interface;
153 +void (*ObjectTraits<agl_shell>::deleter)(agl_shell*) = &agl_shell_destroy;
154 +
155 +}  // namespace wl
156 \ No newline at end of file
157 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
158 new file mode 100644
159 index 0000000000000..e91ac0da8d2fc
160 --- /dev/null
161 +++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
162 @@ -0,0 +1,34 @@
163 +// Copyright 2021 LG Electronics, Inc.
164 +//
165 +// Licensed under the Apache License, Version 2.0 (the "License");
166 +// you may not use this file except in compliance with the License.
167 +// You may obtain a copy of the License at
168 +//
169 +// http://www.apache.org/licenses/LICENSE-2.0
170 +//
171 +// Unless required by applicable law or agreed to in writing, software
172 +// distributed under the License is distributed on an "AS IS" BASIS,
173 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174 +// See the License for the specific language governing permissions and
175 +// limitations under the License.
176 +//
177 +// SPDX-License-Identifier: Apache-2.0
178 +
179 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
180 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
181 +
182 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
183 +
184 +struct agl_shell;
185 +
186 +namespace wl {
187 +
188 +template <>
189 +struct ObjectTraits<agl_shell> {
190 +  static const wl_interface* interface;
191 +  static void (*deleter)(agl_shell*);
192 +};
193 +
194 +}  // namespace wl
195 +
196 +#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
197 \ No newline at end of file
198 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
199 new file mode 100644
200 index 0000000000000..c74fa5d9cd221
201 --- /dev/null
202 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
203 @@ -0,0 +1,113 @@
204 +// Copyright 2021 LG Electronics, Inc.
205 +//
206 +// Licensed under the Apache License, Version 2.0 (the "License");
207 +// you may not use this file except in compliance with the License.
208 +// You may obtain a copy of the License at
209 +//
210 +// http://www.apache.org/licenses/LICENSE-2.0
211 +//
212 +// Unless required by applicable law or agreed to in writing, software
213 +// distributed under the License is distributed on an "AS IS" BASIS,
214 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
215 +// See the License for the specific language governing permissions and
216 +// limitations under the License.
217 +//
218 +// SPDX-License-Identifier: Apache-2.0
219 +
220 +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
221 +
222 +#include "agl_shell_wrapper.h"
223 +#include "base/logging.h"
224 +#include "ui/base/ui_base_switches.h"
225 +#include "ui/ozone/platform/wayland/host/wayland_connection.h"
226 +#include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
227 +#include "ui/ozone/platform/wayland/host/wayland_window.h"
228 +
229 +namespace ui {
230 +
231 +static const struct agl_shell_listener shell_listener = {
232 +    &AglShellWrapper::AglShellBoundOk,
233 +    &AglShellWrapper::AglShellBoundFail,
234 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
235 +    &AglShellWrapper::AglAppState,
236 +#endif
237 +};
238 +
239 +AglShellWrapper::AglShellWrapper(agl_shell* agl_shell,
240 +                                 WaylandConnection* wayland_connection)
241 +    : agl_shell_(agl_shell), connection_(wayland_connection) {
242 +  if (wl::get_version_of_object(agl_shell) >= AGL_SHELL_BOUND_OK_SINCE_VERSION)
243 +    agl_shell_add_listener(agl_shell, &shell_listener, this);
244 +}
245 +
246 +AglShellWrapper::~AglShellWrapper() = default;
247 +
248 +void AglShellWrapper::SetAglActivateApp(const std::string& app_id) {
249 +  wl_output* output =
250 +      connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
251 +  agl_shell_activate_app(agl_shell_.get(), app_id.c_str(), output);
252 +}
253 +
254 +void AglShellWrapper::SetAglPanel(WaylandWindow* window, uint32_t edge) {
255 +  wl_surface* surface = window->root_surface()->surface();
256 +  wl_output* output =
257 +      connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
258 +
259 +  agl_shell_set_panel(agl_shell_.get(), surface, output, edge);
260 +}
261 +
262 +void AglShellWrapper::SetAglBackground(WaylandWindow* window) {
263 +  wl_surface* surface = window->root_surface()->surface();
264 +  wl_output* output =
265 +      connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
266 +
267 +  agl_shell_set_background(agl_shell_.get(), surface, output);
268 +}
269 +
270 +void AglShellWrapper::SetAglReady() {
271 +  agl_shell_ready(agl_shell_.get());
272 +}
273 +
274 +// static
275 +void AglShellWrapper::AglShellBoundOk(void* data, struct agl_shell*) {
276 +  AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
277 +  wrapper->wait_for_bound_ = false;
278 +  wrapper->bound_ok_ = true;
279 +  LOG(INFO) << "Bound to agl_shell (bound_ok)";
280 +}
281 +
282 +// static
283 +void AglShellWrapper::AglShellBoundFail(void* data, struct agl_shell*) {
284 +  AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
285 +  wrapper->wait_for_bound_ = false;
286 +  wrapper->bound_ok_ = false;
287 +  LOG(INFO) << "Failed to bind to agl_shell (bound_fail)";
288 +}
289 +
290 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
291 +// static
292 +void AglShellWrapper::AglAppState(void* data,
293 +                                  struct agl_shell*,
294 +                                  const char* app_id,
295 +                                  uint32_t state) {
296 +  AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
297 +
298 +  LOG(INFO) << "State for app " << app_id << " changed to " << state;
299 +
300 +  if (state == AGL_SHELL_APP_STATE_STARTED) {
301 +    wrapper->SetAglActivateApp(app_id);
302 +    LOG(INFO) << "Activating app " << app_id;
303 +  }
304 +}
305 +#endif
306 +
307 +bool AglShellWrapper::WaitUntilBoundOk() {
308 +  int ret = 0;
309 +  while (ret != -1 && wait_for_bound_) {
310 +    ret = wl_display_dispatch(connection_->display());
311 +  }
312 +
313 +  return bound_ok_;
314 +}
315 +
316 +}  // namespace ui
317 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
318 new file mode 100644
319 index 0000000000000..2ab765883057e
320 --- /dev/null
321 +++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
322 @@ -0,0 +1,62 @@
323 +// Copyright 2021 LG Electronics, Inc.
324 +//
325 +// Licensed under the Apache License, Version 2.0 (the "License");
326 +// you may not use this file except in compliance with the License.
327 +// You may obtain a copy of the License at
328 +//
329 +// http://www.apache.org/licenses/LICENSE-2.0
330 +//
331 +// Unless required by applicable law or agreed to in writing, software
332 +// distributed under the License is distributed on an "AS IS" BASIS,
333 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
334 +// See the License for the specific language governing permissions and
335 +// limitations under the License.
336 +//
337 +// SPDX-License-Identifier: Apache-2.0
338 +
339 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
340 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
341 +
342 +#include <string>
343 +
344 +#include <agl-shell-client-protocol.h>
345 +
346 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
347 +
348 +namespace ui {
349 +
350 +class WaylandConnection;
351 +class WaylandWindow;
352 +
353 +class AglShellWrapper {
354 + public:
355 +  AglShellWrapper(agl_shell* agl_shell, WaylandConnection* wayland_connection);
356 +  AglShellWrapper(const AglShellWrapper&) = delete;
357 +  AglShellWrapper& operator=(const AglShellWrapper&) = delete;
358 +  ~AglShellWrapper();
359 +
360 +  void SetAglActivateApp(const std::string& app_id);
361 +  void SetAglPanel(WaylandWindow* window, uint32_t edge);
362 +  void SetAglBackground(WaylandWindow* window);
363 +  void SetAglReady();
364 +  bool WaitUntilBoundOk();
365 +
366 +  static void AglShellBoundOk(void* data, struct agl_shell*);
367 +  static void AglShellBoundFail(void* data, struct agl_shell*);
368 +#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
369 +  static void AglAppState(void* data,
370 +                          struct agl_shell*,
371 +                          const char* app_id,
372 +                          uint32_t state);
373 +#endif
374 +
375 + private:
376 +  wl::Object<agl_shell> agl_shell_;
377 +  WaylandConnection* connection_;
378 +  bool wait_for_bound_ = true;
379 +  bool bound_ok_ = false;
380 +};
381 +
382 +}  // namespace ui
383 +
384 +#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
385 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
386 new file mode 100644
387 index 0000000000000..df42fc00c84da
388 --- /dev/null
389 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
390 @@ -0,0 +1,37 @@
391 +// Copyright 2021 LG Electronics, Inc.
392 +//
393 +// Licensed under the Apache License, Version 2.0 (the "License");
394 +// you may not use this file except in compliance with the License.
395 +// You may obtain a copy of the License at
396 +//
397 +// http://www.apache.org/licenses/LICENSE-2.0
398 +//
399 +// Unless required by applicable law or agreed to in writing, software
400 +// distributed under the License is distributed on an "AS IS" BASIS,
401 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
402 +// See the License for the specific language governing permissions and
403 +// limitations under the License.
404 +//
405 +// SPDX-License-Identifier: Apache-2.0
406 +
407 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
408 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
409 +
410 +namespace ui {
411 +
412 +class AglShellWrapper;
413 +
414 +// AGL extensions implementation for webOS/Lite
415 +class WaylandExtensionsAgl {
416 + public:
417 +  WaylandExtensionsAgl() = default;
418 +  WaylandExtensionsAgl(const WaylandExtensionsAgl&) = delete;
419 +  WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete;
420 +  virtual ~WaylandExtensionsAgl() = default;
421 +
422 +  virtual AglShellWrapper* GetAglShell() = 0;
423 +};
424 +
425 +}  // namespace ui
426 +
427 +#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
428 \ No newline at end of file
429 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
430 new file mode 100644
431 index 0000000000000..26a5f0550c302
432 --- /dev/null
433 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
434 @@ -0,0 +1,93 @@
435 +// Copyright 2021 LG Electronics, Inc.
436 +//
437 +// Licensed under the Apache License, Version 2.0 (the "License");
438 +// you may not use this file except in compliance with the License.
439 +// You may obtain a copy of the License at
440 +//
441 +// http://www.apache.org/licenses/LICENSE-2.0
442 +//
443 +// Unless required by applicable law or agreed to in writing, software
444 +// distributed under the License is distributed on an "AS IS" BASIS,
445 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
446 +// See the License for the specific language governing permissions and
447 +// limitations under the License.
448 +//
449 +// SPDX-License-Identifier: Apache-2.0
450 +
451 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h"
452 +
453 +#include <cstring>
454 +
455 +#include "base/command_line.h"
456 +#include "base/logging.h"
457 +#include "ui/base/ui_base_switches.h"
458 +#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
459 +#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
460 +#include "ui/ozone/platform/wayland/host/wayland_connection.h"
461 +
462 +namespace ui {
463 +
464 +namespace {
465 +
466 +constexpr uint32_t kMinAglShellExtensionVersion = 1;
467 +constexpr uint32_t kMaxAglShellExtensionVersion = 3;
468 +
469 +}  // namespace
470 +
471 +WaylandExtensionsAglImpl::WaylandExtensionsAglImpl(
472 +    WaylandConnection* connection)
473 +    : connection_(connection) {}
474 +
475 +WaylandExtensionsAglImpl::~WaylandExtensionsAglImpl() = default;
476 +
477 +bool WaylandExtensionsAglImpl::Bind(wl_registry* registry,
478 +                                    uint32_t name,
479 +                                    const char* interface,
480 +                                    uint32_t version) {
481 +  bool should_use_agl_shell = base::CommandLine::ForCurrentProcess()->HasSwitch(
482 +      switches::kAglShellAppId);
483 +  bool can_bind = wl::CanBind(interface, version, kMinAglShellExtensionVersion,
484 +                              kMaxAglShellExtensionVersion);
485 +  bool is_agl_shell_interface = (strcmp(interface, "agl_shell") == 0);
486 +
487 +  if (!is_agl_shell_interface) {
488 +      return false;
489 +  }
490 +
491 +  LOG(INFO) << "should_use_agl_shell: " << should_use_agl_shell <<
492 +               " can_bind: " << can_bind;
493 +
494 +  if (should_use_agl_shell && !agl_shell_ &&
495 +      is_agl_shell_interface && can_bind) {
496 +    wl::Object<agl_shell> aglshell = wl::Bind<agl_shell>(
497 +        registry, name, std::min(version, kMaxAglShellExtensionVersion));
498 +    if (!aglshell) {
499 +      LOG(ERROR) << "Failed to bind to agl_shell global";
500 +      return false;
501 +    }
502 +    agl_shell_ =
503 +        std::make_unique<AglShellWrapper>(aglshell.release(), connection_);
504 +
505 +    LOG(INFO) << "Waiting until bound...";
506 +    return agl_shell_->WaitUntilBoundOk();
507 +  } else {
508 +    LOG(INFO) << "Cant bind.";
509 +  }
510 +
511 +  return false;
512 +}
513 +
514 +bool WaylandExtensionsAglImpl::HasShellObject() const {
515 +  return !!agl_shell_;
516 +}
517 +
518 +AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() {
519 +  return agl_shell_.get();
520 +}
521 +
522 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
523 +    WaylandConnection* connection) {
524 +  return std::make_unique<WaylandExtensionsAglImpl>(connection);
525 +}
526 +
527 +}  // namespace ui
528 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
529 new file mode 100644
530 index 0000000000000..f6cbabe99ed0b
531 --- /dev/null
532 +++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
533 @@ -0,0 +1,54 @@
534 +// Copyright 2021 LG Electronics, Inc.
535 +//
536 +// Licensed under the Apache License, Version 2.0 (the "License");
537 +// you may not use this file except in compliance with the License.
538 +// You may obtain a copy of the License at
539 +//
540 +// http://www.apache.org/licenses/LICENSE-2.0
541 +//
542 +// Unless required by applicable law or agreed to in writing, software
543 +// distributed under the License is distributed on an "AS IS" BASIS,
544 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
545 +// See the License for the specific language governing permissions and
546 +// limitations under the License.
547 +//
548 +// SPDX-License-Identifier: Apache-2.0
549 +
550 +#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
551 +#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
552 +
553 +#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h"
554 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
555 +
556 +namespace ui {
557 +
558 +class AglShellWrapper;
559 +
560 +// AGL extension implementation for webOS/Lite
561 +class WaylandExtensionsAglImpl : public WaylandExtensions,
562 +                                 public WaylandExtensionsAgl {
563 + public:
564 +  explicit WaylandExtensionsAglImpl(WaylandConnection* connection);
565 +  WaylandExtensionsAglImpl(const WaylandExtensionsAglImpl&) = delete;
566 +  WaylandExtensionsAglImpl& operator=(const WaylandExtensionsAglImpl&) = delete;
567 +  ~WaylandExtensionsAglImpl() override;
568 +
569 +  // WaylandExtensions overrides
570 +  bool Bind(wl_registry* registry,
571 +            uint32_t name,
572 +            const char* interface,
573 +            uint32_t version) override;
574 +
575 +  bool HasShellObject() const override;
576 +
577 +  // WaylandExtensionsAgl overrides
578 +  AglShellWrapper* GetAglShell() override;
579 +
580 + private:
581 +  std::unique_ptr<AglShellWrapper> agl_shell_;
582 +  WaylandConnection* connection_;
583 +};
584 +
585 +}  // namespace ui
586 +
587 +#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
588 diff --git a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
589 new file mode 100644
590 index 0000000000000..ad5553d61f189
591 --- /dev/null
592 +++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
593 @@ -0,0 +1,179 @@
594 +<?xml version="1.0" encoding="UTF-8"?>
595 +<protocol name="agl_shell">
596 +  <copyright>
597 +    Copyright Â© 2019, 2022 Collabora, Ltd.
598 +
599 +    Permission is hereby granted, free of charge, to any person obtaining a
600 +    copy of this software and associated documentation files (the "Software"),
601 +    to deal in the Software without restriction, including without limitation
602 +    the rights to use, copy, modify, merge, publish, distribute, sublicense,
603 +    and/or sell copies of the Software, and to permit persons to whom the
604 +    Software is furnished to do so, subject to the following conditions:
605 +
606 +    The above copyright notice and this permission notice (including the next
607 +    paragraph) shall be included in all copies or substantial portions of the
608 +    Software.
609 +
610 +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
611 +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
612 +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
613 +    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
614 +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
615 +    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
616 +    DEALINGS IN THE SOFTWARE.
617 +  </copyright>
618 +  <interface name="agl_shell" version="3">
619 +    <description summary="user interface for Automotive Grade Linux platform">
620 +      Starting with version 2 of the protocol, the client is required to wait
621 +      for the 'bound_ok' or 'bound_fail' events in order to proceed further.
622 +
623 +      In case the client gets a 'bound_fail' event then it should consider that
624 +      there's another client already bound to the agl_shell protocol.
625 +      A client that receives a 'bound_ok' event should consider that there's
626 +      no other client already bound to the interface and can proceed further.
627 +
628 +      If the client uses an older version of the protocol it will receive
629 +      automatically an error and the compositor will terminate the connection,
630 +      if there's another client already bound the interface.
631 +
632 +      If the client receives the 'bound_fail' event and attempts to use the
633 +      interface further it will receive an error and the compositor will
634 +      terminate the connection. After the 'bound_fail' event was received the
635 +      client should call the destructor, which has been added with version 2
636 +      of the protocol. The client is free to try at a later point in time to
637 +      see if it will receive the 'bound_ok' event, but there's no explicit way
638 +      of finding out when that event will be delivered.
639 +      It is assumed that it can infer that information through other
640 +      means/other channels.
641 +    </description>
642 +
643 +    <enum name="error">
644 +      <entry name="invalid_argument" value="0"/>
645 +      <entry name="background_exists" value="1"/>
646 +      <entry name="panel_exists" value="2"/>
647 +    </enum>
648 +
649 +    <enum name="edge">
650 +      <entry name="top" value="0"/>
651 +      <entry name="bottom" value="1"/>
652 +      <entry name="left" value="2"/>
653 +      <entry name="right" value="3"/>
654 +    </enum>
655 +
656 +    <enum name="app_state" since="3">
657 +      <entry name="started" value="0"/>
658 +      <entry name="terminated" value="1"/>
659 +      <entry name="activated" value="2"/>
660 +      <entry name="deactivated" value="3"/>
661 +    </enum>
662 +
663 +    <request name="ready">
664 +      <description summary="client is ready to be shown">
665 +        Tell the server that this client is ready to be shown. The server
666 +        will delay presentation during start-up until all shell clients are
667 +        ready to be shown, and will display a black screen instead.
668 +        This gives the client an opportunity to set up and configure several
669 +        surfaces into a coherent interface.
670 +
671 +        The client that binds to this interface must send this request, otherwise
672 +        they may stall the compositor unnecessarily.
673 +
674 +        If this request is called after the compositor has already finished
675 +        start-up, no operation is performed.
676 +      </description>
677 +    </request>
678 +
679 +    <request name="set_background">
680 +      <description summary="set surface as output's background">
681 +        Set the surface to act as the background of an output. After this
682 +        request, the server will immediately send a configure event with
683 +        the dimensions the client should use to cover the entire output.
684 +
685 +        The surface must have a "desktop" surface role, as supported by
686 +        libweston-desktop.
687 +
688 +        Only a single surface may be the background for any output. If a
689 +        background surface already exists, a protocol error is raised.
690 +      </description>
691 +      <arg name="surface" type="object" interface="wl_surface"/>
692 +      <arg name="output" type="object" interface="wl_output"/>
693 +    </request>
694 +
695 +    <request name="set_panel">
696 +      <description summary="set surface as panel">
697 +        Set the surface to act as a panel of an output. The 'edge' argument
698 +        says what edge of the output the surface will be anchored to.
699 +        After this request, the server will send a configure event with the
700 +        corresponding width/height that the client should use, and 0 for the
701 +        other dimension. E.g. if the edge is 'top', the width will be the
702 +        output's width, and the height will be 0.
703 +
704 +        The surface must have a "desktop" surface role, as supported by
705 +        libweston-desktop.
706 +
707 +        The compositor will take the panel's window geometry into account when
708 +        positioning other windows, so the panels are not covered.
709 +
710 +        XXX: What happens if e.g. both top and left are used at the same time?
711 +        Who gets to have the corner?
712 +
713 +        Only a single surface may be the panel for an output's edge. If a
714 +        surface already exists on an edge, a protocol error is raised.
715 +      </description>
716 +      <arg name="surface" type="object" interface="wl_surface"/>
717 +      <arg name="output" type="object" interface="wl_output"/>
718 +      <arg name="edge" type="uint" enum="edge"/>
719 +    </request>
720 +
721 +    <request name="activate_app">
722 +      <description summary="make client current window">
723 +        Ask the compositor to make a toplevel to become the current/focused
724 +        window for window management purposes.
725 +
726 +        See xdg_toplevel.set_app_id from the xdg-shell protocol for a
727 +        description of app_id.
728 +
729 +        If multiple toplevels have the same app_id, the result is unspecified.
730 +
731 +        XXX: Do we need feedback to say it didn't work? (e.g. client does
732 +        not exist)
733 +      </description>
734 +      <arg name="app_id" type="string"/>
735 +      <arg name="output" type="object" interface="wl_output"/>
736 +    </request>
737 +
738 +    <event name="bound_ok" since="2">
739 +     <description summary="event sent if binding was ok">
740 +        Informs the client that it was able to bind the agl_shell
741 +        interface succesfully. Clients are required to wait for this
742 +        event before continuing further.
743 +     </description>
744 +    </event>
745 +
746 +    <event name="bound_fail" since="2">
747 +      <description summary="event sent if binding was nok">
748 +        Informs the client that binding to the agl_shell interface was
749 +        unsuccesfull. Clients are required to wait for this event for
750 +        continuing further.
751 +      </description>
752 +    </event>
753 +
754 +    <request name="destroy" type="destructor" since="2">
755 +      <description summary="destroys the factory object">
756 +      </description>
757 +    </request>
758 +
759 +    <event name="app_state" since="3">
760 +      <description summary="event sent when an application suffered state modification">
761 +        Informs the client that an application has changed its state to another,
762 +        specified by the app_state enum. Client can use this event to track
763 +        current application state. For instance to know when the application has
764 +        started, or when terminated/stopped.
765 +      </description>
766 +      <arg name="app_id" type="string"/>
767 +      <arg name="state" type="uint" enum="app_state"/>
768 +    </event>
769 +
770 +
771 +  </interface>
772 +</protocol>
773 diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
774 index 6d44128e56458..93427c52e1284 100644
775 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc
776 +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
777 @@ -64,6 +64,8 @@
778  #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h"
779  #include "ui/platform_window/common/platform_window_defaults.h"
780  
781 +#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
782 +
783  #if defined(USE_LIBWAYLAND_STUBS)
784  #include <dlfcn.h>
785  
786 @@ -238,6 +240,10 @@ bool WaylandConnection::Initialize() {
787      return false;
788    }
789  
790 +  if (!extensions_) {
791 +    extensions_ = CreateWaylandExtensions(this);
792 +  }
793 +
794    // Now that the connection with the display server has been properly
795    // estabilished, initialize the event source and input objects.
796    DCHECK(!event_source_);
797 @@ -264,7 +270,7 @@ bool WaylandConnection::Initialize() {
798      LOG(ERROR) << "No wl_shm object";
799      return false;
800    }
801 -  if (!shell_v6_ && !shell_) {
802 +  if (!shell_v6_ && !shell_ && !(extensions_ && extensions_->HasShellObject())) {
803      LOG(ERROR) << "No Wayland shell found";
804      return false;
805    }
806 @@ -434,7 +440,9 @@ void WaylandConnection::Global(void* data,
807    auto* connection = static_cast<WaylandConnection*>(data);
808  
809    auto factory_it = connection->global_object_factories_.find(interface);
810 -  if (factory_it != connection->global_object_factories_.end()) {
811 +  if (connection->extensions_->Bind(registry, name, interface, version)) {
812 +    DVLOG(1) << "Successfully bound to " << interface;
813 +  } else if (factory_it != connection->global_object_factories_.end()) {
814      (*factory_it->second)(connection, registry, name, interface, version);
815    } else if (!connection->compositor_ &&
816               strcmp(interface, "wl_compositor") == 0) {
817 diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
818 index d33959ad4066f..dfd1d060c73f2 100644
819 --- a/ui/ozone/platform/wayland/host/wayland_connection.h
820 +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
821 @@ -45,6 +45,7 @@ class WaylandBufferManagerHost;
822  class WaylandCursor;
823  class WaylandCursorBufferListener;
824  class WaylandEventSource;
825 +class WaylandExtensions;
826  class WaylandOutputManager;
827  class WaylandSeat;
828  class WaylandZAuraShell;
829 @@ -185,6 +186,8 @@ class WaylandConnection {
830  
831    WaylandZAuraShell* zaura_shell() const { return zaura_shell_.get(); }
832  
833 +  WaylandExtensions* extensions() { return extensions_.get(); }
834 +
835    WaylandZcrColorManager* zcr_color_manager() const {
836      return zcr_color_manager_.get();
837    }
838 @@ -424,6 +427,9 @@ class WaylandConnection {
839    std::unique_ptr<OverlayPrioritizer> overlay_prioritizer_;
840    std::unique_ptr<SurfaceAugmenter> surface_augmenter_;
841  
842 +  std::unique_ptr<WaylandExtensions> extensions_;
843 +
844 +
845    // Clipboard-related objects. |clipboard_| must be declared after all
846    // DeviceManager instances it depends on, otherwise tests may crash with
847    // UAFs while attempting to access already destroyed manager pointers.
848 diff --git a/ui/ozone/platform/wayland/host/wayland_extensions.h b/ui/ozone/platform/wayland/host/wayland_extensions.h
849 new file mode 100644
850 index 0000000000000..3bd2fd7a211ae
851 --- /dev/null
852 +++ b/ui/ozone/platform/wayland/host/wayland_extensions.h
853 @@ -0,0 +1,56 @@
854 +// Copyright 2019 LG Electronics, Inc.
855 +//
856 +// Licensed under the Apache License, Version 2.0 (the "License");
857 +// you may not use this file except in compliance with the License.
858 +// You may obtain a copy of the License at
859 +//
860 +// http://www.apache.org/licenses/LICENSE-2.0
861 +//
862 +// Unless required by applicable law or agreed to in writing, software
863 +// distributed under the License is distributed on an "AS IS" BASIS,
864 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
865 +// See the License for the specific language governing permissions and
866 +// limitations under the License.
867 +//
868 +// SPDX-License-Identifier: Apache-2.0
869 +
870 +#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
871 +#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
872 +
873 +#include <memory>
874 +
875 +#include "ui/ozone/platform/wayland/common/wayland_object.h"
876 +
877 +namespace ui {
878 +
879 +class ShellToplevelWrapper;
880 +class ShellPopupWrapper;
881 +class WaylandConnection;
882 +
883 +// Wayland extensions abstract interface to support extending of the Wayland
884 +// protocol. Inherit it to provide your own Wayland extensions implementation.
885 +class WaylandExtensions {
886 + public:
887 +  WaylandExtensions() = default;
888 +  WaylandExtensions(const WaylandExtensions&) = delete;
889 +  WaylandExtensions& operator=(const WaylandExtensions&) = delete;
890 +  virtual ~WaylandExtensions() = default;
891 +
892 +  // Binds to the extensions interface(s). Can encapsulate binding of several
893 +  // interfaces, defined by |interface|.
894 +  virtual bool Bind(wl_registry* registry,
895 +                    uint32_t name,
896 +                    const char* interface,
897 +                    uint32_t version) = 0;
898 +
899 +  // Checks whether the extensions have bound shell object(s).
900 +  virtual bool HasShellObject() const = 0;
901 +};
902 +
903 +// Creates Wayland extensions.
904 +std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
905 +  WaylandConnection* connection);
906 +
907 +}  // namespace ui
908 +
909 +#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
910 -- 
911 2.39.2
912