aboutsummaryrefslogtreecommitdiffstats
path: root/meta-agl-flutter
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2024-06-25 15:39:12 -0400
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2024-06-26 10:42:40 +0000
commitdbb228360317872e7c6fcbd96faaf404535130c3 (patch)
tree361355a3459eb764df0b1a28490615da442fe05d /meta-agl-flutter
parent9c99d6680bc5bd3e14085f2b58301ef52144a937 (diff)
Add meta-agl-flutter
Add meta-agl-flutter layer as it is being moved from meta-agl-devel. The files are copies of the state in meta-agl-devel as of commit 97310e35, with only a minor change to the feature template to adjust the location of the layer for bblayers.conf. Bug-AGL: SPEC-5184 Change-Id: I9a14e4ab3a1b1726b0ccc1dbc112d76864dd106c Signed-off-by: Scott Murray <scott.murray@konsulko.com> Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/30016 Tested-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org> Reviewed-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
Diffstat (limited to 'meta-agl-flutter')
-rw-r--r--meta-agl-flutter/README.md252
-rw-r--r--meta-agl-flutter/conf/include/agl-flutter.inc3
-rw-r--r--meta-agl-flutter/conf/layer.conf19
-rw-r--r--meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery/flutter-gallery.service13
-rw-r--r--meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_%.bbappend1
-rw-r--r--meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_aglflutter.inc13
-rw-r--r--meta-agl-flutter/recipes-config/agl-flutter-env/agl-flutter-env_1.0.bb15
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch26
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch190
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch117
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch28
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch477
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch33
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/flutter-auto_%.bbappend1
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc9
-rw-r--r--meta-agl-flutter/recipes-platform/images/agl-image-flutter-debug.bb29
-rw-r--r--meta-agl-flutter/recipes-platform/images/agl-image-flutter.bb16
-rw-r--r--meta-agl-flutter/tools/.gitignore151
-rw-r--r--meta-agl-flutter/tools/configs/_globals.json5
-rw-r--r--meta-agl-flutter/tools/configs/_repos.json11
-rw-r--r--meta-agl-flutter/tools/configs/agl-qemu-master.json114
-rw-r--r--meta-agl-flutter/tools/configs/agl-qemu-octopus.json114
-rw-r--r--meta-agl-flutter/tools/configs/desktop-auto.json92
l---------meta-agl-flutter/tools/flutter_workspace.py1
24 files changed, 1730 insertions, 0 deletions
diff --git a/meta-agl-flutter/README.md b/meta-agl-flutter/README.md
new file mode 100644
index 000000000..24929ccd0
--- /dev/null
+++ b/meta-agl-flutter/README.md
@@ -0,0 +1,252 @@
+# meta-agl-flutter
+
+## Steps to build `agl-ivi-demo-platform-flutter` image
+
+```
+ export AGL_TOP=$HOME/workspace_agl
+ mkdir -p $AGL_TOP && cd $AGL_TOP
+ repo init -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo -b master
+ repo sync -j $(nproc)
+ source meta-agl/scripts/aglsetup.sh -m qemux86-64 agl-demo
+ bitbake agl-ivi-demo-platform-flutter
+```
+
+This builds AGL demo image that includes Flutter runtime={debug,profile,release}.
+
+
+## Steps to build a minimal flutter image
+
+```
+ export AGL_TOP=$HOME/workspace_agl
+ mkdir -p $AGL_TOP && cd $AGL_TOP
+ repo init -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo -b master
+ repo sync -j `grep -c ^processor /proc/cpuinfo`
+ source meta-agl/scripts/aglsetup.sh -m qemux86-64 agl-devel agl-flutter
+ bitbake agl-image-flutter
+```
+ * includes Flutter engine runtime={debug,release,profile}
+ * includes Flutter Engine SDK
+ * includes SSH server
+ * live debugging/profiling with target via host
+
+## Useful Notes
+
+flutter-auto runs as user `agl-driver`. After logging in as root you can delete password for `agl-driver`:
+```
+# passwd -d agl-driver
+```
+
+To track flutter-auto output:
+```
+# journalctl -ex -u flutter-homescreen -f
+```
+
+To view available Flutter programs in OS image:
+```
+ls -la /usr/share/flutter
+```
+
+To change Flutter program that runs on boot edit this file:
+```
+# vi /usr/lib/systemd/system/flutter-homescreen.service
+```
+
+To change device to run Gallery on reboot edit flutter-homescreen.service to:
+```
+ExecStart=/usr/bin/flutter-auto --b=/usr/share/flutter/gallery/${FLUTTER_VERSION}/${FLUTTER_RUNTIME} --j=/usr/share/flutter/flutter-homescreen.json --xdg-shell-app-id=homescreen
+```
+To enable experimental impeller support edit flutter-homescreen.service adding --enable-impeller:
+```
+ExecStart=/usr/bin/flutter-auto --b=/usr/share/flutter/gallery/${FLUTTER_VERSION}/${FLUTTER_RUNTIME} --j=/usr/share/flutter/flutter-homescreen.json --xdg-shell-app-id=homescreen --enable-impeller
+```
+
+After edits either run:
+```
+# systemctl daemon-reload
+# systemctl restart flutter-homescreen
+```
+or
+```
+# reboot
+```
+
+Collecting a stack trace for flutter-auto
+```
+# systemctl stop flutter-auto
+# export SPDLOG_LEVEL=trace
+# export XDG_RUNTIME_DIR=/run/user/1001/
+# gdb --args flutter-auto --b=/usr/share/flutter/gallery/<flutter version>/release/ --j=/usr/share/flutter/flutter-homescreen.json --xdg-shell-app-id=homescreen
+```
+
+## Flutter Engine SDK
+
+If recipe `flutter-engine-sdk-dev` is included in your AGL image, `engine_sdk.zip` will be present in `/usr/share/flutter/`.
+
+engine_sdk.zip contains
+* sdk/flutter_sdk.version - The Flutter SDK version
+* sdk/engine.version - The git commit of the Flutter Engine
+* sdk/clang_x64/gen_snapshot - used for creating release/profile AOT image
+
+This recipe should be excluded from image in a production release.
+
+
+## Flutter Workspace Automation
+
+ cd $AGL
+ cd $AGL_TOP
+ ln -sf external/workspace-automation/flutter_workspace.py meta-agl-devel/meta-agl-flutter/tools/flutter_workspace.py
+ cd meta-agl-devel/meta-agl-flutter/tools
+ export FLUTTER_WORKSPACE=`pwd`
+ flutter_workspace.py
+ source setup_env.sh
+
+Additional documentation available [here](https://github.com/meta-flutter/meta-flutter/tree/kirkstone/tools#flutter-workspace-automation)
+
+
+## Startup Service
+
+This layer includes an example systemd user service for the Flutter Gallery application which is disabled by default. It can be used to start the application in the minimal image by doing 'systemctl start flutter-gallery'.
+
+
+## `/usr/share/flutter/default.json`
+
+For more JSON key value options see [here](https://github.com/toyota-connected/ivi-homescreen/blob/agl/README.md#json-configuration-keys)
+
+
+## Custom Devices
+
+### desktop-auto
+
+This is a desktop build of flutter-auto. The default configuration for backend is set to `egl` backend. To change this to use the `vulkan` backend, change the `backend` key value in `meta-agl-flutter/tools/flutter_workspace_config.json` from `egl` to `vulkan`. If you use the workspace configuration from meta-flutter it defaults to `vulkan`.
+
+If you are running a Gnome Display Manager (GDM) Wayland session, then it will be an available custom-device platform. To enable a Wayland session, you select the gear icon at the login window. If you don't have a gear icon available on your login screen, then you will need to adjust your system settings to enable a Wayland session.
+
+Append `--device-id=desktop-auto` to `flutter <cmd>` to select this device.
+
+### QEMU-agl
+
+This is a QEMU minimal Flutter image as referenced [here](#steps-to-build-a-minimal-flutter-image). The required runtime packages are installed as part of setup_flutter_workspace.py.
+
+If qemu_run was sucessfully invoked, then this platform will be an available `custom-device`. If QEMU instance is not running on port 2222, then this custom-device platform will not be available.
+
+Append `--device-id=AGL-qemu` to `flutter <cmd>` to select this device.
+
+### Flutter Engine
+
+To enable local build of Flutter Engine set `tools/configs/flutter-engine.json` load key to true.
+
+This enables debugging as custom engine development.
+
+## Steps to Test Flutter Images
+
+### Debug
+
+1. Set up Flutter Workspace per [Flutter Workspace Automation](#flutter-workspace-automation).
+
+2. Run the following commands on the host's terminal, a QEMU window and a new terminal for AGL will be brought up.
+
+```
+ cd $FLUTTER_WORKSPACE
+ source ./setup_env.sh
+ qemu_run
+```
+
+3. If running an updated QEMU image, edit `~/.ssh/known_hosts` and remove previous connection.
+
+4. Wait for QEMU image to boot to idle the run
+```
+ ssh -p 2222 root@localhost who
+```
+_Answering with `y` appends QEMU connection to `~/.ssh/known_hosts`_
+
+5. From the same host terminal open Visual Studio Code Select
+ * **Run and Debug**
+ * **gallery(AGL-qemu)** from the drop down combo box
+ * **run** - this launches the Flutter gallery app in the QEMU window​
+
+6. Or run from the same terminal as qemu_run was executed via
+```
+ cd $FLUTTER_WORKSPACE/app/gallery
+ flutter run --device-id=AGL-qemu
+```
+
+
+### Working with QEMU images
+
+1. Setup the flutter workspace.
+
+ source ${FLUTTER_WORKSPACE}/setup_env.sh
+
+The stdout tail should look similar to:
+
+ ********************************************
+ * Type 'run-agl-qemu-master' to start
+ ********************************************
+ ********************************************
+ * Type 'run-agl-qemu-octopus' to start
+ ********************************************
+
+3. Select image to run using one of above commands.
+
+```
+ run-agl-qemu-octopus
+```
+
+4. If running an updated QEMU image, edit `~/.ssh/known_hosts` and remove previous connection.
+
+5. Login AGL as `root`, and execute `passwd -d agl-driver`. Type `exit` and login as `agl-driver`. Run the Flutter Gallery example with the command in AGL's terminal.
+
+```
+ cd $FLUTTER_WORKSPACE/app/gallery
+ flutter run -d agl-qemu-octopus
+```
+
+
+### Profile
+
+1. Setup the flutter workspace.
+
+ source ${FLUTTER_WORKSPACE}/setup_env.sh
+
+The stdout tail should look similar to:
+
+ ********************************************
+ * Type 'run-agl-qemu-master' to start
+ ********************************************
+ ********************************************
+ * Type 'run-agl-qemu-octopus' to start
+ ********************************************
+
+3. Select image to run using one of above commands.
+
+```
+ run-agl-qemu-octopus
+```
+
+4. If running an updated QEMU image, edit `~/.ssh/known_hosts` and remove previous connection.
+
+5. After waiting for QEMU image to boot to idle issue
+```
+ ssh -p 2222 root@localhost who
+```
+Answering with `y` appends QEMU connection to `~/.ssh/known_hosts`
+
+6. Login AGL as `agl-driver`, and issue the following command
+```
+ flutter-auto --window-type="BG" --b=/usr/share/flutter/gallery/3.3.7/profile --f --observatory-host=0.0.0.0 --observatory-port=1234
+```
+
+The last line of the output message should look similar to this:
+```
+ flutter: The Dart VM service is listening on http://0.0.0.0:1234/xxxxxxxxxxx=/
+```
+
+7. Run the following command in the host terminal, using the correct hash suffix.
+```
+ flutter attach --device-id=AGL-qemu --debug-url=http://127.0.0.1:1234/xxxxxxxxxxx=/
+```
+​
+8. Then you should see the output as below. It tells us the URL of the Flutter DevTools debugger and profiler on AGL x86_64 QEMU Image.
+`An Observatory debugger and profiler on AGL x86_64 QEMU Image is available at: http://127.0.0.1:37383/xxxxxxxxxxx=/`
+​
+9. in the terminal type `v` to launch the debugger.
diff --git a/meta-agl-flutter/conf/include/agl-flutter.inc b/meta-agl-flutter/conf/include/agl-flutter.inc
new file mode 100644
index 000000000..38db25e86
--- /dev/null
+++ b/meta-agl-flutter/conf/include/agl-flutter.inc
@@ -0,0 +1,3 @@
+AGL_FEATURES += "agl-flutter"
+
+FLUTTER_SDK_TAG = "3.19.3"
diff --git a/meta-agl-flutter/conf/layer.conf b/meta-agl-flutter/conf/layer.conf
new file mode 100644
index 000000000..e21f9bc68
--- /dev/null
+++ b/meta-agl-flutter/conf/layer.conf
@@ -0,0 +1,19 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have recipes-* directories, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "agl-flutter-layer"
+BBFILE_PATTERN_agl-flutter-layer = "^${LAYERDIR}/"
+BBFILE_PRIORITY_agl-flutter-layer = "61"
+
+LAYERVERSION_agl-flutter-layer = "1"
+LAYERDEPENDS_agl-flutter-layer = "core flutter-layer"
+LAYERRECOMMENDS_agl-flutter-layer = "flutter-apps-layer"
+LAYERSERIES_COMPAT_agl-flutter-layer = "scarthgap"
+
+BBFILES_DYNAMIC += " \
+ flutter-apps-layer:${LAYERDIR}/dynamic-layers/flutter-apps-layer/*/*/*/*.bbappend \
+"
diff --git a/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery/flutter-gallery.service b/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery/flutter-gallery.service
new file mode 100644
index 000000000..28b967866
--- /dev/null
+++ b/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery/flutter-gallery.service
@@ -0,0 +1,13 @@
+[Unit]
+Requires=agl-compositor.service
+After=agl-compositor.service
+
+[Service]
+User=agl-driver
+EnvironmentFile=/etc/default/flutter
+EnvironmentFile=-/etc/default/flutter-gallery
+Environment=XDG_RUNTIME_DIR=/run/user/1001/
+ExecStart=/usr/bin/flutter-auto --b=/usr/share/flutter/flutter-gallery/${FLUTTER_VERSION}/${FLUTTER_RUNTIME} --f --window-type=BG
+
+[Install]
+WantedBy=graphical.target
diff --git a/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_%.bbappend b/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_%.bbappend
new file mode 100644
index 000000000..835e86e66
--- /dev/null
+++ b/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_%.bbappend
@@ -0,0 +1 @@
+require ${@bb.utils.contains('AGL_FEATURES', 'agl-flutter', 'flutter-gallery_aglflutter.inc', '', d)}
diff --git a/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_aglflutter.inc b/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_aglflutter.inc
new file mode 100644
index 000000000..68c07f188
--- /dev/null
+++ b/meta-agl-flutter/dynamic-layers/flutter-apps-layer/recipes-graphics/flutter-apps/first-party/flutter-gallery_aglflutter.inc
@@ -0,0 +1,13 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/flutter-gallery:"
+
+SRC_URI += "file://flutter-gallery.service"
+
+inherit systemd
+
+do_install:append() {
+ install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service
+}
+
+RDEPENDS:${PN} += "agl-flutter-env"
+
+SYSTEMD_SERVICE:${PN} = "flutter-gallery.service"
diff --git a/meta-agl-flutter/recipes-config/agl-flutter-env/agl-flutter-env_1.0.bb b/meta-agl-flutter/recipes-config/agl-flutter-env/agl-flutter-env_1.0.bb
new file mode 100644
index 000000000..aaff166bf
--- /dev/null
+++ b/meta-agl-flutter/recipes-config/agl-flutter-env/agl-flutter-env_1.0.bb
@@ -0,0 +1,15 @@
+SUMMARY = "AGL Flutter environment file"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
+
+inherit allarch
+
+AGL_FLUTTER_DEFAULT_RUNTIME ?= "release"
+
+do_compile[noexec] = "1"
+
+do_install() {
+ install -d ${D}${sysconfdir}/default
+ echo "FLUTTER_VERSION=${FLUTTER_SDK_TAG}" > ${D}${sysconfdir}/default/flutter
+ echo "FLUTTER_RUNTIME=${AGL_FLUTTER_DEFAULT_RUNTIME}" >> ${D}${sysconfdir}/default/flutter
+}
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch
new file mode 100644
index 000000000..a37233b50
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch
@@ -0,0 +1,26 @@
+From fda28bbd6718bf113061292d8cec15084060c923 Mon Sep 17 00:00:00 2001
+From: Joel Winarske <joel.winarske@gmail.com>
+Date: Wed, 19 Jul 2023 15:21:46 -0700
+Subject: [PATCH] Disable on_frame_base_surface wl_surface_commit
+
+Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
+---
+ shell/wayland/window.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/shell/wayland/window.cc b/shell/wayland/window.cc
+index c74b438..f244f08 100644
+--- a/shell/wayland/window.cc
++++ b/shell/wayland/window.cc
+@@ -257,7 +257,7 @@ void WaylandWindow::on_frame_base_surface(void* data,
+ window->m_fps_counter++;
+ window->m_fps_counter++;
+
+- wl_surface_commit(window->m_base_surface);
++ //wl_surface_commit(window->m_base_surface);
+ }
+
+ uint32_t WaylandWindow::GetFpsCounter() {
+--
+2.41.0
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch
new file mode 100644
index 000000000..fb3a5b3f7
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch
@@ -0,0 +1,190 @@
+From 2c55093cda17dd16d98a8fb0d26717b29d5d0e75 Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Thu, 28 Dec 2023 19:20:31 +0200
+Subject: [PATCH 1/2] activation_area: Add missing width and height
+
+Setting up an activation area can also require a different rectangle
+size, so allow to set-up one.
+
+Note that there's no actual check if the values are invalid, for
+instance like exceeding the output's dimensions.
+
+Bug-AGL: SPEC-5038
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/configuration/configuration.cc | 8 ++++++++
+ shell/configuration/configuration.h | 2 ++
+ shell/view/flutter_view.cc | 3 ++-
+ shell/wayland/display.cc | 10 +++++-----
+ shell/wayland/display.h | 8 +++++++-
+ shell/wayland/window.cc | 13 +++++++++----
+ shell/wayland/window.h | 4 ++++
+ 7 files changed, 37 insertions(+), 11 deletions(-)
+
+diff --git a/shell/configuration/configuration.cc b/shell/configuration/configuration.cc
+index 2cec924..63b7a82 100644
+--- a/shell/configuration/configuration.cc
++++ b/shell/configuration/configuration.cc
+@@ -104,9 +104,17 @@ void Configuration::getViewParameters(
+
+ instance.view.activation_area_x = static_cast<uint32_t>(val["x"].GetInt());
+ instance.view.activation_area_y = static_cast<uint32_t>(val["y"].GetInt());
++ instance.view.activation_area_width =
++ static_cast<uint32_t>(val["width"].GetInt());
++ instance.view.activation_area_height =
++ static_cast<uint32_t>(val["height"].GetInt());
+
+ SPDLOG_DEBUG("activation area x {}", instance.view.activation_area_x);
+ SPDLOG_DEBUG("activation area y {}", instance.view.activation_area_y);
++ SPDLOG_DEBUG("activation area width {}",
++ instance.view.activation_area_width);
++ SPDLOG_DEBUG("activation area height {}",
++ instance.view.activation_area_height);
+ }
+ }
+
+diff --git a/shell/configuration/configuration.h b/shell/configuration/configuration.h
+index 0e3d721..b0ccbc9 100644
+--- a/shell/configuration/configuration.h
++++ b/shell/configuration/configuration.h
+@@ -44,6 +44,8 @@ class Configuration {
+ uint32_t height;
+ uint32_t activation_area_x;
+ uint32_t activation_area_y;
++ uint32_t activation_area_width;
++ uint32_t activation_area_height;
+ bool fullscreen;
+ bool fullscreen_set;
+ double pixel_ratio;
+diff --git a/shell/view/flutter_view.cc b/shell/view/flutter_view.cc
+index ca51f4e..7b48b85 100644
+--- a/shell/view/flutter_view.cc
++++ b/shell/view/flutter_view.cc
+@@ -67,9 +67,10 @@ FlutterView::FlutterView(Configuration::Config config,
+ m_wayland_window = std::make_shared<WaylandWindow>(
+ m_index, display, m_config.view.window_type,
+ m_wayland_display->GetWlOutput(m_config.view.wl_output_index),
+- m_config.view.wl_output_index, m_config.app_id, m_config.view.fullscreen,
++ m_config.view.wl_output_index, m_config.app_id, m_config.view.fullscreen,
+ m_config.view.width, m_config.view.height, m_config.view.pixel_ratio,
+ m_config.view.activation_area_x, m_config.view.activation_area_y,
++ m_config.view.activation_area_width, m_config.view.activation_area_height,
+ m_backend.get(), m_config.view.ivi_surface_id);
+ }
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index aba050a..0b97954 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -857,16 +857,16 @@ void Display::AglShellDoReady() const {
+
+ void Display::AglShellDoSetupActivationArea(uint32_t x,
+ uint32_t y,
++ uint32_t width,
++ uint32_t height,
+ uint32_t index) {
+- uint32_t width = m_all_outputs[index]->width;
+- uint32_t height = m_all_outputs[index]->height - (2 * y);
+-
+ if (!m_agl.shell)
+ return;
+
+ if (m_all_outputs[index]->transform == WL_OUTPUT_TRANSFORM_90) {
+- width = m_all_outputs[index]->height;
+- height = m_all_outputs[index]->width - (2 * y);
++ uint32_t tmp_width = width;
++ width = height;
++ height = tmp_width;
+ }
+
+ SPDLOG_DEBUG("Using custom rectangle [{}x{}+{}x{}] for activation", width,
+diff --git a/shell/wayland/display.h b/shell/wayland/display.h
+index b919047..a792ad7 100644
+--- a/shell/wayland/display.h
++++ b/shell/wayland/display.h
+@@ -172,6 +172,8 @@ class Display {
+ * @return void
+ * @param[in] x the x position for the activation rectangle
+ * @param[in] y the y position for the activation rectangle
++ * @param[in] width the width position for the activation rectangle
++ * @param[in] height the height position for the activation rectangle
+ * @param[index] the output, as a number
+ * @relation
+ *
+@@ -193,7 +195,11 @@ class Display {
+ * | |
+ * --------------------
+ */
+- void AglShellDoSetupActivationArea(uint32_t x, uint32_t y, uint32_t index);
++ void AglShellDoSetupActivationArea(uint32_t x,
++ uint32_t y,
++ uint32_t width,
++ uint32_t height,
++ uint32_t index);
+
+ /**
+ * @brief Set Engine
+diff --git a/shell/wayland/window.cc b/shell/wayland/window.cc
+index 373b0a2..f816e58 100644
+--- a/shell/wayland/window.cc
++++ b/shell/wayland/window.cc
+@@ -31,6 +31,8 @@ WaylandWindow::WaylandWindow(size_t index,
+ double pixel_ratio,
+ uint32_t activation_area_x,
+ uint32_t activation_area_y,
++ uint32_t activation_area_width,
++ uint32_t activation_area_height,
+ Backend* backend,
+ uint32_t ivi_surface_id)
+ : m_index(index),
+@@ -42,7 +44,8 @@ WaylandWindow::WaylandWindow(size_t index,
+ m_geometry({width, height}),
+ m_window_size({width, height}),
+ m_pixel_ratio(pixel_ratio),
+- m_activation_area({activation_area_x, activation_area_y}),
++ m_activation_area({activation_area_x, activation_area_y,
++ activation_area_width, activation_area_height}),
+ m_type(get_window_type(type)),
+ m_app_id(std::move(app_id)),
+ m_ivi_surface_id(ivi_surface_id),
+@@ -98,10 +101,12 @@ WaylandWindow::WaylandWindow(size_t index,
+ case WINDOW_BG:
+ m_display->AglShellDoBackground(m_base_surface, 0);
+ if (m_activation_area.x > 0 && m_activation_area.y > 0)
+- m_display->AglShellDoSetupActivationArea(m_activation_area.x,
+- m_activation_area.y, 0);
++ m_display->AglShellDoSetupActivationArea(
++ m_activation_area.x, m_activation_area.y, m_activation_area.width,
++ m_activation_area.height, 0);
+ else
+- m_display->AglShellDoSetupActivationArea(0, 160, 0);
++ m_display->AglShellDoSetupActivationArea(0, 160, m_activation_area.width,
++ m_activation_area.height, 0);
+ break;
+ case WINDOW_PANEL_TOP:
+ m_display->AglShellDoPanel(m_base_surface, AGL_SHELL_EDGE_TOP, 0);
+diff --git a/shell/wayland/window.h b/shell/wayland/window.h
+index 998a1c8..f66f70a 100644
+--- a/shell/wayland/window.h
++++ b/shell/wayland/window.h
+@@ -67,6 +67,8 @@ class WaylandWindow {
+ double pixel_ratio,
+ uint32_t activation_area_x,
+ uint32_t activation_area_y,
++ uint32_t activation_area_width,
++ uint32_t activation_area_height,
+ Backend* backend,
+ uint32_t ivi_surface_id);
+
+@@ -166,6 +168,8 @@ class WaylandWindow {
+ struct {
+ uint32_t x;
+ uint32_t y;
++ uint32_t width;
++ uint32_t height;
+ } m_activation_area;
+ struct {
+ int32_t width;
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch
new file mode 100644
index 000000000..6b1b3e4c9
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch
@@ -0,0 +1,117 @@
+From 10d1d855a0ce4557cb710e73e3e7c9ab0dd0e734 Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Mon, 4 Dec 2023 14:16:36 +0200
+Subject: [PATCH 1/2] display: Add support for wl_output version 4
+
+This allows support for wl_output.name and wl_output.desc be sent out
+by the compositor that supports it.
+
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/display.cc | 34 ++++++++++++++++++++++++++++++----
+ shell/wayland/display.h | 28 ++++++++++++++++++++++++++++
+ 2 files changed, 58 insertions(+), 4 deletions(-)
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index 8e309ef..3ee814a 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -191,9 +191,16 @@ void Display::registry_handle_global(void* data,
+ auto oi = std::make_shared<output_info_t>();
+ std::fill_n(oi.get(), 1, output_info_t{});
+ oi->global_id = name;
+- oi->output = static_cast<struct wl_output*>(
+- wl_registry_bind(registry, name, &wl_output_interface,
+- std::min(static_cast<uint32_t>(2), version)));
++ // be compat with v2 as well
++ if (version >= WL_OUTPUT_NAME_SINCE_VERSION &&
++ version >= WL_OUTPUT_DESCRIPTION_SINCE_VERSION)
++ oi->output = static_cast<struct wl_output*>(
++ wl_registry_bind(registry, name, &wl_output_interface,
++ std::min(static_cast<uint32_t>(4), version)));
++ else
++ oi->output = static_cast<struct wl_output*>(
++ wl_registry_bind(registry, name, &wl_output_interface,
++ std::min(static_cast<uint32_t>(2), version)));
+ wl_output_add_listener(oi->output, &output_listener, oi.get());
+ SPDLOG_DEBUG("Wayland: Output [{}]", d->m_all_outputs.size());
+ d->m_all_outputs.push_back(oi);
+@@ -299,9 +306,28 @@ void Display::display_handle_done(void* data,
+ oi->done = true;
+ }
+
++void Display::display_handle_name(void* data,
++ struct wl_output* /* wl_output */,
++ const char* name) {
++ auto* oi = static_cast<output_info_t*>(data);
++ oi->name = std::string(name);
++}
++
++void Display::display_handle_desc(void* data,
++ struct wl_output* /* wl_output */,
++ const char* desc) {
++ auto* oi = static_cast<output_info_t*>(data);
++ oi->desc = std::string(desc);
++}
++
+ const struct wl_output_listener Display::output_listener = {
+ display_handle_geometry, display_handle_mode, display_handle_done,
+- display_handle_scale};
++ display_handle_scale
++#if defined(WL_OUTPUT_NAME_SINCE_VERSION) && \
++ defined(WL_OUTPUT_DESCRIPTION_SINCE_VERSION)
++ , display_handle_name, display_handle_desc
++#endif
++};
+
+ void Display::shm_format(void* /* data */,
+ struct wl_shm* /* wl_shm */,
+diff --git a/shell/wayland/display.h b/shell/wayland/display.h
+index cc3f4be..a0756f0 100644
+--- a/shell/wayland/display.h
++++ b/shell/wayland/display.h
+@@ -329,6 +329,8 @@ class Display {
+ int32_t scale;
+ MAYBE_UNUSED bool done;
+ int transform;
++ std::string name;
++ std::string desc;
+ } output_info_t;
+
+ struct pointer_event {
+@@ -520,6 +522,32 @@ class Display {
+ */
+ static void display_handle_done(void* data, struct wl_output* wl_output);
+
++ /**
++ * @brief Set the display output name
++ * @param[in,out] data Data of type output_info_t*
++ * @param[in] wl_output No use
++ * @param[in] output_name Display name
++ * @return void
++ * @relation
++ * wayland - since @v4 of wl_output
++ */
++ static void display_handle_name(void* data,
++ struct wl_output* wl_output,
++ const char* output_name);
++
++ /**
++ * @brief Set the display description
++ * @param[in,out] data Data of type output_info_t*
++ * @param[in] wl_output No use
++ * @param[in] desc_name Display description name
++ * @return void
++ * @relation
++ * wayland - since @v4 of wl_output
++ */
++ static void display_handle_desc(void* data,
++ struct wl_output* wl_output,
++ const char* desc_name);
++
+ static const struct wl_shm_listener shm_listener;
+
+ /**
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch
new file mode 100644
index 000000000..f0cf9ddb3
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch
@@ -0,0 +1,28 @@
+From 641ca7ca26c1bfc11e7d0c0f30b731f53467bf1f Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Thu, 28 Dec 2023 20:28:12 +0200
+Subject: [PATCH 2/2] activation_area: Allow x and y values be zero for the
+ activation area
+
+Bug-AGL: SPEC-5038
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/window.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/shell/wayland/window.cc b/shell/wayland/window.cc
+index f816e58..929b9af 100644
+--- a/shell/wayland/window.cc
++++ b/shell/wayland/window.cc
+@@ -100,7 +100,7 @@ WaylandWindow::WaylandWindow(size_t index,
+ break;
+ case WINDOW_BG:
+ m_display->AglShellDoBackground(m_base_surface, 0);
+- if (m_activation_area.x > 0 && m_activation_area.y > 0)
++ if (m_activation_area.x >= 0 && m_activation_area.y >= 0)
+ m_display->AglShellDoSetupActivationArea(
+ m_activation_area.x, m_activation_area.y, m_activation_area.width,
+ m_activation_area.height, 0);
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch
new file mode 100644
index 000000000..792811769
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch
@@ -0,0 +1,477 @@
+From d44f07a0c2cc410414bfd7b338ee071c17422a0a Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Mon, 4 Dec 2023 18:17:00 +0200
+Subject: [PATCH 2/2] display: Add support for agl_shell version 8
+
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/display.cc | 156 ++++++++++++++++++++++--
+ shell/wayland/display.h | 58 +++++++++
+ third_party/agl/protocol/agl-shell.xml | 160 ++++++++++++++++++++++++-
+ 3 files changed, 366 insertions(+), 8 deletions(-)
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index 3ee814a..aba050a 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -220,7 +220,7 @@ void Display::registry_handle_global(void* data,
+ if (version >= 2) {
+ d->m_agl.shell = static_cast<struct agl_shell*>(
+ wl_registry_bind(registry, name, &agl_shell_interface,
+- std::min(static_cast<uint32_t>(4), version)));
++ std::min(static_cast<uint32_t>(8), version)));
+ agl_shell_add_listener(d->m_agl.shell, &agl_shell_listener, data);
+ } else {
+ d->m_agl.shell = static_cast<struct agl_shell*>(
+@@ -980,6 +980,148 @@ void Display::agl_shell_bound_fail(void* data, struct agl_shell* shell) {
+ d->m_agl.bound_ok = false;
+ }
+
++void Display::addAppToStack(std::string app_id) {
++ if (app_id == "homescreen")
++ return;
++
++ bool found_app = false;
++ for (auto& i : apps_stack) {
++ if (i == app_id) {
++ found_app = true;
++ break;
++ }
++ }
++
++ if (!found_app) {
++ apps_stack.push_back(app_id);
++ } else {
++ // fixme
++ }
++}
++
++int Display::find_output_by_name(std::string output_name) {
++ int index = 0;
++ for (auto& i : m_all_outputs) {
++ if (i->name == output_name) {
++ return index;
++ }
++ index++;
++ }
++
++ return -1;
++}
++
++void Display::activateApp(std::string app_id) {
++ int default_output_index = 0;
++
++ FML_LOG(INFO) << "got app_id " << app_id;
++
++ // search for a pending application which might have a different output
++ auto iter = pending_app_list.begin();
++ bool found_pending_app = false;
++ while (iter != pending_app_list.end()) {
++ auto app_to_search = iter->first;
++ FML_LOG(INFO) << "searching for " << app_to_search;
++
++ if (app_to_search == app_id) {
++ found_pending_app = true;
++ break;
++ }
++
++ iter++;
++ }
++
++ if (found_pending_app) {
++ auto output_name = iter->second;
++ default_output_index = find_output_by_name(output_name);
++
++ FML_LOG(INFO) << "Found app_id " << app_id << " at all";
++
++ if (default_output_index < 0) {
++ // try with remoting-remote-X which is the streaming
++ std::string new_remote_output = "remoting-" + output_name;
++
++ default_output_index = find_output_by_name(new_remote_output);
++ if (default_output_index < 0) {
++ FML_LOG(INFO) << "Not activating app_id " << app_id << " at all";
++ return;
++ }
++ }
++
++ pending_app_list.erase(iter);
++ }
++
++ FML_LOG(INFO) << "Activating app_id " << app_id << " on output "
++ << default_output_index;
++ agl_shell_activate_app(m_agl.shell, app_id.c_str(),
++ m_all_outputs[default_output_index]->output);
++ wl_display_flush(m_display);
++}
++
++void Display::deactivateApp(std::string app_id) {
++ for (auto& i : apps_stack) {
++ if (i == app_id) {
++ // remove it from apps_stack
++ apps_stack.remove(i);
++ if (!apps_stack.empty())
++ activateApp(apps_stack.back());
++ break;
++ }
++ }
++}
++
++void Display::processAppStatusEvent(const char* app_id,
++ const std::string event_type) {
++ if (!m_agl.shell)
++ return;
++
++ if (event_type == "started") {
++ activateApp(std::string(app_id));
++ } else if (event_type == "terminated") {
++ deactivateApp(std::string(app_id));
++ } else if (event_type == "deactivated") {
++ // not handled
++ }
++}
++
++void Display::agl_shell_app_on_output(void* data,
++ struct agl_shell* agl_shell,
++ const char* app_id,
++ const char* output_name) {
++ auto* d = static_cast<Display*>(data);
++
++ FML_LOG(INFO) << "Gove event app_on_out app_id " << app_id << " output name "
++ << output_name;
++
++ // a couple of use-cases, if there is no app_id in the app_list then it
++ // means this is a request to map the application, from the start to a
++ // different output that the default one. We'd get an
++ // AGL_SHELL_APP_STATE_STARTED which will handle activation.
++ //
++ // if there's an app_id then it means we might have gotten an event to
++ // move the application to another output; so we'd need to process it
++ // by explicitly calling processAppStatusEvent() which would ultimately
++ // activate the application on other output. We'd have to pick-up the
++ // last activated window and activate the default output.
++ //
++ // finally if the outputs are identical probably that's an user-error -
++ // but the compositor won't activate it again, so we don't handle that.
++ std::pair new_pending_app =
++ std::pair(std::string(app_id), std::string(output_name));
++ d->pending_app_list.push_back(new_pending_app);
++
++ auto iter = d->apps_stack.begin();
++ while (iter != d->apps_stack.end()) {
++ if (*iter == std::string(app_id)) {
++ FML_LOG(INFO) << "Gove event to move " << app_id << " to another output "
++ << output_name;
++ d->processAppStatusEvent(app_id, std::string("started"));
++ break;
++ }
++ iter++;
++ }
++}
++
+ void Display::agl_shell_app_state(void* data,
+ struct agl_shell* /* agl_shell */,
+ const char* app_id,
+@@ -991,12 +1133,7 @@ void Display::agl_shell_app_state(void* data,
+ FML_DLOG(INFO) << "Got AGL_SHELL_APP_STATE_STARTED for app_id " << app_id;
+
+ if (d->m_agl.shell) {
+- // we always assume the first output advertised by the wl_output
+- // interface
+- unsigned int default_output_index = 0;
+-
+- agl_shell_activate_app(d->m_agl.shell, app_id,
+- d->m_all_outputs[default_output_index]->output);
++ d->processAppStatusEvent(app_id, std::string("started"));
+ }
+
+ break;
+@@ -1007,6 +1144,10 @@ void Display::agl_shell_app_state(void* data,
+ case AGL_SHELL_APP_STATE_ACTIVATED:
+ FML_DLOG(INFO) << "Got AGL_SHELL_APP_STATE_ACTIVATED for app_id "
+ << app_id;
++ d->addAppToStack(std::string(app_id));
++ break;
++ case AGL_SHELL_APP_STATE_DEACTIVATED:
++ d->processAppStatusEvent(app_id, std::string("deactivated"));
+ break;
+ default:
+ break;
+@@ -1017,6 +1158,7 @@ const struct agl_shell_listener Display::agl_shell_listener = {
+ .bound_ok = agl_shell_bound_ok,
+ .bound_fail = agl_shell_bound_fail,
+ .app_state = agl_shell_app_state,
++ .app_on_output = agl_shell_app_on_output,
+ };
+
+ void Display::ivi_wm_surface_visibility(void* /* data */,
+diff --git a/shell/wayland/display.h b/shell/wayland/display.h
+index a0756f0..b919047 100644
+--- a/shell/wayland/display.h
++++ b/shell/wayland/display.h
+@@ -18,6 +18,7 @@
+ #pragma once
+
+ #include <chrono>
++#include <list>
+ #include <memory>
+ #include <mutex>
+ #include <string>
+@@ -271,6 +272,44 @@ class Display {
+ */
+ std::pair<int32_t, int32_t> GetVideoModeSize(uint32_t index);
+
++ /**
++ * @brief deactivate/hide the application pointed by app_id
++ * @param[in] app_id the app_id
++ * @relation
++ * agl_shell
++ */
++ void deactivateApp(std::string app_id);
++ /**
++ * @brief activate/show the application pointed by app_id
++ * @param[in] app_id the app_id
++ * @relation
++ * agl_shell
++ */
++ void activateApp(std::string app_id);
++ /**
++ * @brief Add app_id to a list of list applications
++ * @param[in] app_id the app_id
++ * @relation
++ * agl_shell
++ */
++ void addAppToStack(std::string app_id);
++ /**
++ * @brief Helper to retrieve the output using its output_name
++ * @param[in] output_name a std::string representing the output
++ * @retval an integer that can used to get the proper output
++ * @relation
++ * agl_sell
++ */
++ int find_output_by_name(std::string output_name);
++ /**
++ * @brief helper to process the application status
++ * @param[in] app_id an array of char
++ * @param[in] event_type a std::string representing the type of event (started/stopped/terminated)
++ * @relation
++ * agl_shell
++ */
++ void processAppStatusEvent(const char* app_id, const std::string event_type);
++
+ private:
+ std::shared_ptr<Engine> m_flutter_engine;
+
+@@ -300,6 +339,9 @@ class Display {
+ uint32_t version = 0;
+ } m_agl;
+
++ std::list<std::string> apps_stack;
++ std::list<std::pair<const std::string, const std::string>> pending_app_list;
++
+ struct ivi_shell {
+ struct ivi_application* application = nullptr;
+ struct ivi_wm* ivi_wm = nullptr;
+@@ -982,6 +1024,22 @@ class Display {
+ const char* app_id,
+ uint32_t state);
+
++ /**
++ * @brief AGL app_app_on_output event
++ * @param[in,out] data Data of type Display
++ * @param[in] shell No use
++ * @param[in] app_id the application id for which this event was sent
++ * @param[in] state the state: CREATED/TERMINATED/ACTIVATED/DEACTIVATED
++ * @return void
++ * @relation
++ * wayland, agl-shell
++ * @note Do nothing
++ */
++ static void agl_shell_app_on_output(void* data,
++ struct agl_shell* agl_shell,
++ const char* app_id,
++ const char* output_name);
++
+ static const struct agl_shell_listener agl_shell_listener;
+
+ /**
+diff --git a/third_party/agl/protocol/agl-shell.xml b/third_party/agl/protocol/agl-shell.xml
+index bf5ab02..e010a80 100644
+--- a/third_party/agl/protocol/agl-shell.xml
++++ b/third_party/agl/protocol/agl-shell.xml
+@@ -22,7 +22,7 @@
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+- <interface name="agl_shell" version="4">
++ <interface name="agl_shell" version="8">
+ <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.
+@@ -200,5 +200,163 @@
+ <arg name="width" type="int" summary="width of rectangle"/>
+ <arg name="height" type="int" summary="height of rectangle"/>
+ </request>
++
++ <request name="deactivate_app" since="5">
++ <description summary="de-activate/hide window identified by app_id">
++ Ask the compositor to hide the toplevel window for window
++ management purposes. Depending on the window role, this request
++ will either display the previously active window (or the background
++ in case there's no previously active surface) or temporarily (or
++ until a 'activate_app' is called upon) hide the surface.
++
++ All the surfaces are identifiable by using the app_id, and no actions
++ are taken in case the app_id is not/was not present.
++
++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a
++ description of app_id.
++ </description>
++ <arg name="app_id" type="string"/>
++ </request>
++
++ <request name="set_app_float" since="6">
++ <description summary="set the window identified by app_id as float">
++ Makes the application identified by app_id as floating. If the
++ application's window is already mapped, in a maximized, normal state,
++ it would transition to the float state.
++
++ For applications that want to modify their own state, this request
++ must be done before the initial surface commit in order to take effect.
++
++ If the application is already in floating state, this request wouldn't
++ do anything.
++
++ There's no persistence of this request, once the application terminated
++ you'll to issue this request again for that particular app_id.
++
++ The x, and y values would be initial position of the window where the
++ window surface will be placed.
++
++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a
++ description of app_id.
++ </description>
++ <arg name="app_id" type="string"/>
++ <arg name="x" type="int" summary="x position"/>
++ <arg name="y" type="int" summary="y position"/>
++ </request>
++
++ <request name="set_app_normal" since="6">
++ <description summary="set the window identified by app_id as normally started">
++ Returns the application identified by app_id as it was in the normal state.
++ This is useful to come back from other states to the maximized state, the
++ normal state applications are started.
++ </description>
++ <arg name="app_id" type="string"/>
++ </request>
++
++ <request name="set_app_fullscreen" since="7">
++ <description summary="">
++ Makes the application identified by app_id as fullscreen. If the
++ application's window is already mapped, in a maximized, normal state,
++ it would transition to the fullscreen state.
++
++ For applications that want to modify their own state, this request
++ must be done before the initial surface commit in order to take effect.
++
++ If the application is already in fullscreen state, this request wouldn't
++ do anything.
++
++ There's no persistence of this request, once the application terminated
++ you'll to issue this request again for that particular app_id.
++
++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a
++ description of app_id.
++ </description>
++ <arg name="app_id" type="string"/>
++ </request>
++
++ <request name="set_app_output" since="8">
++ <description summary="Assign an application to a particular output">
++ This would allow the compositor to place an application on a particular
++ output, if that output is indeed available. This can happen before
++ application is started which would make the application start on that
++ particular output. If the application is already started it would
++ move the application to that output.
++
++ There's no persistence of this request, once the application terminated
++ you'll need to issue this request again for that particular app_id.
++
++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a
++ description of app_id.
++ </description>
++ <arg name="app_id" type="string"/>
++ <arg name="output" type="object" interface="wl_output"/>
++ </request>
++
++ <event name="app_on_output" since="8">
++ <description summary="Event sent as a reponse to set_app_output">
++ Clients can use this event to be notified when an application
++ wants to be displayed on a certain output. This event is sent in
++ response to the set_app_output request.
++
++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a
++ description of app_id.
++ </description>
++ <arg name="app_id" type="string"/>
++ <arg name="output_name" type="string"/>
++ </event>
++ </interface>
++
++ <interface name="agl_shell_ext" version="1">
++ <description summary="extended user interface for Automotive Grade Linux platform">
++ This interface allows another client bind to the agl_shell interface,
++ while there's another shell client already present.
++
++ The client should first bind to this interface and then inform the
++ compositor with the 'doas_shell_client' request and it wants to bind to
++ the agl_shell interface. The client is still expected, if using a new
++ version of the agl_shell interface, to wait for the 'bound_ok' and
++ 'bound_fail' events before issueing any other requests/events.
++
++ Note that this interface has its limitations, and the compositor would
++ still refuse the act for 'set_panel' or 'set_background' requests
++ of the agl_shell interface if there's already a client that used them.
++
++ Any other requests or events should be delievered and handled as it would
++ a client bound to the agl_shell interface.
++ </description>
++
++ <enum name="doas_shell_client_status">
++ <entry name="success" value="0"/>
++ <entry name="failed" value="1"/>
++ </enum>
++
++ <request name="destroy" type="destructor">
++ <description summary="destroys the factory object">
++ Call the destructor once you're ready with agl_shell_ext interface.
++ This would reset the state and would make any requests made
++ on the agl_shell interface be terminated. The client would need
++ to bind again the agl_shell_ext and issue a 'doas_shell_client'
++ request.
++ </description>
++ </request>
++
++ <request name="doas_shell_client">
++ <description summary="Informs the compositor it wants to bind to the
++ agl_shell interface">
++ Prior to binding to agl_shell interface, this request would inform
++ the compositor that it wants to gain access the agl_shell interface.
++ The client is expected to wait for 'doas_shell_client_done' event and
++ check for a successful status before going further with binding to
++ the agl_shell interface.
++ </description>
++ </request>
++
++ <event name="doas_done">
++ <description summary="event sent as a reply to doas_shell_client">
++ The client should check the status event to verify that the
++ compositor was able to handle the request.
++ </description>
++ <arg name="status" type="uint" enum="doas_shell_client_status"/>
++ </event>
+ </interface>
+ </protocol>
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch
new file mode 100644
index 000000000..f59add5a8
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch
@@ -0,0 +1,33 @@
+From b247f63441f75c47cebd6edd00ecc0c5f94728b6 Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Tue, 2 Jan 2024 15:00:13 +0200
+Subject: [PATCH 3/3] activation_area: Remove the implicit width/height swap
+
+This does more harm than being useful so remove it.
+
+Bug-AGL: SPEC-5038
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/display.cc | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index 0b97954..9452dbf 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -863,12 +863,6 @@ void Display::AglShellDoSetupActivationArea(uint32_t x,
+ if (!m_agl.shell)
+ return;
+
+- if (m_all_outputs[index]->transform == WL_OUTPUT_TRANSFORM_90) {
+- uint32_t tmp_width = width;
+- width = height;
+- height = tmp_width;
+- }
+-
+ SPDLOG_DEBUG("Using custom rectangle [{}x{}+{}x{}] for activation", width,
+ height, x, y);
+
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_%.bbappend b/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_%.bbappend
new file mode 100644
index 000000000..dbc82bc3f
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_%.bbappend
@@ -0,0 +1 @@
+require ${@bb.utils.contains('AGL_FEATURES', 'agl-flutter', 'flutter-auto_aglflutter.inc', '', d)}
diff --git a/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc b/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc
new file mode 100644
index 000000000..c75cdc007
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/flutter-auto_aglflutter.inc
@@ -0,0 +1,9 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
+
+SRC_URI:append:use-nxp-bsp = " file://0001-Disable-on_frame_base_surface-wl_surface_commit.patch"
+SRC_URI:append: = " file://0001-display-Add-support-for-wl_output-version-4.patch \
+ file://0002-display-Add-support-for-agl_shell-version-8.patch \
+ file://0001-activation_area-Add-missing-width-and-height.patch \
+ file://0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch \
+ file://0003-activation_area-Remove-the-implicit-width-height-swa.patch \
+ "
diff --git a/meta-agl-flutter/recipes-platform/images/agl-image-flutter-debug.bb b/meta-agl-flutter/recipes-platform/images/agl-image-flutter-debug.bb
new file mode 100644
index 000000000..c9c1f2980
--- /dev/null
+++ b/meta-agl-flutter/recipes-platform/images/agl-image-flutter-debug.bb
@@ -0,0 +1,29 @@
+require recipes-platform/images/agl-image-compositor.bb
+
+SUMMARY = "Example Flutter application debug image for development"
+LICENSE = "MIT"
+
+CLANGSDK = "1"
+
+# NOTES:
+# - the package-management IMAGE_FEATURE and packagegroup-agl-core-devel
+# are explicitly added here to cover the usecase of building without
+# passing agl-devel to aglsetup.sh. This is explicitly a debug image
+# where those are are always desired.
+# - Getting the debug version of the application requires changing
+# the value of FLUTTER_APP_RUNTIME_MODES to include "debug",
+# which is outside the scope of this image recipe.
+
+IMAGE_FEATURES += "ssh-server-openssh package-management dbg-pkgs"
+
+IMAGE_INSTALL += "\
+ packagegroup-agl-core-devel \
+ \
+ weston-ini-conf-landscape \
+ \
+ flutter-auto-verbose-logs \
+ \
+ flutter-engine-sdk-dev \
+ \
+ flutter-gallery \
+"
diff --git a/meta-agl-flutter/recipes-platform/images/agl-image-flutter.bb b/meta-agl-flutter/recipes-platform/images/agl-image-flutter.bb
new file mode 100644
index 000000000..0fdb7da08
--- /dev/null
+++ b/meta-agl-flutter/recipes-platform/images/agl-image-flutter.bb
@@ -0,0 +1,16 @@
+require recipes-platform/images/agl-image-compositor.bb
+
+SUMMARY = "Example Flutter application image"
+LICENSE = "MIT"
+
+CLANGSDK = "1"
+
+IMAGE_FEATURES += "ssh-server-openssh"
+
+IMAGE_INSTALL += "\
+ weston-ini-conf-landscape \
+ \
+ flutter-auto \
+ \
+ flutter-gallery \
+"
diff --git a/meta-agl-flutter/tools/.gitignore b/meta-agl-flutter/tools/.gitignore
new file mode 100644
index 000000000..abda9b65c
--- /dev/null
+++ b/meta-agl-flutter/tools/.gitignore
@@ -0,0 +1,151 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# IDEA
+.idea
+
+# Flutter Workspace generated
+.agl
+.config
+.flutter-auto
+.pub_cache
+.tmp
+.vscode
+setup_env.sh
+flutter
+app
+flutter_*.log
+qemu_run.scpt
+
+dart-revision.json
+engine-revision.json
+
+*.scpt
+
diff --git a/meta-agl-flutter/tools/configs/_globals.json b/meta-agl-flutter/tools/configs/_globals.json
new file mode 100644
index 000000000..4caf9e8a0
--- /dev/null
+++ b/meta-agl-flutter/tools/configs/_globals.json
@@ -0,0 +1,5 @@
+{
+ "flutter-version": "3.19.3",
+ "github_token": "",
+ "cookie_file": ""
+} \ No newline at end of file
diff --git a/meta-agl-flutter/tools/configs/_repos.json b/meta-agl-flutter/tools/configs/_repos.json
new file mode 100644
index 000000000..7002d4161
--- /dev/null
+++ b/meta-agl-flutter/tools/configs/_repos.json
@@ -0,0 +1,11 @@
+[
+ {
+ "uri": "https://github.com/toyota-connected/ivi-homescreen.git",
+ "rev": "ee49745485a88f23c32b8e3a62da40d4102c4623",
+ "branch": "agl"
+ },
+ {
+ "uri": "https://chromium.googlesource.com/chromium/tools/depot_tools.git",
+ "branch": "main"
+ }
+]
diff --git a/meta-agl-flutter/tools/configs/agl-qemu-master.json b/meta-agl-flutter/tools/configs/agl-qemu-master.json
new file mode 100644
index 000000000..eba953f7d
--- /dev/null
+++ b/meta-agl-flutter/tools/configs/agl-qemu-master.json
@@ -0,0 +1,114 @@
+{
+ "id": "agl-qemu-master",
+ "load": true,
+ "supported_archs": [
+ "x86_64",
+ "arm64"
+ ],
+ "supported_host_types": [
+ "darwin",
+ "ubuntu",
+ "fedora"
+ ],
+ "flutter_runtime": "debug",
+ "type": "qemu",
+ "env": {
+ "RELEASE_NAME": "master",
+ "RELEASE_VERSION": "latest",
+ "FLUTTER_DEBUG_PORT": "1234",
+ "FLUTTER_OBSERVATORY_HOST": "0.0.0.0",
+ "CONTAINER_SSH_PORT": "2222",
+ "DEVICE_HOSTNAME": "localhost",
+ "FLUTTER_AUTO_EXE": "flutter-auto --j=/tmp/${appName}/default_config.json --b=/tmp/${appName}",
+ "PING_CMD": "(echo >/dev/tcp/localhost/${CONTAINER_SSH_PORT}) &>/dev/null && echo open || echo closed",
+ "DELETE_USER_PWD": "ssh -p ${CONTAINER_SSH_PORT} -t -oBatchMode=yes root@${DEVICE_HOSTNAME} passwd -d agl-driver",
+ "CREATE_BUNDLE_FOLDER": "ssh -p ${CONTAINER_SSH_PORT} -o BatchMode=yes agl-driver@${DEVICE_HOSTNAME} mkdir -p /tmp/${appName}/data",
+ "COPY_PLATFORM_ID_TO_DEVICE": "scp -P ${CONTAINER_SSH_PORT} -r ${PLATFORM_ID_DIR}/default_config.json agl-driver@${DEVICE_HOSTNAME}:/tmp/${appName}/",
+ "COPY_ASSETS_TO_DEVICE": "scp -P ${CONTAINER_SSH_PORT} -r ${localPath}/* agl-driver@${DEVICE_HOSTNAME}:/tmp/${appName}/data/flutter_assets",
+ "DELETE_APP_FOLDER": "ssh -p ${CONTAINER_SSH_PORT} -o BatchMode=yes agl-driver@${DEVICE_HOSTNAME} rm -rf /tmp/${appName}"
+ },
+ "runtime": {
+ "config": {
+ "view": [
+ {
+ "window_type": "BG",
+ "width": 1920,
+ "height": 1080
+ }
+ ]
+ },
+ "pre-requisites": {
+ "arm64": {
+ "darwin": {
+ "cmds": [
+ "bash -c \"arch -arm64 brew install xz\"",
+ "bash -c \"arch -arm64 brew install qemu\""
+ ]
+ }
+ }
+ },
+ "artifacts": {
+ "http": {
+ "url": "https://download.automotivelinux.org/AGL/snapshots/${RELEASE_NAME}/${RELEASE_VERSION}",
+ "artifacts": {
+ "x86_64": [
+ {
+ "endpoint": "/qemux86-64/deploy/images/qemux86-64/agl-ivi-demo-platform-flutter-qemux86-64.wic.vmdk.xz"
+ }
+ ],
+ "arm64": [
+ {
+ "endpoint": "/qemuarm64/deploy/images/qemuarm64/agl-demo-platform-crosssdk-qemuarm64.ext4.xz"
+ },
+ {
+ "endpoint": "/qemuarm64/deploy/images/qemuarm64/Image-qemuarm64.bin"
+ }
+ ]
+ }
+ }
+ },
+ "qemu": {
+ "cmd": "qemu-system-${FORMAL_MACHINE_ARCH}",
+ "x86_64": {
+ "image": "agl-ivi-demo-platform-flutter-qemux86-64.wic.vmdk",
+ "args": "-m 2048 ${QEMU_EXTRA} -hda ${QEMU_IMAGE} -cpu kvm64 -cpu qemu64,+ssse3,+sse4.1,+sse4.2,+popcnt -vga virtio -device virtio-rng-pci -serial mon:stdio -serial null -device intel-hda -device hda-duplex -device virtio-net-pci,netdev=net0,mac=${RANDOM_MAC} -netdev user,id=net0,hostfwd=tcp::${CONTAINER_SSH_PORT}-:22,hostfwd=tcp::${FLUTTER_DEBUG_PORT}-:${FLUTTER_DEBUG_PORT}"
+ },
+ "arm64": {
+ "kernel": "Image-qemuarm64.bin",
+ "image": "agl-demo-platform-crosssdk-qemuarm64.ext4",
+ "args": "-accel hvf -cpu host -M virt ${QEMU_EXTRA} -m 4096 -device virtio-gpu-pci -nographic -display cocoa,show-cursor=on -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 -device qemu-xhci -device usb-tablet -device usb-mouse -device usb-kbd -device virtio-net-pci,netdev=vnet -netdev user,id=vnet,hostfwd=tcp::${CONTAINER_SSH_PORT}-:22,hostfwd=tcp::${FLUTTER_DEBUG_PORT}-:${FLUTTER_DEBUG_PORT} -kernel ${QEMU_KERNEL} -drive file=${QEMU_IMAGE},format=raw,if=virtio -append root=/dev/vda"
+ },
+ "extra": {
+ "darwin": "-smp cpus=8,sockets=1,cores=8,threads=1",
+ "ubuntu": "-bios OVMF.fd",
+ "fedora": "-bios /usr/share/edk2/ovmf/OVMF_CODE.fd"
+ }
+ },
+ "post_cmds": [
+ {
+ "cwd": "${PLATFORM_ID_DIR}",
+ "cmds": [
+ "bash -c \"rm ${QEMU_IMAGE}|true\"",
+ "unxz --keep ${QEMU_IMAGE}.xz"
+ ]
+ }
+ ]
+ },
+ "overwrite-existing": true,
+ "custom-device": {
+ "id": "agl-qemu-${RELEASE_NAME}",
+ "label": "AGL ${RELEASE_NAME}-${RELEASE_VERSION} QEMU Image",
+ "sdkNameAndVersion": "qemu-${RELEASE_NAME} ${RELEASE_VERSION}",
+ "platform": "linux-x64",
+ "enabled": true,
+ "ping": "bash -c \"${PING_CMD}\"",
+ "pingSuccessRegex": "open",
+ "postBuild": "bash -c \"${DELETE_USER_PWD}\"",
+ "install": "bash -c \"${CREATE_BUNDLE_FOLDER} && ${COPY_PLATFORM_ID_TO_DEVICE} && ${COPY_ASSETS_TO_DEVICE}\"",
+ "uninstall": "bash -c \"${DELETE_APP_FOLDER}\"",
+ "runDebug": "bash -c \"ssh -t -t -o BatchMode=yes agl-driver@${DEVICE_HOSTNAME} ${FLUTTER_AUTO_EXE}\"",
+ "forwardPort": null,
+ "forwardPortSuccessRegex": null,
+ "screenshot": null
+ }
+} \ No newline at end of file
diff --git a/meta-agl-flutter/tools/configs/agl-qemu-octopus.json b/meta-agl-flutter/tools/configs/agl-qemu-octopus.json
new file mode 100644
index 000000000..dba5a8820
--- /dev/null
+++ b/meta-agl-flutter/tools/configs/agl-qemu-octopus.json
@@ -0,0 +1,114 @@
+{
+ "id": "agl-qemu-octopus",
+ "load": true,
+ "supported_archs": [
+ "x86_64",
+ "arm64"
+ ],
+ "supported_host_types": [
+ "darwin",
+ "ubuntu",
+ "fedora"
+ ],
+ "flutter_runtime": "debug",
+ "type": "qemu",
+ "env": {
+ "RELEASE_NAME": "octopus",
+ "RELEASE_VERSION": "latest",
+ "FLUTTER_DEBUG_PORT": "1234",
+ "FLUTTER_OBSERVATORY_HOST": "0.0.0.0",
+ "CONTAINER_SSH_PORT": "2222",
+ "DEVICE_HOSTNAME": "localhost",
+ "FLUTTER_AUTO_EXE": "flutter-auto --j=/tmp/${appName}/default_config.json --b=/tmp/${appName}",
+ "PING_CMD": "(echo >/dev/tcp/localhost/${CONTAINER_SSH_PORT}) &>/dev/null && echo open || echo closed",
+ "DELETE_USER_PWD": "ssh -p ${CONTAINER_SSH_PORT} -t -oBatchMode=yes root@${DEVICE_HOSTNAME} passwd -d agl-driver",
+ "CREATE_BUNDLE_FOLDER": "ssh -p ${CONTAINER_SSH_PORT} -o BatchMode=yes agl-driver@${DEVICE_HOSTNAME} mkdir -p /tmp/${appName}/data",
+ "COPY_PLATFORM_ID_TO_DEVICE": "scp -P ${CONTAINER_SSH_PORT} -r ${PLATFORM_ID_DIR}/default_config.json agl-driver@${DEVICE_HOSTNAME}:/tmp/${appName}/",
+ "COPY_ASSETS_TO_DEVICE": "scp -P ${CONTAINER_SSH_PORT} -r ${localPath}/* agl-driver@${DEVICE_HOSTNAME}:/tmp/${appName}/data/flutter_assets",
+ "DELETE_APP_FOLDER": "ssh -p ${CONTAINER_SSH_PORT} -o BatchMode=yes agl-driver@${DEVICE_HOSTNAME} rm -rf /tmp/${appName}"
+ },
+ "runtime": {
+ "config": {
+ "view": [
+ {
+ "window_type": "BG",
+ "width": 1920,
+ "height": 1080
+ }
+ ]
+ },
+ "pre-requisites": {
+ "arm64": {
+ "darwin": {
+ "cmds": [
+ "bash -c \"arch -arm64 brew install xz\"",
+ "bash -c \"arch -arm64 brew install qemu\""
+ ]
+ }
+ }
+ },
+ "artifacts": {
+ "http": {
+ "url": "https://download.automotivelinux.org/AGL/release/${RELEASE_NAME}/${RELEASE_VERSION}",
+ "artifacts": {
+ "x86_64": [
+ {
+ "endpoint": "/qemux86-64/deploy/images/qemux86-64/agl-ivi-demo-platform-flutter-qemux86-64.wic.vmdk.xz"
+ }
+ ],
+ "arm64": [
+ {
+ "endpoint": "/qemuarm64/deploy/images/qemuarm64/agl-demo-platform-crosssdk-qemuarm64.ext4.xz"
+ },
+ {
+ "endpoint": "/qemuarm64/deploy/images/qemuarm64/Image-qemuarm64.bin"
+ }
+ ]
+ }
+ }
+ },
+ "qemu": {
+ "cmd": "qemu-system-${FORMAL_MACHINE_ARCH}",
+ "x86_64": {
+ "image": "agl-ivi-demo-platform-flutter-qemux86-64.wic.vmdk",
+ "args": "-m 2048 ${QEMU_EXTRA} -hda ${QEMU_IMAGE} -cpu kvm64 -cpu qemu64,+ssse3,+sse4.1,+sse4.2,+popcnt -vga virtio -device virtio-rng-pci -serial mon:stdio -serial null -device intel-hda -device hda-duplex -device virtio-net-pci,netdev=net0,mac=${RANDOM_MAC} -netdev user,id=net0,hostfwd=tcp::${CONTAINER_SSH_PORT}-:22,hostfwd=tcp::${FLUTTER_DEBUG_PORT}-:${FLUTTER_DEBUG_PORT}"
+ },
+ "arm64": {
+ "kernel": "Image-qemuarm64.bin",
+ "image": "agl-demo-platform-crosssdk-qemuarm64.ext4",
+ "args": "-accel hvf -cpu host -M virt ${QEMU_EXTRA} -m 4096 -device virtio-gpu-pci -nographic -display cocoa,show-cursor=on -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 -device qemu-xhci -device usb-tablet -device usb-mouse -device usb-kbd -device virtio-net-pci,netdev=vnet -netdev user,id=vnet,hostfwd=tcp::${CONTAINER_SSH_PORT}-:22,hostfwd=tcp::${FLUTTER_DEBUG_PORT}-:${FLUTTER_DEBUG_PORT} -kernel ${QEMU_KERNEL} -drive file=${QEMU_IMAGE},format=raw,if=virtio -append root=/dev/vda"
+ },
+ "extra": {
+ "darwin": "-smp cpus=8,sockets=1,cores=8,threads=1",
+ "ubuntu": "-bios OVMF.fd",
+ "fedora": "-bios /usr/share/edk2/ovmf/OVMF_CODE.fd"
+ }
+ },
+ "post_cmds": [
+ {
+ "cwd": "${PLATFORM_ID_DIR}",
+ "cmds": [
+ "bash -c \"rm ${QEMU_IMAGE}|true\"",
+ "unxz --keep ${QEMU_IMAGE}.xz"
+ ]
+ }
+ ]
+ },
+ "overwrite-existing": true,
+ "custom-device": {
+ "id": "agl-qemu-${RELEASE_NAME}",
+ "label": "AGL ${RELEASE_NAME}-${RELEASE_VERSION} QEMU Image",
+ "sdkNameAndVersion": "qemu-${RELEASE_NAME} ${RELEASE_VERSION}",
+ "platform": "linux-x64",
+ "enabled": true,
+ "ping": "bash -c \"${PING_CMD}\"",
+ "pingSuccessRegex": "open",
+ "postBuild": "bash -c \"${DELETE_USER_PWD}\"",
+ "install": "bash -c \"${CREATE_BUNDLE_FOLDER} && ${COPY_PLATFORM_ID_TO_DEVICE} && ${COPY_ASSETS_TO_DEVICE}\"",
+ "uninstall": "bash -c \"${DELETE_APP_FOLDER}\"",
+ "runDebug": "bash -c \"ssh -t -t -o BatchMode=yes agl-driver@${DEVICE_HOSTNAME} ${FLUTTER_AUTO_EXE}\"",
+ "forwardPort": null,
+ "forwardPortSuccessRegex": null,
+ "screenshot": null
+ }
+} \ No newline at end of file
diff --git a/meta-agl-flutter/tools/configs/desktop-auto.json b/meta-agl-flutter/tools/configs/desktop-auto.json
new file mode 100644
index 000000000..cb3b9e688
--- /dev/null
+++ b/meta-agl-flutter/tools/configs/desktop-auto.json
@@ -0,0 +1,92 @@
+{
+ "id": "desktop-auto",
+ "load": true,
+ "supported_archs": [
+ "x86_64"
+ ],
+ "supported_host_types": [
+ "ubuntu",
+ "fedora"
+ ],
+ "flutter_runtime": "debug",
+ "type": "host",
+ "env": {
+ "HOMESCREEN_SRC_DIR": "${FLUTTER_WORKSPACE}/app/ivi-homescreen",
+ "HOMESCREEN_BUILD_DIR": "${FLUTTER_WORKSPACE}/app/ivi-homescreen/build",
+ "HOMESCREEN_CMAKE_ARGS": "-DCMAKE_BUILD_TYPE=Debug -DENABLE_DLT=OFF",
+ "HOMESCREEN_EXE": "${HOMESCREEN_BUILD_DIR}/shell/homescreen --j=${PLATFORM_ID_DIR_RELATIVE}/default_config.json --b=${PLATFORM_ID_DIR_RELATIVE}",
+ "PING_CMD": "loginctl show-session $(awk '/tty/ {print $1}' <(loginctl)) -p Type",
+ "CREATE_BUNDLE_FOLDER": "mkdir -p ${PLATFORM_ID_DIR_RELATIVE}/data",
+ "COPY_PLATFORM_ID_TO_BUNDLE_FOLDER": "cp -r ${PLATFORM_ID_DIR}/default_config.json ${PLATFORM_ID_DIR_RELATIVE}/",
+ "COPY_BUNDLE_FOLDER_TO_PLATOFRM_ID": "cp -r ${BUNDLE_FOLDER}/* ${PLATFORM_ID_DIR_RELATIVE}/",
+ "CREATE_ASSET_SYMLINK": "ln -rsf build/flutter_assets ${PLATFORM_ID_DIR_RELATIVE}/data/flutter_assets",
+ "STAGE_BUNDLE_FOLDER": "${CREATE_BUNDLE_FOLDER} && ${COPY_PLATFORM_ID_TO_BUNDLE_FOLDER} && ${COPY_BUNDLE_FOLDER_TO_PLATOFRM_ID} && ${CREATE_ASSET_SYMLINK}"
+ },
+ "runtime": {
+ "config": {
+ "view": [
+ {
+ "width": 1920,
+ "height": 1080,
+ "cursor_theme": "DMZ-White",
+ "fullscreen": false
+ }
+ ]
+ },
+ "pre-requisites": {
+ "x86_64": {
+ "ubuntu": {
+ "cmds": [
+ "sudo snap install cmake --classic",
+ "sudo add-apt-repository -y ppa:kisak/kisak-mesa",
+ "sudo apt update -y",
+ "sudo apt install lsb-release wget software-properties-common gnupg apt-file",
+ "sudo apt-file update",
+ "sudo apt install -y libwayland-dev wayland-protocols mesa-common-dev libegl1-mesa-dev libgles2-mesa-dev mesa-utils libxkbcommon-dev ninja-build",
+ "sudo apt install -y build-essential libvulkan-dev vulkan-tools vulkan-validationlayers vulkan-utils libtool",
+ "sudo apt autoremove -y",
+ "sudo apt clean -y",
+ "cmake --version",
+ "apt-file search cmake"
+ ]
+ },
+ "fedora": {
+ "cmds": [
+ "sudo dnf -y update",
+ "sudo dnf -y upgrade",
+ "sudo dnf -y install wayland-devel wayland-protocols-devel libxkbcommon-devel cmake ninja-build mesa-dri-drivers mesa-filesystem mesa-libEGL-devel mesa-libGL-devel mesa-libGLU-devel mesa-libgbm-devel mesa-libglapi mesa-libxatracker mesa-vulkan-drivers vulkan-tools libunwind-devel gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugins-bad-free-devel gstreamer1-plugins-bad-free-extras gstreamer1-plugins-base-tools gstreamer1-plugins-good gstreamer1-plugins-good-extras gstreamer1-plugins-ugly-free libtool",
+ "sudo dnf -y autoremove",
+ "cmake --version",
+ "dnf provides cmake"
+ ]
+ }
+ }
+ },
+ "post_cmds": [
+ {
+ "cwd": "${HOMESCREEN_BUILD_DIR}",
+ "cmds": [
+ "cmake ${HOMESCREEN_SRC_DIR} ${HOMESCREEN_CMAKE_ARGS}",
+ "make homescreen -j"
+ ]
+ }
+ ]
+ },
+ "overwrite-existing": true,
+ "custom-device": {
+ "id": "desktop-auto",
+ "label": "Toyota Homescreen for AGL",
+ "sdkNameAndVersion": "flutter-auto x86_64",
+ "platform": "linux-x64",
+ "enabled": true,
+ "ping": "bash -c \"${PING_CMD}\"",
+ "pingSuccessRegex": "Type=wayland",
+ "postBuild": "bash -c \"rm -rf ${PLATFORM_ID_DIR_RELATIVE}\"",
+ "install": "bash -c \"${STAGE_BUNDLE_FOLDER}\"",
+ "uninstall": "bash -c \"rm -rf ${PLATFORM_ID_DIR_RELATIVE}\"",
+ "runDebug": "bash -c \"${HOMESCREEN_EXE}\"",
+ "forwardPort": null,
+ "forwardPortSuccessRegex": null,
+ "screenshot": null
+ }
+} \ No newline at end of file
diff --git a/meta-agl-flutter/tools/flutter_workspace.py b/meta-agl-flutter/tools/flutter_workspace.py
new file mode 120000
index 000000000..faacf59eb
--- /dev/null
+++ b/meta-agl-flutter/tools/flutter_workspace.py
@@ -0,0 +1 @@
+external/workspace-automation/flutter_workspace.py \ No newline at end of file