diff options
-rw-r--r-- | meta-agl-flutter/recipes-graphics/toyota/files/0001-Add-optional-agl_shell-plugin.patch | 274 | ||||
-rw-r--r-- | meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc | 9 |
2 files changed, 283 insertions, 0 deletions
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0001-Add-optional-agl_shell-plugin.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0001-Add-optional-agl_shell-plugin.patch new file mode 100644 index 00000000..b5ab653e --- /dev/null +++ b/meta-agl-flutter/recipes-graphics/toyota/files/0001-Add-optional-agl_shell-plugin.patch @@ -0,0 +1,274 @@ +From 278945f12726692bc8b148ea1a59697a1c01405a Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Mon, 14 Nov 2022 17:58:12 -0500 +Subject: [PATCH] Add optional agl_shell plugin + +Add an optional agl_shell static plugin to expose the activate_app +call from the agl-shell Wayland protocol that is used when running +against the AGL compositor. This provides a way for a homescreen +application to activate other application surfaces to switch between +multiple applications as is needed for the AGL demo. + +Upstream-Status: Pending +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + cmake/plugins.cmake | 5 ++ + shell/engine.cc | 6 ++ + shell/engine.h | 10 +++ + shell/platform_channel.cc | 6 ++ + shell/static_plugins/agl_shell/agl_shell.cc | 77 +++++++++++++++++++++ + shell/static_plugins/agl_shell/agl_shell.h | 31 +++++++++ + shell/wayland/display.cc | 8 +++ + shell/wayland/display.h | 3 + + shell/wayland/window.h | 2 + + 9 files changed, 148 insertions(+) + create mode 100644 shell/static_plugins/agl_shell/agl_shell.cc + create mode 100644 shell/static_plugins/agl_shell/agl_shell.h + +diff --git a/cmake/plugins.cmake b/cmake/plugins.cmake +index 6bdc75b..a599f95 100644 +--- a/cmake/plugins.cmake ++++ b/cmake/plugins.cmake +@@ -101,4 +101,9 @@ if (BUILD_PLUGIN_SECURE_STORAGE) + pkg_check_modules(PLUGIN_SECURE_STORAGE REQUIRED libsecret-1) + endif () + ++option(BUILD_PLUGIN_AGL_SHELL "Includes AGL Shell Wayland Protocol Plugin" OFF) ++if (BUILD_PLUGIN_AGL_SHELL) ++ ENABLE_PLUGIN(agl_shell) ++endif () ++ + message(STATUS "Plugin Config .......... ${PLUGINS}") +diff --git a/shell/engine.cc b/shell/engine.cc +index ad0c83c..9ce346d 100644 +--- a/shell/engine.cc ++++ b/shell/engine.cc +@@ -595,3 +595,9 @@ MAYBE_UNUSED TextInput* Engine::GetTextInput() const { + } + + #endif ++ ++#if ENABLE_PLUGIN_AGL_SHELL ++std::shared_ptr<Display> Engine::GetDisplay() const { ++ return m_egl_window->GetDisplay(); ++} ++#endif +diff --git a/shell/engine.h b/shell/engine.h +index 501ba4b..4193e7e 100644 +--- a/shell/engine.h ++++ b/shell/engine.h +@@ -50,6 +50,12 @@ class TextInput; + + #endif + ++#if ENABLE_PLUGIN_AGL_SHELL ++ ++class Display; ++ ++#endif ++ + class Engine { + public: + Engine(FlutterView* view, +@@ -146,6 +152,10 @@ class Engine { + + #endif + ++#if ENABLE_PLUGIN_AGL_SHELL ++ std::shared_ptr<Display> GetDisplay() const; ++#endif ++ + Backend* GetBackend() { + return m_backend; + } +diff --git a/shell/platform_channel.cc b/shell/platform_channel.cc +index 10f4715..2c7ab8c 100644 +--- a/shell/platform_channel.cc ++++ b/shell/platform_channel.cc +@@ -53,6 +53,9 @@ + #ifdef ENABLE_PLUGIN_SECURE_STORAGE + #include "static_plugins/secure_storage/secure_storage.h" + #endif ++#ifdef ENABLE_PLUGIN_AGL_SHELL ++#include "static_plugins/agl_shell/agl_shell.h" ++#endif + + PlatformChannel* PlatformChannel::singleton = nullptr; + +@@ -101,4 +104,7 @@ PlatformChannel::PlatformChannel() { + RegisterCallback(SecureStorage::kChannelName, + &SecureStorage::OnPlatformMessage); + #endif ++#ifdef ENABLE_PLUGIN_AGL_SHELL ++ RegisterCallback(AglShell::kChannelName, &AglShell::OnPlatformMessage); ++#endif + } +diff --git a/shell/static_plugins/agl_shell/agl_shell.cc b/shell/static_plugins/agl_shell/agl_shell.cc +new file mode 100644 +index 0000000..81627b6 +--- /dev/null ++++ b/shell/static_plugins/agl_shell/agl_shell.cc +@@ -0,0 +1,77 @@ ++// Copyright 2020 Toyota Connected North America ++// Copyright 2022 Konsulko Group ++// ++// 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. ++ ++#include "agl_shell.h" ++ ++#include <flutter/fml/logging.h> ++#include <flutter/standard_method_codec.h> ++ ++#include "engine.h" ++#include "wayland/display.h" ++ ++#include <iostream> ++ ++void AglShell::OnPlatformMessage(const FlutterPlatformMessage* message, ++ void* userdata) { ++ std::unique_ptr<std::vector<uint8_t>> result; ++ auto engine = reinterpret_cast<Engine*>(userdata); ++ auto& codec = flutter::StandardMethodCodec::GetInstance(); ++ auto obj = codec.DecodeMethodCall(message->message, message->message_size); ++ ++ auto method = obj->method_name(); ++ if (method == kMethodActivateApp) { ++ if (obj->arguments()->IsNull()) { ++ result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments"); ++ goto done; ++ } ++ ++ auto args = std::get_if<flutter::EncodableMap>(obj->arguments()); ++ if (!args) { ++ result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments"); ++ goto done; ++ } ++ ++ std::string app_id; ++ auto it = args->find(flutter::EncodableValue("app_id")); ++ if (it != args->end()) { ++ app_id = std::get<std::string>(it->second); ++ } ++ ++ int32_t index = 0; ++ it = args->find(flutter::EncodableValue("index")); ++ if (it != args->end()) { ++ index = std::get<int32_t>(it->second); ++ } ++ ++ if (app_id.empty() || index < 0) { ++ result = codec.EncodeErrorEnvelope("argument_error", "Invalid Arguments"); ++ goto done; ++ } ++ ++ auto display = engine->GetDisplay(); ++ if (display) { ++ display->AglShellDoActivate(app_id, index); ++ } ++ auto val = flutter::EncodableValue(true); ++ result = codec.EncodeSuccessEnvelope(&val); ++ } else { ++ FML_DLOG(INFO) << "AglShell: " << method << " is unhandled"; ++ result = codec.EncodeErrorEnvelope("unhandled_method", "Unhandled Method"); ++ } ++ ++ done: ++ engine->SendPlatformMessageResponse(message->response_handle, result->data(), ++ result->size()); ++} +diff --git a/shell/static_plugins/agl_shell/agl_shell.h b/shell/static_plugins/agl_shell/agl_shell.h +new file mode 100644 +index 0000000..747eb36 +--- /dev/null ++++ b/shell/static_plugins/agl_shell/agl_shell.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright 2020 Toyota Connected North America ++ * Copyright 2022 Konsulko Group ++ * ++ * 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. ++ */ ++ ++#pragma once ++ ++#include <flutter_embedder.h> ++ ++class AglShell { ++ public: ++ static constexpr char kChannelName[] = "flutter/agl_shell"; ++ ++ static void OnPlatformMessage(const FlutterPlatformMessage* message, ++ void* userdata); ++ ++ private: ++ static constexpr char kMethodActivateApp[] = "activate_app"; ++}; +diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc +index 5d78471..48262c3 100644 +--- a/shell/wayland/display.cc ++++ b/shell/wayland/display.cc +@@ -697,6 +697,14 @@ void Display::AglShellDoPanel(struct wl_surface* surface, + } + } + ++void Display::AglShellDoActivate(const std::string& app_id, ++ size_t index) { ++ if (m_agl_shell) { ++ agl_shell_activate_app(m_agl_shell, app_id.c_str(), ++ m_all_outputs[index]->output); ++ } ++} ++ + void Display::AglShellDoReady() { + if (m_agl_shell) { + agl_shell_ready(m_agl_shell); +diff --git a/shell/wayland/display.h b/shell/wayland/display.h +index bf05b27..c628c8c 100644 +--- a/shell/wayland/display.h ++++ b/shell/wayland/display.h +@@ -82,6 +82,9 @@ class Display { + enum agl_shell_edge mode, + size_t index); + ++ void AglShellDoActivate(const std::string& app_id, ++ size_t index); ++ + void AglShellDoReady(); + + void SetEngine(wl_surface* surface, Engine* engine); +diff --git a/shell/wayland/window.h b/shell/wayland/window.h +index 4b5c726..b4d0be3 100644 +--- a/shell/wayland/window.h ++++ b/shell/wayland/window.h +@@ -81,6 +81,8 @@ class WaylandWindow { + uint32_t m_fps_counter; + static window_type get_window_type(const std::string& type); + ++ std::shared_ptr<Display> GetDisplay() { return m_display; } ++ + private: + struct shm_buffer { + struct wl_buffer* buffer; +-- +2.38.1 + diff --git a/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc b/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc index 1fb1a3b4..41035f58 100644 --- a/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc +++ b/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc @@ -1,4 +1,13 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI += "file://0001-Add-optional-agl_shell-plugin.patch" # For now disable gstreamer to avoid needing to enable "commercial" # licenses for the stated ffmpeg dependency. PACKAGECONFIG:remove = "gstreamer" + +# Enable agl-shell wayland protocol plugin +PACKAGECONFIG[agl-shell] = "-DBUILD_PLUGIN_AGL_SHELL=ON, -DBUILD_PLUGIN_AGL_SHELL=OFF" +# NOTE: Cannot use += here due to ??= use in the recipe +PACKAGECONFIG:append = " agl-shell" + |