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
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.
12 Upstream-Status: Pending
13 Signed-off-by: Scott Murray <scott.murray@konsulko.com>
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
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)
36 +option(BUILD_PLUGIN_AGL_SHELL "Includes AGL Shell Wayland Protocol Plugin" OFF)
37 +if (BUILD_PLUGIN_AGL_SHELL)
38 + ENABLE_PLUGIN(agl_shell)
41 message(STATUS "Plugin Config .......... ${PLUGINS}")
42 diff --git a/shell/engine.cc b/shell/engine.cc
43 index ad0c83c..9ce346d 100644
46 @@ -595,3 +595,9 @@ MAYBE_UNUSED TextInput* Engine::GetTextInput() const {
51 +#if ENABLE_PLUGIN_AGL_SHELL
52 +std::shared_ptr<Display> Engine::GetDisplay() const {
53 + return m_egl_window->GetDisplay();
56 diff --git a/shell/engine.h b/shell/engine.h
57 index 501ba4b..4193e7e 100644
60 @@ -50,6 +50,12 @@ class TextInput;
64 +#if ENABLE_PLUGIN_AGL_SHELL
72 Engine(FlutterView* view,
73 @@ -146,6 +152,10 @@ class Engine {
77 +#if ENABLE_PLUGIN_AGL_SHELL
78 + std::shared_ptr<Display> GetDisplay() const;
81 Backend* GetBackend() {
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
89 #ifdef ENABLE_PLUGIN_SECURE_STORAGE
90 #include "static_plugins/secure_storage/secure_storage.h"
92 +#ifdef ENABLE_PLUGIN_AGL_SHELL
93 +#include "static_plugins/agl_shell/agl_shell.h"
96 PlatformChannel* PlatformChannel::singleton = nullptr;
98 @@ -101,4 +104,7 @@ PlatformChannel::PlatformChannel() {
99 RegisterCallback(SecureStorage::kChannelName,
100 &SecureStorage::OnPlatformMessage);
102 +#ifdef ENABLE_PLUGIN_AGL_SHELL
103 + RegisterCallback(AglShell::kChannelName, &AglShell::OnPlatformMessage);
106 diff --git a/shell/static_plugins/agl_shell/agl_shell.cc b/shell/static_plugins/agl_shell/agl_shell.cc
108 index 0000000..81627b6
110 +++ b/shell/static_plugins/agl_shell/agl_shell.cc
112 +// Copyright 2020 Toyota Connected North America
113 +// Copyright 2022 Konsulko Group
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
119 +// http://www.apache.org/licenses/LICENSE-2.0
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.
127 +#include "agl_shell.h"
129 +#include <flutter/fml/logging.h>
130 +#include <flutter/standard_method_codec.h>
133 +#include "wayland/display.h"
137 +void AglShell::OnPlatformMessage(const FlutterPlatformMessage* message,
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);
144 + auto method = obj->method_name();
145 + if (method == kMethodActivateApp) {
146 + if (obj->arguments()->IsNull()) {
147 + result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
151 + auto args = std::get_if<flutter::EncodableMap>(obj->arguments());
153 + result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
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);
164 + it = args->find(flutter::EncodableValue("index"));
165 + if (it != args->end()) {
166 + index = std::get<int32_t>(it->second);
169 + if (app_id.empty() || index < 0) {
170 + result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments");
174 + auto display = engine->GetDisplay();
176 + display->AglShellDoActivate(app_id, index);
178 + auto val = flutter::EncodableValue(true);
179 + result = codec.EncodeSuccessEnvelope(&val);
181 + FML_DLOG(INFO) << "AglShell: " << method << " is unhandled";
182 + result = codec.EncodeErrorEnvelope("unhandled_method", "Unhandled Method");
186 + engine->SendPlatformMessageResponse(message->response_handle, result->data(),
189 diff --git a/shell/static_plugins/agl_shell/agl_shell.h b/shell/static_plugins/agl_shell/agl_shell.h
191 index 0000000..747eb36
193 +++ b/shell/static_plugins/agl_shell/agl_shell.h
196 + * Copyright 2020 Toyota Connected North America
197 + * Copyright 2022 Konsulko Group
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
203 + * http://www.apache.org/licenses/LICENSE-2.0
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.
214 +#include <flutter_embedder.h>
218 + static constexpr char kChannelName[] = "flutter/agl_shell";
220 + static void OnPlatformMessage(const FlutterPlatformMessage* message,
224 + static constexpr char kMethodActivateApp[] = "activate_app";
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,
234 +void Display::AglShellDoActivate(const std::string& app_id,
237 + agl_shell_activate_app(m_agl_shell, app_id.c_str(),
238 + m_all_outputs[index]->output);
242 void Display::AglShellDoReady() {
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,
253 + void AglShellDoActivate(const std::string& app_id,
256 void AglShellDoReady();
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);
267 + std::shared_ptr<Display> GetDisplay() { return m_display; }
271 struct wl_buffer* buffer;