diff options
| author | unitexe <unitexe70@gmail.com> | 2026-02-06 09:09:11 -0600 |
|---|---|---|
| committer | unitexe <unitexe70@gmail.com> | 2026-02-07 21:39:05 -0600 |
| commit | e9ef477e623a397c3cae8e1e2d676046069cbb01 (patch) | |
| tree | af57d5d245aa30e38013a05d50ddd1302f3ccd2f | |
| parent | 5c293149dbbf6e304a6934945cd602c43ab58c9e (diff) | |
Boot to flutter app using ivi-homescreen embedder
- Introduce meta-unit-graphics layer
- Flutter app is run under the kiosk user
- Added weston.ini specific to raspberrypi3-64 LCD screen
- Move linger class to meta-unit-users layer so it can be used by meta-unit-graphics and meta-unit-core
- Update svc and unitexe user UIDs so they dont clash with the weston user
20 files changed, 220 insertions, 3 deletions
diff --git a/meta-unit-core/conf/layer.conf b/meta-unit-core/conf/layer.conf index 64e7d24..7f6e371 100644 --- a/meta-unit-core/conf/layer.conf +++ b/meta-unit-core/conf/layer.conf @@ -4,7 +4,9 @@ BBFILES += "${LAYERDIR}/recipes*/*/*.bb ${LAYERDIR}/recipes*/*/*.bbappend" BBFILE_COLLECTIONS += "unit-core" BBFILE_PATTERN_unit-core := "^${LAYERDIR}/" -BBFILE_PRIORITY_unit-core = "13" +BBFILE_PRIORITY_unit-core = "14" + +LAYERDEPENDS_unit-distro = "core yocto unit-users-layer" LAYERSERIES_COMPAT_unit-core = "whinlatter" @@ -17,6 +19,8 @@ BBFILES_DYNAMIC += " \ unit-profiling-layer:${LAYERDIR}/dynamic-layers/unit-profiling-layer/recipes-*/*/*.bbappend \ raspberrypi:${LAYERDIR}/dynamic-layers/raspberrypi/recipes-*/*/*.bb \ raspberrypi:${LAYERDIR}/dynamic-layers/raspberrypi/recipes-*/*/*.bbappend \ + unit-graphics-layer:${LAYERDIR}/dynamic-layers/unit-graphics-layer/recipes-*/*/*.bb \ + unit-graphics-layer:${LAYERDIR}/dynamic-layers/unit-graphics-layer/recipes-*/*/*.bbappend \ " UNIT_CORE_LAYERDIR = "${LAYERDIR}" diff --git a/meta-unit-core/dynamic-layers/unit-graphics-layer/recipes-unit/images/core-image-unit.bbappend b/meta-unit-core/dynamic-layers/unit-graphics-layer/recipes-unit/images/core-image-unit.bbappend new file mode 100644 index 0000000..379ddca --- /dev/null +++ b/meta-unit-core/dynamic-layers/unit-graphics-layer/recipes-unit/images/core-image-unit.bbappend @@ -0,0 +1,5 @@ +inherit fix-kiosk-home-dir-ownership + +IMAGE_FEATURES:append = " hwcodecs" + +IMAGE_INSTALL:append = " packagegroup-unit-kiosk" diff --git a/meta-unit-core/recipes-users/useradd/add-user-svc.bb b/meta-unit-core/recipes-users/useradd/add-user-svc.bb index ee534c5..a1d44fa 100644 --- a/meta-unit-core/recipes-users/useradd/add-user-svc.bb +++ b/meta-unit-core/recipes-users/useradd/add-user-svc.bb @@ -14,7 +14,7 @@ RDEPENDS:${PN}:append = " systemd" USERADD_PACKAGES = "${PN}" USER_TO_ADD_NAME ?= "svc" -USER_TO_ADD_UID ?= "2000" +USER_TO_ADD_UID ?= "50556" USER_TO_ADD_PASSWORD_HASHED ?= "\$6\$1TQs7iLskyTyCjoL\$xhngcFWaPRsoaZCwLSsYXUrRcVdR19zV2vBEzrzSEVu8zbqDlfKu4HLwzsZfiqJCiWqiu9qirD4Ym12CMf7D7." COMMA_SEPARATED_LIST_OF_GROUPS_TO_ADD_USER_TO ?= "systemd-journal" diff --git a/meta-unit-core/recipes-users/useradd/add-user-unitexe.bb b/meta-unit-core/recipes-users/useradd/add-user-unitexe.bb index 527af74..5af066d 100644 --- a/meta-unit-core/recipes-users/useradd/add-user-unitexe.bb +++ b/meta-unit-core/recipes-users/useradd/add-user-unitexe.bb @@ -16,7 +16,7 @@ RDEPENDS:${PN}:append = " systemd" USERADD_PACKAGES = "${PN}" USER_TO_ADD_NAME ?= "unitexe" -USER_TO_ADD_UID ?= "1000" +USER_TO_ADD_UID ?= "50555" USER_TO_ADD_PASSWORD_HASHED ?= "\$6\$esHchcEKubkj/1v7\$woeV0ChUqcC8J8lOEWB563mX4XRAvYJldGcU/I0Pzg1Nw9bBGOQoLmIsn0wU1gUzpysZr6R18xps5Cjn470Nv/" COMMA_SEPARATED_LIST_OF_GROUPS_TO_ADD_USER_TO ?= "systemd-journal" diff --git a/meta-unit-graphics/LICENSE b/meta-unit-graphics/LICENSE new file mode 100644 index 0000000..52686ad --- /dev/null +++ b/meta-unit-graphics/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Closed Circuit Consulting + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
\ No newline at end of file diff --git a/meta-unit-graphics/classes/fix-kiosk-home-dir-ownership.bbclass b/meta-unit-graphics/classes/fix-kiosk-home-dir-ownership.bbclass new file mode 100644 index 0000000..f556b5c --- /dev/null +++ b/meta-unit-graphics/classes/fix-kiosk-home-dir-ownership.bbclass @@ -0,0 +1,5 @@ +ROOTFS_POSTPROCESS_COMMAND:append = " fix_kiosk_user_home_directory_ownership;" + +fix_kiosk_user_home_directory_ownership() { + chown -R kiosk:kiosk ${IMAGE_ROOTFS}/home/kiosk +} diff --git a/meta-unit-graphics/conf/layer.conf b/meta-unit-graphics/conf/layer.conf new file mode 100644 index 0000000..b87c882 --- /dev/null +++ b/meta-unit-graphics/conf/layer.conf @@ -0,0 +1,18 @@ +BBPATH .= ":${LAYERDIR}" + +BBFILES += "${LAYERDIR}/recipes*/*/*.bb ${LAYERDIR}/recipes*/*/*.bbappend" + +BBFILE_COLLECTIONS += "unit-graphics-layer" +BBFILE_PATTERN_unit-graphics-layer := "^${LAYERDIR}/" +BBFILE_PRIORITY_unit-graphics-layer = "13" + +LAYERDEPENDS_unit-distro = "core yocto unit-users-layer" + +LAYERSERIES_COMPAT_unit-graphics-layer = "whinlatter" + +BBFILES_DYNAMIC += " \ + flutter-layer:${LAYERDIR}/dynamic-layers/flutter-layer/recipes-*/*/*.bb \ + flutter-layer:${LAYERDIR}/dynamic-layers/flutter-layer/recipes-*/*/*.bbappend \ +" + +UNIT_GRAPHICS_LAYERDIR = "${LAYERDIR}" diff --git a/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-core/systemd/systemd-flutter-kiosk.bb b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-core/systemd/systemd-flutter-kiosk.bb new file mode 100644 index 0000000..9aa8d71 --- /dev/null +++ b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-core/systemd/systemd-flutter-kiosk.bb @@ -0,0 +1,37 @@ +SUMMARY = "Systemd service for launching kiosk application" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${UNIT_GRAPHICS_LAYERDIR}/LICENSE;md5=a77c12e0c0e8a14cebb1494195720ccc" + +inherit systemd + +require conf/include/flutter-version.inc + +SRC_URI = "file://kiosk.service" + +RDEPENDS:${PN}:append = " flutter-sample-no-material" +RDEPENDS:${PN}:append = " ivi-homescreen" +RDEPENDS:${PN}:append = " weston" +RDEPENDS:${PN}:append = " weston-init" +RDEPENDS:${PN}:append = " add-user-kiosk" + +S = "${UNPACKDIR}" + +SYSTEMD_USER = "kiosk" +SYSTEMD_USER_UNITDIR = "/home/${SYSTEMD_USER}/.config/systemd/user" + +do_install() { + install -D -p -m0644 ${S}/kiosk.service ${D}${SYSTEMD_USER_UNITDIR}/kiosk.service + + # Variable substitution. + sed -i 's|@@FLUTTER_SDK_TAG@@|${FLUTTER_SDK_TAG}|g' ${D}${SYSTEMD_USER_UNITDIR}/kiosk.service + sed -i 's|@@KIOSK_APPLICATION_NAME@@|flutter_sample_no_material|g' ${D}${SYSTEMD_USER_UNITDIR}/kiosk.service + + # Auto-enable systemd unit by creating the appropriate symlink + install -d ${D}${SYSTEMD_USER_UNITDIR}/default.target.wants + ln -sf ${SYSTEMD_USER_UNITDIR}/kiosk.service ${D}${SYSTEMD_USER_UNITDIR}/default.target.wants/kiosk.service +} + +FILES:${PN} = "\ + ${SYSTEMD_USER_UNITDIR}/kiosk.service \ + ${SYSTEMD_USER_UNITDIR}/default.target.wants/kiosk.service \ +" diff --git a/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-core/systemd/systemd-flutter-kiosk/kiosk.service b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-core/systemd/systemd-flutter-kiosk/kiosk.service new file mode 100644 index 0000000..3534eed --- /dev/null +++ b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-core/systemd/systemd-flutter-kiosk/kiosk.service @@ -0,0 +1,15 @@ +[Unit] +Description=Kiosk Application + +[Service] +Type=simple +Environment="WAYLAND_DISPLAY=/run/wayland-0" +ExecStart=/usr/bin/homescreen --bundle /usr/share/flutter/@@KIOSK_APPLICATION_NAME@@/@@FLUTTER_SDK_TAG@@/release/ --fullscreen +Restart=on-failure +RestartSec=2s +RestartSteps=5 +RestartMaxDelaySec=10s +TimeoutStartSec=15min + +[Install] +WantedBy=graphical.target diff --git a/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-graphics/flutter-apps/flutter-sample-no-material.bb b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-graphics/flutter-apps/flutter-sample-no-material.bb new file mode 100644 index 0000000..403786b --- /dev/null +++ b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-graphics/flutter-apps/flutter-sample-no-material.bb @@ -0,0 +1,17 @@ +SUMMARY = "flutter_sample_no_material" +DESCRIPTION = "A sample that shows a Flutter app without material widgets." +AUTHOR = "unitexe" +HOMEPAGE = "https://github.com/unitexe/flutter_sample_no_material" +BUGTRACKER = "None" +SECTION = "graphics" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=38bf13be5d6979b28bd8adddb2f2f9b3" + +SRCREV = "e34c7c4ca151d6ca5282176cdbbe8f9d1844c9ae" +SRC_URI = "git://git.closedcircuitconsulting.com/flutter_sample_no_material;branch=main;protocol=https" + +PUBSPEC_APPNAME = "flutter_sample_no_material" +PUBSPEC_IGNORE_LOCKFILE = "1" + +inherit flutter-app diff --git a/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-graphics/packagegroups/packagegroup-unit-kiosk.bb b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-graphics/packagegroups/packagegroup-unit-kiosk.bb new file mode 100644 index 0000000..cbacc24 --- /dev/null +++ b/meta-unit-graphics/dynamic-layers/flutter-layer/recipes-graphics/packagegroups/packagegroup-unit-kiosk.bb @@ -0,0 +1,7 @@ +SUMMARY = "Unit kiosk" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +inherit packagegroup + +RDEPENDS:${PN}:append = " systemd-flutter-kiosk" diff --git a/meta-unit-graphics/recipes-graphics/wayland/weston-init.bbappend b/meta-unit-graphics/recipes-graphics/wayland/weston-init.bbappend new file mode 100644 index 0000000..4fc41d0 --- /dev/null +++ b/meta-unit-graphics/recipes-graphics/wayland/weston-init.bbappend @@ -0,0 +1 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" diff --git a/meta-unit-graphics/recipes-graphics/wayland/weston-init/raspberrypi3-64/weston.ini b/meta-unit-graphics/recipes-graphics/wayland/weston-init/raspberrypi3-64/weston.ini new file mode 100644 index 0000000..6866595 --- /dev/null +++ b/meta-unit-graphics/recipes-graphics/wayland/weston-init/raspberrypi3-64/weston.ini @@ -0,0 +1,6 @@ +[core] +require-input=false + +[output] +name=DSI-1 +mode=current diff --git a/meta-unit-graphics/recipes-users/useradd/add-user-kiosk.bb b/meta-unit-graphics/recipes-users/useradd/add-user-kiosk.bb new file mode 100644 index 0000000..b18f9ce --- /dev/null +++ b/meta-unit-graphics/recipes-users/useradd/add-user-kiosk.bb @@ -0,0 +1,38 @@ +SUMMARY = "Add kiosk user" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${UNIT_GRAPHICS_LAYERDIR}/LICENSE;md5=a77c12e0c0e8a14cebb1494195720ccc" + +EXCLUDE_FROM_WORLD = "1" + +inherit useradd +inherit extrausers +inherit enable-linger + +RDEPENDS:${PN}:append = " systemd" +RDEPENDS:${PN}:append = " weston-init" + +SRC_URI = "file://.profile" + +USERADD_PACKAGES = "${PN}" +USER_TO_ADD_NAME ?= "kiosk" +USER_TO_ADD_UID ?= "50557" +USER_TO_ADD_PASSWORD_HASHED ?= "\$6\$oD8hxDdrL3h.n..p\$j2LvVlUqokdmPQGDQLKgy3oA5qg.l7Sy4cV4m6zrMu8A8Yc8WJD8Kn9BgYC.Y5iZiAEbMdpUyiuFCCo7Whvgq0" +COMMA_SEPARATED_LIST_OF_GROUPS_TO_ADD_USER_TO ?= "systemd-journal,video,input,render,seat,wayland" + +USERADD_PARAM:${PN} = "-u ${USER_TO_ADD_UID} -U -d /home/${USER_TO_ADD_NAME} -s ${base_bindir}/sh -G ${COMMA_SEPARATED_LIST_OF_GROUPS_TO_ADD_USER_TO} -p '${USER_TO_ADD_PASSWORD_HASHED}' ${USER_TO_ADD_NAME}" + +INHIBIT_PACKAGE_DEBUG_SPLIT = "1" + +S = "${UNPACKDIR}" + +do_install() { + install -D -m 0644 ${S}/.profile ${D}/home/${USER_TO_ADD_NAME}/.profile +} + +# Prior to useradd being performed on the sysroot a couple things must happen: +# 1. Need the systemd recipe to create the systemd-journal group +# 2. Need busybox shell present +# 3. Need the weston-init recipe to create the video,input,render and seat groups +do_prepare_recipe_sysroot[depends] += "systemd:do_populate_sysroot busybox:do_populate_sysroot weston-init:do_populate_sysroot" + +FILES:${PN} = "/home/${USER_TO_ADD_NAME}/.profile" diff --git a/meta-unit-graphics/recipes-users/useradd/add-user-kiosk/.profile b/meta-unit-graphics/recipes-users/useradd/add-user-kiosk/.profile new file mode 100644 index 0000000..8957ce2 --- /dev/null +++ b/meta-unit-graphics/recipes-users/useradd/add-user-kiosk/.profile @@ -0,0 +1,3 @@ +# User is not part of sudo group and therefore doesn't +# have sbin in path, add it for access to common commands. +export PATH="${sbindir}:/sbin:$PATH" diff --git a/meta-unit-kas/images/unit-poky/raspberrypi3-64/core-image-unit/whinlatter.yml b/meta-unit-kas/images/unit-poky/raspberrypi3-64/core-image-unit/whinlatter.yml index 67057a2..349fe75 100644 --- a/meta-unit-kas/images/unit-poky/raspberrypi3-64/core-image-unit/whinlatter.yml +++ b/meta-unit-kas/images/unit-poky/raspberrypi3-64/core-image-unit/whinlatter.yml @@ -15,6 +15,8 @@ header: - meta-unit-kas/include/layers/meta-openembedded/whinlatter.yml - meta-unit-kas/include/layers/meta-virtualization/remote.yml - meta-unit-kas/include/layers/meta-virtualization/main.yml + - meta-unit-kas/include/layers/meta-flutter/remote.yml + - meta-unit-kas/include/layers/meta-flutter/main.yml - meta-unit-kas/include/layers/meta-unit-core/core-image-unit.yml - meta-unit-kas/include/layers/meta-unit-distro/unit-poky.yml @@ -25,10 +27,16 @@ repos: meta-oe: meta-networking: meta-python: + meta-flutter: + layers: + .: + meta-flutter-apps: meta-unit: layers: meta-raspberrypi-extra: meta-unit-core: meta-unit-distro: + meta-unit-graphics: meta-unit-profiling: + meta-unit-users: meta-virtualization-extra: diff --git a/meta-unit-kas/include/layers/meta-flutter/main.yml b/meta-unit-kas/include/layers/meta-flutter/main.yml new file mode 100644 index 0000000..bea15ce --- /dev/null +++ b/meta-unit-kas/include/layers/meta-flutter/main.yml @@ -0,0 +1,7 @@ +header: + version: 20 + +repos: + meta-flutter: + branch: master + commit: 3383163ea5aec1c59268440095ccf3c0a32d8ff3 diff --git a/meta-unit-kas/include/layers/meta-flutter/remote.yml b/meta-unit-kas/include/layers/meta-flutter/remote.yml new file mode 100644 index 0000000..3a84248 --- /dev/null +++ b/meta-unit-kas/include/layers/meta-flutter/remote.yml @@ -0,0 +1,7 @@ +header: + version: 20 + +repos: + meta-flutter: + url: https://github.com/meta-flutter/meta-flutter + path: layers/meta-flutter diff --git a/meta-unit-users/classes/enable-linger.bbclass b/meta-unit-users/classes/enable-linger.bbclass new file mode 100644 index 0000000..e464b9e --- /dev/null +++ b/meta-unit-users/classes/enable-linger.bbclass @@ -0,0 +1,9 @@ +do_install:append() { + # Enabling linger does two effects for systemd user units: + # 1. Units are automatically started after a reboot + # 2. Units are not automatically stopped after a log out + install -d ${D}${localstatedir}/lib/systemd/linger + touch ${D}${localstatedir}/lib/systemd/linger/${USER_TO_ADD_NAME} +} + +FILES:${PN}:append = " ${localstatedir}/lib/systemd/linger/${USER_TO_ADD_NAME}" diff --git a/meta-unit-users/conf/layer.conf b/meta-unit-users/conf/layer.conf new file mode 100644 index 0000000..59919c8 --- /dev/null +++ b/meta-unit-users/conf/layer.conf @@ -0,0 +1,9 @@ +BBPATH .= ":${LAYERDIR}" + +BBFILE_COLLECTIONS += "unit-users-layer" +BBFILE_PATTERN_unit-users-layer := "^${LAYERDIR}/" +BBFILE_PRIORITY_unit-users-layer = "6" + +LAYERDEPENDS_unit-users-layer = "core" + +LAYERSERIES_COMPAT_unit-users-layer = "whinlatter" |
