meta-agl-flutter: Add option agl-shell plugin patch to embedder
[AGL/meta-agl-devel.git] / meta-agl-flutter / recipes-graphics / toyota / files / 0001-Add-optional-agl_shell-plugin.patch
1 From 278945f12726692bc8b148ea1a59697a1c01405a Mon Sep 17 00:00:00 2001
2 From: Scott Murray <scott.murray@konsulko.com>
3 Date: Mon, 14 Nov 2022 17:58:12 -0500
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 Signed-off-by: Scott Murray <scott.murray@konsulko.com>
14 ---
15  cmake/plugins.cmake                         |  5 ++
16  shell/engine.cc                             |  6 ++
17  shell/engine.h                              | 10 +++
18  shell/platform_channel.cc                   |  6 ++
19  shell/static_plugins/agl_shell/agl_shell.cc | 77 +++++++++++++++++++++
20  shell/static_plugins/agl_shell/agl_shell.h  | 31 +++++++++
21  shell/wayland/display.cc                    |  8 +++
22  shell/wayland/display.h                     |  3 +
23  shell/wayland/window.h                      |  2 +
24  9 files changed, 148 insertions(+)
25  create mode 100644 shell/static_plugins/agl_shell/agl_shell.cc
26  create mode 100644 shell/static_plugins/agl_shell/agl_shell.h
27
28 diff --git a/cmake/plugins.cmake b/cmake/plugins.cmake
29 index 6bdc75b..a599f95 100644
30 --- a/cmake/plugins.cmake
31 +++ b/cmake/plugins.cmake
32 @@ -101,4 +101,9 @@ if (BUILD_PLUGIN_SECURE_STORAGE)
33      pkg_check_modules(PLUGIN_SECURE_STORAGE REQUIRED libsecret-1)
34  endif ()
35  
36 +option(BUILD_PLUGIN_AGL_SHELL "Includes AGL Shell Wayland Protocol Plugin" OFF)
37 +if (BUILD_PLUGIN_AGL_SHELL)
38 +    ENABLE_PLUGIN(agl_shell)
39 +endif ()
40 +
41  message(STATUS "Plugin Config .......... ${PLUGINS}")
42 diff --git a/shell/engine.cc b/shell/engine.cc
43 index ad0c83c..9ce346d 100644
44 --- a/shell/engine.cc
45 +++ b/shell/engine.cc
46 @@ -595,3 +595,9 @@ MAYBE_UNUSED TextInput* Engine::GetTextInput() const {
47  }
48  
49  #endif
50 +
51 +#if ENABLE_PLUGIN_AGL_SHELL
52 +std::shared_ptr<Display> Engine::GetDisplay() const {
53 +  return m_egl_window->GetDisplay();
54 +}
55 +#endif
56 diff --git a/shell/engine.h b/shell/engine.h
57 index 501ba4b..4193e7e 100644
58 --- a/shell/engine.h
59 +++ b/shell/engine.h
60 @@ -50,6 +50,12 @@ class TextInput;
61  
62  #endif
63  
64 +#if ENABLE_PLUGIN_AGL_SHELL
65 +
66 +class Display;
67 +
68 +#endif
69 +
70  class Engine {
71   public:
72    Engine(FlutterView* view,
73 @@ -146,6 +152,10 @@ class Engine {
74  
75  #endif
76  
77 +#if ENABLE_PLUGIN_AGL_SHELL
78 +  std::shared_ptr<Display> GetDisplay() const;
79 +#endif
80 +
81    Backend* GetBackend() {
82      return m_backend;
83    }
84 diff --git a/shell/platform_channel.cc b/shell/platform_channel.cc
85 index 10f4715..2c7ab8c 100644
86 --- a/shell/platform_channel.cc
87 +++ b/shell/platform_channel.cc
88 @@ -53,6 +53,9 @@
89  #ifdef ENABLE_PLUGIN_SECURE_STORAGE
90  #include "static_plugins/secure_storage/secure_storage.h"
91  #endif
92 +#ifdef ENABLE_PLUGIN_AGL_SHELL
93 +#include "static_plugins/agl_shell/agl_shell.h"
94 +#endif
95  
96  PlatformChannel* PlatformChannel::singleton = nullptr;
97  
98 @@ -101,4 +104,7 @@ PlatformChannel::PlatformChannel() {
99    RegisterCallback(SecureStorage::kChannelName,
100                     &SecureStorage::OnPlatformMessage);
101  #endif
102 +#ifdef ENABLE_PLUGIN_AGL_SHELL
103 +  RegisterCallback(AglShell::kChannelName, &AglShell::OnPlatformMessage);
104 +#endif
105  }
106 diff --git a/shell/static_plugins/agl_shell/agl_shell.cc b/shell/static_plugins/agl_shell/agl_shell.cc
107 new file mode 100644
108 index 0000000..81627b6
109 --- /dev/null
110 +++ b/shell/static_plugins/agl_shell/agl_shell.cc
111 @@ -0,0 +1,77 @@
112 +// Copyright 2020 Toyota Connected North America
113 +// Copyright 2022 Konsulko Group
114 +//
115 +// Licensed under the Apache License, Version 2.0 (the "License");
116 +// you may not use this file except in compliance with the License.
117 +// You may obtain a copy of the License at
118 +//
119 +//      http://www.apache.org/licenses/LICENSE-2.0
120 +//
121 +// Unless required by applicable law or agreed to in writing, software
122 +// distributed under the License is distributed on an "AS IS" BASIS,
123 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124 +// See the License for the specific language governing permissions and
125 +// limitations under the License.
126 +
127 +#include "agl_shell.h"
128 +
129 +#include <flutter/fml/logging.h>
130 +#include <flutter/standard_method_codec.h>
131 +
132 +#include "engine.h"
133 +#include "wayland/display.h"
134 +
135 +#include <iostream>
136 +
137 +void AglShell::OnPlatformMessage(const FlutterPlatformMessage* message,
138 +                                    void* userdata) {
139 +  std::unique_ptr<std::vector<uint8_t>> result;
140 +  auto engine = reinterpret_cast<Engine*>(userdata);
141 +  auto& codec = flutter::StandardMethodCodec::GetInstance();
142 +  auto obj = codec.DecodeMethodCall(message->message, message->message_size);
143 +
144 +  auto method = obj->method_name();
145 +  if (method == kMethodActivateApp) {
146 +    if (obj->arguments()->IsNull()) {
147 +      result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
148 +      goto done;
149 +    }
150 +
151 +    auto args = std::get_if<flutter::EncodableMap>(obj->arguments());
152 +    if (!args) {
153 +      result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
154 +      goto done;
155 +    }
156 +
157 +    std::string app_id;
158 +    auto it = args->find(flutter::EncodableValue("app_id"));
159 +    if (it != args->end()) {
160 +      app_id = std::get<std::string>(it->second);
161 +    }
162 +
163 +    int32_t index = 0;
164 +    it = args->find(flutter::EncodableValue("index"));
165 +    if (it != args->end()) {
166 +      index = std::get<int32_t>(it->second);
167 +    }
168 +
169 +    if (app_id.empty() || index < 0) {
170 +      result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
171 +      goto done;
172 +    }
173 +
174 +    auto display = engine->GetDisplay();
175 +    if (display) {
176 +      display->AglShellDoActivate(app_id, index);
177 +    }
178 +    auto val = flutter::EncodableValue(true);
179 +    result = codec.EncodeSuccessEnvelope(&val);
180 +  } else {
181 +    FML_DLOG(INFO) << "AglShell: " << method << " is unhandled";
182 +    result = codec.EncodeErrorEnvelope("unhandled_method", "Unhandled Method");
183 +  }
184 +
185 + done:
186 +  engine->SendPlatformMessageResponse(message->response_handle, result->data(),
187 +                                      result->size());
188 +}
189 diff --git a/shell/static_plugins/agl_shell/agl_shell.h b/shell/static_plugins/agl_shell/agl_shell.h
190 new file mode 100644
191 index 0000000..747eb36
192 --- /dev/null
193 +++ b/shell/static_plugins/agl_shell/agl_shell.h
194 @@ -0,0 +1,31 @@
195 +/*
196 + * Copyright 2020 Toyota Connected North America
197 + * Copyright 2022 Konsulko Group
198 + *
199 + * Licensed under the Apache License, Version 2.0 (the "License");
200 + * you may not use this file except in compliance with the License.
201 + * You may obtain a copy of the License at
202 + *
203 + *      http://www.apache.org/licenses/LICENSE-2.0
204 + *
205 + * Unless required by applicable law or agreed to in writing, software
206 + * distributed under the License is distributed on an "AS IS" BASIS,
207 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
208 + * See the License for the specific language governing permissions and
209 + * limitations under the License.
210 + */
211 +
212 +#pragma once
213 +
214 +#include <flutter_embedder.h>
215 +
216 +class AglShell {
217 + public:
218 +  static constexpr char kChannelName[] = "flutter/agl_shell";
219 +
220 +  static void OnPlatformMessage(const FlutterPlatformMessage* message,
221 +                                void* userdata);
222 +
223 + private:
224 +  static constexpr char kMethodActivateApp[] = "activate_app";
225 +};
226 diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
227 index 5d78471..48262c3 100644
228 --- a/shell/wayland/display.cc
229 +++ b/shell/wayland/display.cc
230 @@ -697,6 +697,14 @@ void Display::AglShellDoPanel(struct wl_surface* surface,
231    }
232  }
233  
234 +void Display::AglShellDoActivate(const std::string& app_id,
235 +                                 size_t index) {
236 +  if (m_agl_shell) {
237 +    agl_shell_activate_app(m_agl_shell, app_id.c_str(),
238 +                           m_all_outputs[index]->output);
239 +  }
240 +}
241 +
242  void Display::AglShellDoReady() {
243    if (m_agl_shell) {
244      agl_shell_ready(m_agl_shell);
245 diff --git a/shell/wayland/display.h b/shell/wayland/display.h
246 index bf05b27..c628c8c 100644
247 --- a/shell/wayland/display.h
248 +++ b/shell/wayland/display.h
249 @@ -82,6 +82,9 @@ class Display {
250                         enum agl_shell_edge mode,
251                         size_t index);
252  
253 +  void AglShellDoActivate(const std::string& app_id,
254 +                          size_t index);
255 +
256    void AglShellDoReady();
257  
258    void SetEngine(wl_surface* surface, Engine* engine);
259 diff --git a/shell/wayland/window.h b/shell/wayland/window.h
260 index 4b5c726..b4d0be3 100644
261 --- a/shell/wayland/window.h
262 +++ b/shell/wayland/window.h
263 @@ -81,6 +81,8 @@ class WaylandWindow {
264    uint32_t m_fps_counter;
265    static window_type get_window_type(const std::string& type);
266  
267 +  std::shared_ptr<Display> GetDisplay() { return m_display; }
268 +
269   private:
270    struct shm_buffer {
271      struct wl_buffer* buffer;
272 -- 
273 2.38.1
274