Flutter bbclass refactor
[AGL/meta-agl-devel.git] / meta-agl-flutter / recipes-graphics / toyota / files / 0001-Add-optional-agl_shell-plugin.patch
1 From 164756be1d20b555f43e2eb3160da3efa7d38865 Mon Sep 17 00:00:00 2001
2 From: Scott Murray <scott.murray@konsulko.com>
3 Date: Thu, 1 Jun 2023 14:34:03 -0400
4 Subject: [PATCH] Add optional agl_shell plugin
5
6 Add an optional agl_shell static plugin to expose the activate_app
7 call from the agl-shell Wayland protocol that is used when running
8 against the AGL compositor.  This provides a way for a homescreen
9 application to activate other application surfaces to switch between
10 multiple applications as is needed for the AGL demo.
11
12 Upstream-Status: Pending
13
14 Signed-off-by: Scott Murray <scott.murray@konsulko.com>
15 [Updated to work with upstream OSS 0223 release]
16 Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
17 ---
18  cmake/plugins.cmake                         |  5 ++
19  shell/engine.cc                             |  6 ++
20  shell/engine.h                              | 10 +++
21  shell/platform_channel.cc                   |  6 ++
22  shell/static_plugins/agl_shell/agl_shell.cc | 77 +++++++++++++++++++++
23  shell/static_plugins/agl_shell/agl_shell.h  | 31 +++++++++
24  shell/wayland/display.cc                    |  7 ++
25  shell/wayland/display.h                     |  8 +++
26  shell/wayland/window.h                      |  2 +
27  9 files changed, 152 insertions(+)
28  create mode 100644 shell/static_plugins/agl_shell/agl_shell.cc
29  create mode 100644 shell/static_plugins/agl_shell/agl_shell.h
30
31 diff --git a/cmake/plugins.cmake b/cmake/plugins.cmake
32 index b720dca..20a55d7 100644
33 --- a/cmake/plugins.cmake
34 +++ b/cmake/plugins.cmake
35 @@ -123,4 +123,9 @@ if (BUILD_PLUGIN_SECURE_STORAGE)
36  endif ()
37  
38  
39 +option(BUILD_PLUGIN_AGL_SHELL "Includes AGL Shell Wayland Protocol Plugin" OFF)
40 +if (BUILD_PLUGIN_AGL_SHELL)
41 +    ENABLE_PLUGIN(agl_shell)
42 +endif ()
43 +
44  message(STATUS "Plugin Config .......... ${PLUGINS}")
45 diff --git a/shell/engine.cc b/shell/engine.cc
46 index d20b6ba..a0e38e9 100644
47 --- a/shell/engine.cc
48 +++ b/shell/engine.cc
49 @@ -614,3 +614,9 @@ MAYBE_UNUSED TextInput* Engine::GetTextInput() const {
50    return m_key_event;
51  }
52  #endif
53 +
54 +#if ENABLE_PLUGIN_AGL_SHELL
55 +std::shared_ptr<Display> Engine::GetDisplay() const {
56 +  return m_egl_window->GetDisplay();
57 +}
58 +#endif
59 diff --git a/shell/engine.h b/shell/engine.h
60 index 94808dc..3a06f51 100644
61 --- a/shell/engine.h
62 +++ b/shell/engine.h
63 @@ -60,6 +60,12 @@ class KeyEvent;
64  
65  #endif
66  
67 +#if ENABLE_PLUGIN_AGL_SHELL
68 +
69 +class Display;
70 +
71 +#endif
72 +
73  class Engine {
74   public:
75    /**
76 @@ -445,6 +451,10 @@ class Engine {
77    MAYBE_UNUSED NODISCARD KeyEvent* GetKeyEvent() const;
78  #endif
79  
80 +#if ENABLE_PLUGIN_AGL_SHELL
81 +  std::shared_ptr<Display> GetDisplay() const;
82 +#endif
83 +
84    /**
85     * @brief Get backend of view
86     * @return Backend*
87 diff --git a/shell/platform_channel.cc b/shell/platform_channel.cc
88 index b72156a..81d7cb5 100644
89 --- a/shell/platform_channel.cc
90 +++ b/shell/platform_channel.cc
91 @@ -62,6 +62,9 @@
92  #ifdef ENABLE_PLUGIN_SECURE_STORAGE
93  #include "static_plugins/secure_storage/secure_storage.h"
94  #endif
95 +#ifdef ENABLE_PLUGIN_AGL_SHELL
96 +#include "static_plugins/agl_shell/agl_shell.h"
97 +#endif
98  
99  PlatformChannel* PlatformChannel::singleton = nullptr;
100  
101 @@ -122,4 +125,7 @@ PlatformChannel::PlatformChannel() {
102    RegisterCallback(SecureStorage::kChannelName,
103                     &SecureStorage::OnPlatformMessage);
104  #endif
105 +#ifdef ENABLE_PLUGIN_AGL_SHELL
106 +  RegisterCallback(AglShell::kChannelName, &AglShell::OnPlatformMessage);
107 +#endif
108  }
109 diff --git a/shell/static_plugins/agl_shell/agl_shell.cc b/shell/static_plugins/agl_shell/agl_shell.cc
110 new file mode 100644
111 index 0000000..e6160a5
112 --- /dev/null
113 +++ b/shell/static_plugins/agl_shell/agl_shell.cc
114 @@ -0,0 +1,77 @@
115 +// Copyright 2020 Toyota Connected North America
116 +// Copyright 2022 Konsulko Group
117 +//
118 +// Licensed under the Apache License, Version 2.0 (the "License");
119 +// you may not use this file except in compliance with the License.
120 +// You may obtain a copy of the License at
121 +//
122 +//      http://www.apache.org/licenses/LICENSE-2.0
123 +//
124 +// Unless required by applicable law or agreed to in writing, software
125 +// distributed under the License is distributed on an "AS IS" BASIS,
126 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127 +// See the License for the specific language governing permissions and
128 +// limitations under the License.
129 +
130 +#include "agl_shell.h"
131 +
132 +#include <flutter/fml/logging.h>
133 +#include <flutter/standard_method_codec.h>
134 +
135 +#include "engine.h"
136 +#include "wayland/display.h"
137 +
138 +#include <iostream>
139 +
140 +void AglShell::OnPlatformMessage(const FlutterPlatformMessage* message,
141 +                                 void* userdata) {
142 +  std::unique_ptr<std::vector<uint8_t>> result;
143 +  auto engine = reinterpret_cast<Engine*>(userdata);
144 +  auto& codec = flutter::StandardMethodCodec::GetInstance();
145 +  auto obj = codec.DecodeMethodCall(message->message, message->message_size);
146 +
147 +  auto method = obj->method_name();
148 +  if (method == kMethodActivateApp) {
149 +    if (obj->arguments()->IsNull()) {
150 +      result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
151 +      goto done;
152 +    }
153 +
154 +    auto args = std::get_if<flutter::EncodableMap>(obj->arguments());
155 +    if (!args) {
156 +      result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
157 +      goto done;
158 +    }
159 +
160 +    std::string app_id;
161 +    auto it = args->find(flutter::EncodableValue("app_id"));
162 +    if (it != args->end()) {
163 +      app_id = std::get<std::string>(it->second);
164 +    }
165 +
166 +    int32_t index = 0;
167 +    it = args->find(flutter::EncodableValue("index"));
168 +    if (it != args->end()) {
169 +      index = std::get<int32_t>(it->second);
170 +    }
171 +
172 +    if (app_id.empty() || index < 0) {
173 +      result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
174 +      goto done;
175 +    }
176 +
177 +    auto display = engine->GetDisplay();
178 +    if (display) {
179 +      display->AglShellDoActivate(app_id, index);
180 +    }
181 +    auto val = flutter::EncodableValue(true);
182 +    result = codec.EncodeSuccessEnvelope(&val);
183 +  } else {
184 +    FML_DLOG(INFO) << "AglShell: " << method << " is unhandled";
185 +    result = codec.EncodeErrorEnvelope("unhandled_method", "Unhandled Method");
186 +  }
187 +
188 +done:
189 +  engine->SendPlatformMessageResponse(message->response_handle, result->data(),
190 +                                      result->size());
191 +}
192 diff --git a/shell/static_plugins/agl_shell/agl_shell.h b/shell/static_plugins/agl_shell/agl_shell.h
193 new file mode 100644
194 index 0000000..698e44c
195 --- /dev/null
196 +++ b/shell/static_plugins/agl_shell/agl_shell.h
197 @@ -0,0 +1,31 @@
198 +/*
199 + * Copyright 2020 Toyota Connected North America
200 + * Copyright 2022 Konsulko Group
201 + *
202 + * Licensed under the Apache License, Version 2.0 (the "License");
203 + * you may not use this file except in compliance with the License.
204 + * You may obtain a copy of the License at
205 + *
206 + *      http://www.apache.org/licenses/LICENSE-2.0
207 + *
208 + * Unless required by applicable law or agreed to in writing, software
209 + * distributed under the License is distributed on an "AS IS" BASIS,
210 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
211 + * See the License for the specific language governing permissions and
212 + * limitations under the License.
213 + */
214 +
215 +#pragma once
216 +
217 +#include <shell/platform/embedder/embedder.h>
218 +
219 +class AglShell {
220 + public:
221 +  static constexpr char kChannelName[] = "flutter/agl_shell";
222 +
223 +  static void OnPlatformMessage(const FlutterPlatformMessage* message,
224 +                                void* userdata);
225 +
226 + private:
227 +  static constexpr char kMethodActivateApp[] = "activate_app";
228 +};
229 diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
230 index 9351fb9..583d8ba 100644
231 --- a/shell/wayland/display.cc
232 +++ b/shell/wayland/display.cc
233 @@ -845,6 +845,13 @@ void Display::AglShellDoReady() const {
234    }
235  }
236  
237 +void Display::AglShellDoActivate(const std::string& app_id, size_t index) {
238 +  if (m_agl.shell) {
239 +    agl_shell_activate_app(m_agl.shell, app_id.c_str(),
240 +                           m_all_outputs[index]->output);
241 +  }
242 +}
243 +
244  void Display::SetEngine(wl_surface* surface, Engine* engine) {
245    m_active_engine = engine;
246    m_active_surface = surface;
247 diff --git a/shell/wayland/display.h b/shell/wayland/display.h
248 index daeefea..3efdc9c 100644
249 --- a/shell/wayland/display.h
250 +++ b/shell/wayland/display.h
251 @@ -150,6 +150,14 @@ class Display {
252     */
253    void AglShellDoReady() const;
254  
255 +  /**
256 +   * @brief AglShellDoActivate:
257 +   * @return void
258 +   * @relation
259 +   * wayland, agl-shell
260 +   */
261 +  void AglShellDoActivate(const std::string& app_id, size_t index);
262 +
263    /**
264     * @brief Set Engine
265     * @param[in] surface Image
266 diff --git a/shell/wayland/window.h b/shell/wayland/window.h
267 index c0f2abc..da9cf45 100644
268 --- a/shell/wayland/window.h
269 +++ b/shell/wayland/window.h
270 @@ -127,6 +127,8 @@ class WaylandWindow {
271      return std::pair<int32_t, int32_t>{m_geometry.width, m_geometry.height};
272    }
273  
274 +  std::shared_ptr<Display> GetDisplay() { return m_display; }
275 +
276   private:
277    size_t m_index;
278    std::shared_ptr<Display> m_display;
279 -- 
280 2.40.1
281