[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
diff --git a/recipes-wam/cef/files/chromium/0005-Add-the-essential-parts-of-wayland-extensions-and-ag.patch b/recipes-wam/cef/files/chromium/0005-Add-the-essential-parts-of-wayland-extensions-and-ag.patch
new file mode 100644 (file)
index 0000000..fea8c04
--- /dev/null
@@ -0,0 +1,912 @@
+From 7e927a21ecaa70c14873d5f06667dfc3bdaa4d25 Mon Sep 17 00:00:00 2001
+From: Roger Zanoni <rzanoni@igalia.com>
+Date: Mon, 15 May 2023 20:32:06 +0200
+Subject: [PATCH 5/9] Add the essential parts of wayland extensions and
+ agl_shell
+
+---
+ ui/base/ui_base_switches.cc                   |   2 +
+ ui/base/ui_base_switches.h                    |   3 +
+ ui/ozone/platform/wayland/BUILD.gn            |   7 +
+ .../platform/wayland/extensions/agl/BUILD.gn  |  40 ++++
+ .../agl/common/wayland_object_agl.cc          |  26 +++
+ .../agl/common/wayland_object_agl.h           |  34 ++++
+ .../extensions/agl/host/agl_shell_wrapper.cc  | 113 +++++++++++
+ .../extensions/agl/host/agl_shell_wrapper.h   |  62 ++++++
+ .../agl/host/wayland_extensions_agl.h         |  37 ++++
+ .../agl/host/wayland_extensions_agl_impl.cc   |  93 +++++++++
+ .../agl/host/wayland_extensions_agl_impl.h    |  54 ++++++
+ .../extensions/agl/protocol/agl-shell.xml     | 179 ++++++++++++++++++
+ .../wayland/host/wayland_connection.cc        |  12 +-
+ .../wayland/host/wayland_connection.h         |   6 +
+ .../wayland/host/wayland_extensions.h         |  56 ++++++
+ 15 files changed, 722 insertions(+), 2 deletions(-)
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/BUILD.gn
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
+ create mode 100644 ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
+ create mode 100644 ui/ozone/platform/wayland/host/wayland_extensions.h
+
+diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
+index f8556679a79d8..e72ae83737c04 100644
+--- a/ui/base/ui_base_switches.cc
++++ b/ui/base/ui_base_switches.cc
+@@ -100,4 +100,6 @@ const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
+ // Enables the ozone x11 clipboard for linux-chromeos.
+ const char kUseSystemClipboard[] = "use-system-clipboard";
++const char kAglShellAppId[] = "agl-shell-appid";
++
+ }  // namespace switches
+diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
+index d35e544f2bc2f..019ba0e5151e5 100644
+--- a/ui/base/ui_base_switches.h
++++ b/ui/base/ui_base_switches.h
+@@ -45,6 +45,9 @@ COMPONENT_EXPORT(UI_BASE) extern const char kTopChromeTouchUiEnabled[];
+ COMPONENT_EXPORT(UI_BASE) extern const char kUIDisablePartialSwap[];
+ COMPONENT_EXPORT(UI_BASE) extern const char kUseSystemClipboard[];
++// Agl related
++COMPONENT_EXPORT(UI_BASE) extern const char kAglShellAppId[];
++
+ // Test related.
+ COMPONENT_EXPORT(UI_BASE) extern const char kDisallowNonExactResourceReuse[];
+ COMPONENT_EXPORT(UI_BASE) extern const char kMangleLocalizedStrings[];
+diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
+index e0f0d7dea3747..1a2f889dc8947 100644
+--- a/ui/ozone/platform/wayland/BUILD.gn
++++ b/ui/ozone/platform/wayland/BUILD.gn
+@@ -407,6 +407,13 @@ source_set("wayland") {
+     ]
+   }
++  sources += [
++   "host/wayland_extensions.h",
++   "host/wayland_extensions_stub.cc",
++  ]
++
++  deps += [ "extensions/agl" ]
++
+   configs += [ "//third_party/khronos:khronos_headers" ]
+ }
+diff --git a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
+new file mode 100644
+index 0000000000000..ce289bc5dbbca
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn
+@@ -0,0 +1,40 @@
++# Copyright 2021 LG Electronics, Inc.
++#
++# Licensed under the Apache License, Version 2.0 (the "License");
++# you may not use this file except in compliance with the License.
++# You may obtain a copy of the License at
++#
++# http://www.apache.org/licenses/LICENSE-2.0
++#
++# Unless required by applicable law or agreed to in writing, software
++# distributed under the License is distributed on an "AS IS" BASIS,
++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++# See the License for the specific language governing permissions and
++# limitations under the License.
++#
++# SPDX-License-Identifier: Apache-2.0
++
++import("//third_party/wayland/wayland_protocol.gni")
++
++visibility = [ "//ui/ozone/*" ]
++
++wayland_protocol("agl_shell_protocol") {
++  sources = [ "protocol/agl-shell.xml" ]
++}
++
++source_set("agl") {
++  sources = [
++    "common/wayland_object_agl.cc",
++    "common/wayland_object_agl.h",
++    "host/agl_shell_wrapper.cc",
++    "host/agl_shell_wrapper.h",
++    "host/wayland_extensions_agl.h",
++    "host/wayland_extensions_agl_impl.cc",
++    "host/wayland_extensions_agl_impl.h",
++  ]
++
++  deps = [
++    ":agl_shell_protocol",
++    "//ui/ozone/platform/wayland/mojom",
++  ]
++}
+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
+new file mode 100644
+index 0000000000000..9f3300766df2c
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc
+@@ -0,0 +1,26 @@
++// Copyright 2021 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
++
++#include <agl-shell-client-protocol.h>
++
++namespace wl {
++
++const wl_interface* ObjectTraits<agl_shell>::interface = &agl_shell_interface;
++void (*ObjectTraits<agl_shell>::deleter)(agl_shell*) = &agl_shell_destroy;
++
++}  // namespace wl
+\ No newline at end of file
+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
+new file mode 100644
+index 0000000000000..e91ac0da8d2fc
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h
+@@ -0,0 +1,34 @@
++// Copyright 2021 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
++
++#include "ui/ozone/platform/wayland/common/wayland_object.h"
++
++struct agl_shell;
++
++namespace wl {
++
++template <>
++struct ObjectTraits<agl_shell> {
++  static const wl_interface* interface;
++  static void (*deleter)(agl_shell*);
++};
++
++}  // namespace wl
++
++#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_
+\ No newline at end of file
+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
+new file mode 100644
+index 0000000000000..c74fa5d9cd221
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc
+@@ -0,0 +1,113 @@
++// Copyright 2021 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
++
++#include "agl_shell_wrapper.h"
++#include "base/logging.h"
++#include "ui/base/ui_base_switches.h"
++#include "ui/ozone/platform/wayland/host/wayland_connection.h"
++#include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
++#include "ui/ozone/platform/wayland/host/wayland_window.h"
++
++namespace ui {
++
++static const struct agl_shell_listener shell_listener = {
++    &AglShellWrapper::AglShellBoundOk,
++    &AglShellWrapper::AglShellBoundFail,
++#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
++    &AglShellWrapper::AglAppState,
++#endif
++};
++
++AglShellWrapper::AglShellWrapper(agl_shell* agl_shell,
++                                 WaylandConnection* wayland_connection)
++    : agl_shell_(agl_shell), connection_(wayland_connection) {
++  if (wl::get_version_of_object(agl_shell) >= AGL_SHELL_BOUND_OK_SINCE_VERSION)
++    agl_shell_add_listener(agl_shell, &shell_listener, this);
++}
++
++AglShellWrapper::~AglShellWrapper() = default;
++
++void AglShellWrapper::SetAglActivateApp(const std::string& app_id) {
++  wl_output* output =
++      connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
++  agl_shell_activate_app(agl_shell_.get(), app_id.c_str(), output);
++}
++
++void AglShellWrapper::SetAglPanel(WaylandWindow* window, uint32_t edge) {
++  wl_surface* surface = window->root_surface()->surface();
++  wl_output* output =
++      connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
++
++  agl_shell_set_panel(agl_shell_.get(), surface, output, edge);
++}
++
++void AglShellWrapper::SetAglBackground(WaylandWindow* window) {
++  wl_surface* surface = window->root_surface()->surface();
++  wl_output* output =
++      connection_->wayland_output_manager()->GetPrimaryOutput()->get_output();
++
++  agl_shell_set_background(agl_shell_.get(), surface, output);
++}
++
++void AglShellWrapper::SetAglReady() {
++  agl_shell_ready(agl_shell_.get());
++}
++
++// static
++void AglShellWrapper::AglShellBoundOk(void* data, struct agl_shell*) {
++  AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
++  wrapper->wait_for_bound_ = false;
++  wrapper->bound_ok_ = true;
++  LOG(INFO) << "Bound to agl_shell (bound_ok)";
++}
++
++// static
++void AglShellWrapper::AglShellBoundFail(void* data, struct agl_shell*) {
++  AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
++  wrapper->wait_for_bound_ = false;
++  wrapper->bound_ok_ = false;
++  LOG(INFO) << "Failed to bind to agl_shell (bound_fail)";
++}
++
++#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
++// static
++void AglShellWrapper::AglAppState(void* data,
++                                  struct agl_shell*,
++                                  const char* app_id,
++                                  uint32_t state) {
++  AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data);
++
++  LOG(INFO) << "State for app " << app_id << " changed to " << state;
++
++  if (state == AGL_SHELL_APP_STATE_STARTED) {
++    wrapper->SetAglActivateApp(app_id);
++    LOG(INFO) << "Activating app " << app_id;
++  }
++}
++#endif
++
++bool AglShellWrapper::WaitUntilBoundOk() {
++  int ret = 0;
++  while (ret != -1 && wait_for_bound_) {
++    ret = wl_display_dispatch(connection_->display());
++  }
++
++  return bound_ok_;
++}
++
++}  // namespace ui
+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
+new file mode 100644
+index 0000000000000..2ab765883057e
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h
+@@ -0,0 +1,62 @@
++// Copyright 2021 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
++
++#include <string>
++
++#include <agl-shell-client-protocol.h>
++
++#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
++
++namespace ui {
++
++class WaylandConnection;
++class WaylandWindow;
++
++class AglShellWrapper {
++ public:
++  AglShellWrapper(agl_shell* agl_shell, WaylandConnection* wayland_connection);
++  AglShellWrapper(const AglShellWrapper&) = delete;
++  AglShellWrapper& operator=(const AglShellWrapper&) = delete;
++  ~AglShellWrapper();
++
++  void SetAglActivateApp(const std::string& app_id);
++  void SetAglPanel(WaylandWindow* window, uint32_t edge);
++  void SetAglBackground(WaylandWindow* window);
++  void SetAglReady();
++  bool WaitUntilBoundOk();
++
++  static void AglShellBoundOk(void* data, struct agl_shell*);
++  static void AglShellBoundFail(void* data, struct agl_shell*);
++#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION
++  static void AglAppState(void* data,
++                          struct agl_shell*,
++                          const char* app_id,
++                          uint32_t state);
++#endif
++
++ private:
++  wl::Object<agl_shell> agl_shell_;
++  WaylandConnection* connection_;
++  bool wait_for_bound_ = true;
++  bool bound_ok_ = false;
++};
++
++}  // namespace ui
++
++#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_
+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
+new file mode 100644
+index 0000000000000..df42fc00c84da
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h
+@@ -0,0 +1,37 @@
++// Copyright 2021 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
++
++namespace ui {
++
++class AglShellWrapper;
++
++// AGL extensions implementation for webOS/Lite
++class WaylandExtensionsAgl {
++ public:
++  WaylandExtensionsAgl() = default;
++  WaylandExtensionsAgl(const WaylandExtensionsAgl&) = delete;
++  WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete;
++  virtual ~WaylandExtensionsAgl() = default;
++
++  virtual AglShellWrapper* GetAglShell() = 0;
++};
++
++}  // namespace ui
++
++#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_
+\ No newline at end of file
+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
+new file mode 100644
+index 0000000000000..26a5f0550c302
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc
+@@ -0,0 +1,93 @@
++// Copyright 2021 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h"
++
++#include <cstring>
++
++#include "base/command_line.h"
++#include "base/logging.h"
++#include "ui/base/ui_base_switches.h"
++#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h"
++#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h"
++#include "ui/ozone/platform/wayland/host/wayland_connection.h"
++
++namespace ui {
++
++namespace {
++
++constexpr uint32_t kMinAglShellExtensionVersion = 1;
++constexpr uint32_t kMaxAglShellExtensionVersion = 3;
++
++}  // namespace
++
++WaylandExtensionsAglImpl::WaylandExtensionsAglImpl(
++    WaylandConnection* connection)
++    : connection_(connection) {}
++
++WaylandExtensionsAglImpl::~WaylandExtensionsAglImpl() = default;
++
++bool WaylandExtensionsAglImpl::Bind(wl_registry* registry,
++                                    uint32_t name,
++                                    const char* interface,
++                                    uint32_t version) {
++  bool should_use_agl_shell = base::CommandLine::ForCurrentProcess()->HasSwitch(
++      switches::kAglShellAppId);
++  bool can_bind = wl::CanBind(interface, version, kMinAglShellExtensionVersion,
++                              kMaxAglShellExtensionVersion);
++  bool is_agl_shell_interface = (strcmp(interface, "agl_shell") == 0);
++
++  if (!is_agl_shell_interface) {
++      return false;
++  }
++
++  LOG(INFO) << "should_use_agl_shell: " << should_use_agl_shell <<
++               " can_bind: " << can_bind;
++
++  if (should_use_agl_shell && !agl_shell_ &&
++      is_agl_shell_interface && can_bind) {
++    wl::Object<agl_shell> aglshell = wl::Bind<agl_shell>(
++        registry, name, std::min(version, kMaxAglShellExtensionVersion));
++    if (!aglshell) {
++      LOG(ERROR) << "Failed to bind to agl_shell global";
++      return false;
++    }
++    agl_shell_ =
++        std::make_unique<AglShellWrapper>(aglshell.release(), connection_);
++
++    LOG(INFO) << "Waiting until bound...";
++    return agl_shell_->WaitUntilBoundOk();
++  } else {
++    LOG(INFO) << "Cant bind.";
++  }
++
++  return false;
++}
++
++bool WaylandExtensionsAglImpl::HasShellObject() const {
++  return !!agl_shell_;
++}
++
++AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() {
++  return agl_shell_.get();
++}
++
++std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
++    WaylandConnection* connection) {
++  return std::make_unique<WaylandExtensionsAglImpl>(connection);
++}
++
++}  // namespace ui
+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
+new file mode 100644
+index 0000000000000..f6cbabe99ed0b
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h
+@@ -0,0 +1,54 @@
++// Copyright 2021 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
++
++#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h"
++#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
++
++namespace ui {
++
++class AglShellWrapper;
++
++// AGL extension implementation for webOS/Lite
++class WaylandExtensionsAglImpl : public WaylandExtensions,
++                                 public WaylandExtensionsAgl {
++ public:
++  explicit WaylandExtensionsAglImpl(WaylandConnection* connection);
++  WaylandExtensionsAglImpl(const WaylandExtensionsAglImpl&) = delete;
++  WaylandExtensionsAglImpl& operator=(const WaylandExtensionsAglImpl&) = delete;
++  ~WaylandExtensionsAglImpl() override;
++
++  // WaylandExtensions overrides
++  bool Bind(wl_registry* registry,
++            uint32_t name,
++            const char* interface,
++            uint32_t version) override;
++
++  bool HasShellObject() const override;
++
++  // WaylandExtensionsAgl overrides
++  AglShellWrapper* GetAglShell() override;
++
++ private:
++  std::unique_ptr<AglShellWrapper> agl_shell_;
++  WaylandConnection* connection_;
++};
++
++}  // namespace ui
++
++#endif  // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_
+diff --git a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
+new file mode 100644
+index 0000000000000..ad5553d61f189
+--- /dev/null
++++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml
+@@ -0,0 +1,179 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<protocol name="agl_shell">
++  <copyright>
++    Copyright © 2019, 2022 Collabora, Ltd.
++
++    Permission is hereby granted, free of charge, to any person obtaining a
++    copy of this software and associated documentation files (the "Software"),
++    to deal in the Software without restriction, including without limitation
++    the rights to use, copy, modify, merge, publish, distribute, sublicense,
++    and/or sell copies of the Software, and to permit persons to whom the
++    Software is furnished to do so, subject to the following conditions:
++
++    The above copyright notice and this permission notice (including the next
++    paragraph) shall be included in all copies or substantial portions of the
++    Software.
++
++    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++    DEALINGS IN THE SOFTWARE.
++  </copyright>
++  <interface name="agl_shell" version="3">
++    <description summary="user interface for Automotive Grade Linux platform">
++      Starting with version 2 of the protocol, the client is required to wait
++      for the 'bound_ok' or 'bound_fail' events in order to proceed further.
++
++      In case the client gets a 'bound_fail' event then it should consider that
++      there's another client already bound to the agl_shell protocol.
++      A client that receives a 'bound_ok' event should consider that there's
++      no other client already bound to the interface and can proceed further.
++
++      If the client uses an older version of the protocol it will receive
++      automatically an error and the compositor will terminate the connection,
++      if there's another client already bound the interface.
++
++      If the client receives the 'bound_fail' event and attempts to use the
++      interface further it will receive an error and the compositor will
++      terminate the connection. After the 'bound_fail' event was received the
++      client should call the destructor, which has been added with version 2
++      of the protocol. The client is free to try at a later point in time to
++      see if it will receive the 'bound_ok' event, but there's no explicit way
++      of finding out when that event will be delivered.
++      It is assumed that it can infer that information through other
++      means/other channels.
++    </description>
++
++    <enum name="error">
++      <entry name="invalid_argument" value="0"/>
++      <entry name="background_exists" value="1"/>
++      <entry name="panel_exists" value="2"/>
++    </enum>
++
++    <enum name="edge">
++      <entry name="top" value="0"/>
++      <entry name="bottom" value="1"/>
++      <entry name="left" value="2"/>
++      <entry name="right" value="3"/>
++    </enum>
++
++    <enum name="app_state" since="3">
++      <entry name="started" value="0"/>
++      <entry name="terminated" value="1"/>
++      <entry name="activated" value="2"/>
++      <entry name="deactivated" value="3"/>
++    </enum>
++
++    <request name="ready">
++      <description summary="client is ready to be shown">
++        Tell the server that this client is ready to be shown. The server
++        will delay presentation during start-up until all shell clients are
++        ready to be shown, and will display a black screen instead.
++        This gives the client an opportunity to set up and configure several
++        surfaces into a coherent interface.
++
++        The client that binds to this interface must send this request, otherwise
++        they may stall the compositor unnecessarily.
++
++        If this request is called after the compositor has already finished
++        start-up, no operation is performed.
++      </description>
++    </request>
++
++    <request name="set_background">
++      <description summary="set surface as output's background">
++        Set the surface to act as the background of an output. After this
++        request, the server will immediately send a configure event with
++        the dimensions the client should use to cover the entire output.
++
++        The surface must have a "desktop" surface role, as supported by
++        libweston-desktop.
++
++        Only a single surface may be the background for any output. If a
++        background surface already exists, a protocol error is raised.
++      </description>
++      <arg name="surface" type="object" interface="wl_surface"/>
++      <arg name="output" type="object" interface="wl_output"/>
++    </request>
++
++    <request name="set_panel">
++      <description summary="set surface as panel">
++        Set the surface to act as a panel of an output. The 'edge' argument
++        says what edge of the output the surface will be anchored to.
++        After this request, the server will send a configure event with the
++        corresponding width/height that the client should use, and 0 for the
++        other dimension. E.g. if the edge is 'top', the width will be the
++        output's width, and the height will be 0.
++
++        The surface must have a "desktop" surface role, as supported by
++        libweston-desktop.
++
++        The compositor will take the panel's window geometry into account when
++        positioning other windows, so the panels are not covered.
++
++        XXX: What happens if e.g. both top and left are used at the same time?
++        Who gets to have the corner?
++
++        Only a single surface may be the panel for an output's edge. If a
++        surface already exists on an edge, a protocol error is raised.
++      </description>
++      <arg name="surface" type="object" interface="wl_surface"/>
++      <arg name="output" type="object" interface="wl_output"/>
++      <arg name="edge" type="uint" enum="edge"/>
++    </request>
++
++    <request name="activate_app">
++      <description summary="make client current window">
++        Ask the compositor to make a toplevel to become the current/focused
++        window for window management purposes.
++
++        See xdg_toplevel.set_app_id from the xdg-shell protocol for a
++        description of app_id.
++
++        If multiple toplevels have the same app_id, the result is unspecified.
++
++        XXX: Do we need feedback to say it didn't work? (e.g. client does
++        not exist)
++      </description>
++      <arg name="app_id" type="string"/>
++      <arg name="output" type="object" interface="wl_output"/>
++    </request>
++
++    <event name="bound_ok" since="2">
++     <description summary="event sent if binding was ok">
++        Informs the client that it was able to bind the agl_shell
++        interface succesfully. Clients are required to wait for this
++        event before continuing further.
++     </description>
++    </event>
++
++    <event name="bound_fail" since="2">
++      <description summary="event sent if binding was nok">
++        Informs the client that binding to the agl_shell interface was
++        unsuccesfull. Clients are required to wait for this event for
++        continuing further.
++      </description>
++    </event>
++
++    <request name="destroy" type="destructor" since="2">
++      <description summary="destroys the factory object">
++      </description>
++    </request>
++
++    <event name="app_state" since="3">
++      <description summary="event sent when an application suffered state modification">
++        Informs the client that an application has changed its state to another,
++        specified by the app_state enum. Client can use this event to track
++        current application state. For instance to know when the application has
++        started, or when terminated/stopped.
++      </description>
++      <arg name="app_id" type="string"/>
++      <arg name="state" type="uint" enum="app_state"/>
++    </event>
++
++
++  </interface>
++</protocol>
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
+index 6d44128e56458..93427c52e1284 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
++++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
+@@ -64,6 +64,8 @@
+ #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h"
+ #include "ui/platform_window/common/platform_window_defaults.h"
++#include "ui/ozone/platform/wayland/host/wayland_extensions.h"
++
+ #if defined(USE_LIBWAYLAND_STUBS)
+ #include <dlfcn.h>
+@@ -238,6 +240,10 @@ bool WaylandConnection::Initialize() {
+     return false;
+   }
++  if (!extensions_) {
++    extensions_ = CreateWaylandExtensions(this);
++  }
++
+   // Now that the connection with the display server has been properly
+   // estabilished, initialize the event source and input objects.
+   DCHECK(!event_source_);
+@@ -264,7 +270,7 @@ bool WaylandConnection::Initialize() {
+     LOG(ERROR) << "No wl_shm object";
+     return false;
+   }
+-  if (!shell_v6_ && !shell_) {
++  if (!shell_v6_ && !shell_ && !(extensions_ && extensions_->HasShellObject())) {
+     LOG(ERROR) << "No Wayland shell found";
+     return false;
+   }
+@@ -434,7 +440,9 @@ void WaylandConnection::Global(void* data,
+   auto* connection = static_cast<WaylandConnection*>(data);
+   auto factory_it = connection->global_object_factories_.find(interface);
+-  if (factory_it != connection->global_object_factories_.end()) {
++  if (connection->extensions_->Bind(registry, name, interface, version)) {
++    DVLOG(1) << "Successfully bound to " << interface;
++  } else if (factory_it != connection->global_object_factories_.end()) {
+     (*factory_it->second)(connection, registry, name, interface, version);
+   } else if (!connection->compositor_ &&
+              strcmp(interface, "wl_compositor") == 0) {
+diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
+index d33959ad4066f..dfd1d060c73f2 100644
+--- a/ui/ozone/platform/wayland/host/wayland_connection.h
++++ b/ui/ozone/platform/wayland/host/wayland_connection.h
+@@ -45,6 +45,7 @@ class WaylandBufferManagerHost;
+ class WaylandCursor;
+ class WaylandCursorBufferListener;
+ class WaylandEventSource;
++class WaylandExtensions;
+ class WaylandOutputManager;
+ class WaylandSeat;
+ class WaylandZAuraShell;
+@@ -185,6 +186,8 @@ class WaylandConnection {
+   WaylandZAuraShell* zaura_shell() const { return zaura_shell_.get(); }
++  WaylandExtensions* extensions() { return extensions_.get(); }
++
+   WaylandZcrColorManager* zcr_color_manager() const {
+     return zcr_color_manager_.get();
+   }
+@@ -424,6 +427,9 @@ class WaylandConnection {
+   std::unique_ptr<OverlayPrioritizer> overlay_prioritizer_;
+   std::unique_ptr<SurfaceAugmenter> surface_augmenter_;
++  std::unique_ptr<WaylandExtensions> extensions_;
++
++
+   // Clipboard-related objects. |clipboard_| must be declared after all
+   // DeviceManager instances it depends on, otherwise tests may crash with
+   // UAFs while attempting to access already destroyed manager pointers.
+diff --git a/ui/ozone/platform/wayland/host/wayland_extensions.h b/ui/ozone/platform/wayland/host/wayland_extensions.h
+new file mode 100644
+index 0000000000000..3bd2fd7a211ae
+--- /dev/null
++++ b/ui/ozone/platform/wayland/host/wayland_extensions.h
+@@ -0,0 +1,56 @@
++// Copyright 2019 LG Electronics, Inc.
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++// SPDX-License-Identifier: Apache-2.0
++
++#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
++#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
++
++#include <memory>
++
++#include "ui/ozone/platform/wayland/common/wayland_object.h"
++
++namespace ui {
++
++class ShellToplevelWrapper;
++class ShellPopupWrapper;
++class WaylandConnection;
++
++// Wayland extensions abstract interface to support extending of the Wayland
++// protocol. Inherit it to provide your own Wayland extensions implementation.
++class WaylandExtensions {
++ public:
++  WaylandExtensions() = default;
++  WaylandExtensions(const WaylandExtensions&) = delete;
++  WaylandExtensions& operator=(const WaylandExtensions&) = delete;
++  virtual ~WaylandExtensions() = default;
++
++  // Binds to the extensions interface(s). Can encapsulate binding of several
++  // interfaces, defined by |interface|.
++  virtual bool Bind(wl_registry* registry,
++                    uint32_t name,
++                    const char* interface,
++                    uint32_t version) = 0;
++
++  // Checks whether the extensions have bound shell object(s).
++  virtual bool HasShellObject() const = 0;
++};
++
++// Creates Wayland extensions.
++std::unique_ptr<WaylandExtensions> CreateWaylandExtensions(
++  WaylandConnection* connection);
++
++}  // namespace ui
++
++#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_
+-- 
+2.39.2
+