diff --git a/Dockerfile.agnos b/Dockerfile.agnos
index f9bc67d..64914f6 100644
--- a/Dockerfile.agnos
+++ b/Dockerfile.agnos
@@ -51,6 +51,14 @@ COPY ./userspace/compile-lpac.sh /tmp/agnos/
RUN --mount=type=cache,target=/root/.ccache,id=lpac,sharing=shared \
/tmp/agnos/compile-lpac.sh
+# qtwayland5
+FROM agnos-compiler AS agnos-compiler-qtwayland5
+COPY ./userspace/qtwayland/*.deb /tmp/agnos/
+COPY ./userspace/compile-qtwayland5.sh /tmp/agnos/
+COPY ./userspace/qtwayland/patch* /tmp/agnos/
+RUN --mount=type=cache,target=/root/.ccache,id=qtwayland5,sharing=shared \
+ /tmp/agnos/compile-qtwayland5.sh
+
# ################## #
# ###### Base ###### #
# ################## #
@@ -79,6 +87,15 @@ RUN /tmp/agnos/openpilot_dependencies.sh
COPY ./userspace/openpilot_python_dependencies.sh /tmp/agnos/
RUN /tmp/agnos/openpilot_python_dependencies.sh
+# Install old Qt 5.12.8, libwayland 1.9.0-1 and deps
+COPY ./userspace/qtwayland/*.deb /tmp/agnos/
+RUN apt-get -o Dpkg::Options::="--force-overwrite" install -yq \
+ /tmp/agnos/qt-5.12.8.deb \
+ /tmp/agnos/libwayland-1.9.0-1.deb \
+ /tmp/agnos/libicu66_66.1-2ubuntu2.1_arm64.deb \
+ /tmp/agnos/libssl1.1_1.1.1f-1ubuntu2.22_arm64.deb \
+ /tmp/agnos/libffi6_3.2.1-8_arm64.deb
+
# ################### #
# ###### AGNOS ###### #
# ################### #
@@ -136,6 +153,12 @@ RUN source $XDG_DATA_HOME/venv/bin/activate && \
COPY ./userspace/install_extras.sh /tmp/agnos/
RUN /tmp/agnos/install_extras.sh
+COPY --from=agnos-compiler-qtwayland5 /tmp/qtwayland5.deb /tmp/qtwayland5.deb
+RUN cd /tmp && apt-get -o Dpkg::Options::="--force-overwrite" install -yq --allow-downgrades ./qtwayland5.deb
+
+# Patched libeglSubDriverWayland with fixed nullptr deref in CommitBuffer
+COPY ./userspace/files/libeglSubDriverWayland.so.patched /lib/aarch64-linux-gnu/libeglSubDriverWayland.so
+
COPY ./userspace/home/ /home/$USERNAME/
COPY ./userspace/home/.config/ /root/.config
RUN chown -R $USERNAME: /home/$USERNAME/.config
@@ -171,6 +194,10 @@ COPY ./userspace/libs32/* /usr/lib/arm-linux-gnueabihf/
#COPY ./userspace/files/linux-headers-4.9.103+_4.9.103+-1_arm64.deb /tmp/
#RUN dpkg -i /tmp/linux-headers-4.9.103+_4.9.103+-1_arm64.deb
+# Weston with hacked touch rotate and color correction
+COPY ./userspace/files/weston /usr/bin/weston
+COPY ./userspace/files/gl-renderer.so /usr/lib/arm-linux-gnueabihf/weston
+
# Setup systemd services
COPY ./userspace/services.sh /tmp/agnos
RUN /tmp/agnos/services.sh
@@ -199,6 +226,9 @@ COPY ./userspace/files/avahi-override.conf /etc/systemd/system/avahi-daemon.serv
# Prevent polkitd memory leak from getting out of hand by restarting it every ~day
COPY ./userspace/files/polkit-override.conf /etc/systemd/system/polkit.service.d/override.conf
+# Remove qt network bearer plugins
+RUN rm -rf /usr/lib/aarch64-linux-gnu/qt5/plugins/bearer
+
# Add iptable rules to block incoming traffic on wwan0
COPY ./userspace/etc/iptables/rules.v4 /etc/iptables/rules.v4
diff --git a/README.md b/README.md
index f3fa579..31ffd95 100644
--- a/README.md
+++ b/README.md
@@ -87,4 +87,4 @@ Some concrete things on the roadmap:
- [ ] mainline Linux kernel https://github.com/commaai/openpilot/issues/32386
- [ ] fully open source
- [ ] anything from `firmware/`: XBL, ABL, etc.
- - [x] Weston https://github.com/commaai/agnos-builder/issues/16 deleted!
+ - [ ] Weston https://github.com/commaai/agnos-builder/issues/16
diff --git a/userspace/.gitattributes b/userspace/.gitattributes
index ee2edf9..7db9ea4 100644
--- a/userspace/.gitattributes
+++ b/userspace/.gitattributes
@@ -1,5 +1,7 @@
usr/comma/wlan.ko filter=lfs diff=lfs merge=lfs -text
usr/comma/wifi filter=lfs diff=lfs merge=lfs -text
+files/weston filter=lfs diff=lfs merge=lfs -text
+files/libeglSubDriverWayland.so.patched filter=lfs diff=lfs merge=lfs -text
usr/comma/reset filter=lfs diff=lfs merge=lfs -text
usr/comma/setup filter=lfs diff=lfs merge=lfs -text
usr/comma/installer filter=lfs diff=lfs merge=lfs -text
diff --git a/userspace/compile-qtwayland5.sh b/userspace/compile-qtwayland5.sh
new file mode 100755
index 0000000..6d5c930
--- /dev/null
+++ b/userspace/compile-qtwayland5.sh
@@ -0,0 +1,63 @@
+#!/bin/bash -e
+
+VERSION=5.12.9
+
+# Install build requirements
+dpkg --add-architecture armhf
+
+apt-get update && apt-get install -yq --no-install-recommends \
+ libc6:armhf \
+ libdbus-1-3 \
+ libegl-dev \
+ libexpat1:armhf \
+ libfontconfig-dev \
+ libfreetype6 \
+ libgles-dev \
+ libglib2.0-dev \
+ libharfbuzz-dev \
+ libpcre2-dev \
+ libwayland-dev \
+ libxcomposite-dev \
+ libxkbcommon-dev \
+ zlib1g-dev
+
+apt-get -o Dpkg::Options::="--force-overwrite" install -yq \
+ /tmp/agnos/qt-5.12.8.deb \
+ /tmp/agnos/libwayland-1.9.0-1.deb \
+ /tmp/agnos/libicu66_66.1-2ubuntu2.1_arm64.deb \
+ /tmp/agnos/libssl1.1_1.1.1f-1ubuntu2.22_arm64.deb \
+ /tmp/agnos/libffi6_3.2.1-8_arm64.deb
+
+# Patched qtwayland that outputs a fixed screen size
+# Clone qtwayland submodule, checkout, apply patch, qmake, make
+cd /tmp
+git clone --branch v${VERSION} --depth 1 https://github.com/qt/qtwayland.git
+cd qtwayland
+
+git apply /tmp/agnos/patch-qtwayland-v5.12
+
+# qtwayland is incorrectly built against libdl.so instead of libdl.so.2
+# https://stackoverflow.com/a/75855054/639708
+ln -s libdl.so.2 /usr/lib/aarch64-linux-gnu/libdl.so
+
+qmake
+export MAKEFLAGS="-j$(nproc)"
+make
+
+OUTPUT_DIR=/tmp/qtwayland5
+mkdir $OUTPUT_DIR
+make install INSTALL_ROOT=$OUTPUT_DIR
+
+mkdir $OUTPUT_DIR/DEBIAN
+cat << EOF > $OUTPUT_DIR/DEBIAN/control
+Package: qtwayland5
+Version: ${VERSION}-1
+Architecture: all
+Maintainer: Andrei Radulescu
+Replaces: qtwayland5, libqt5waylandclient5, libqt5waylandcompositor5
+Installed-Size: `du -s $OUTPUT_DIR | awk '{print $1}'`
+Homepage: https://comma.ai
+Description: Patched qtwayland that outputs a fixed screen size
+EOF
+
+dpkg-deb --root-owner-group --build $OUTPUT_DIR /tmp/qtwayland5.deb
diff --git a/userspace/files/agnos-tests.service b/userspace/files/agnos-tests.service
index e925dec..5b26bf4 100644
--- a/userspace/files/agnos-tests.service
+++ b/userspace/files/agnos-tests.service
@@ -1,5 +1,5 @@
[Unit]
-#After=
+#After=weston-ready.service
[Service]
#Type=simple
@@ -10,6 +10,7 @@ Restart=no
# exit if connected to 5V
ExecStartPre=/bin/bash -c "if [ $(cat /sys/class/hwmon/hwmon1/in1_input) -le 6500 ]; then echo 'Exiting, connected to 5V'; exit 1; fi"
+#ExecStart=/bin/bash -c "source /etc/profile && /usr/comma/tests/test_weston.py"
ExecStart=/bin/bash -c "source /etc/profile && /usr/comma/tests/test_sounds.py"
[Install]
diff --git a/userspace/files/gl-renderer.so b/userspace/files/gl-renderer.so
new file mode 100755
index 0000000..8de34bb
Binary files /dev/null and b/userspace/files/gl-renderer.so differ
diff --git a/userspace/files/libeglSubDriverWayland.so.patched b/userspace/files/libeglSubDriverWayland.so.patched
new file mode 100644
index 0000000..cd9fbe6
--- /dev/null
+++ b/userspace/files/libeglSubDriverWayland.so.patched
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:34b01105549bba97710ded5916a24a318d4b7dbe91fe4e617ca320a7d98f6a39
+size 197632
diff --git a/userspace/files/profile b/userspace/files/profile
index 9363f2a..e6aa526 100644
--- a/userspace/files/profile
+++ b/userspace/files/profile
@@ -26,7 +26,9 @@ if [ -d /etc/profile.d ]; then
unset i
fi
-export XDG_RUNTIME_DIR="/var/tmp/xdg"
+# display setup
+export XDG_RUNTIME_DIR="/var/tmp/weston"
+export QT_QPA_PLATFORM="wayland-egl"
# python setup
export PYTHONPATH="/data/pythonpath"
diff --git a/userspace/files/weston b/userspace/files/weston
new file mode 100755
index 0000000..7600b66
--- /dev/null
+++ b/userspace/files/weston
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7e38b2701eaa61471dfb2418b606846c0512afd90f67bfc0d65dcf5178fb51b8
+size 782832
diff --git a/userspace/files/weston-ready.service b/userspace/files/weston-ready.service
new file mode 100644
index 0000000..49b84cf
--- /dev/null
+++ b/userspace/files/weston-ready.service
@@ -0,0 +1,28 @@
+[Unit]
+PartOf=weston.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+Restart=no
+Environment="XDG_RUNTIME_DIR=/var/tmp/weston"
+
+ExecStart=/bin/echo "waiting for wayland socket"
+ExecStart=/bin/bash -c "while [ ! -e \"$XDG_RUNTIME_DIR/wayland-0\" ]; do sleep 0.1; done"
+
+# still starting after socket comes up
+ExecStart=/bin/sleep 0.5
+
+ExecStart=/bin/echo "fixing permissions"
+ExecStart=/bin/bash -c "chown -R comma: $XDG_RUNTIME_DIR"
+ExecStart=/bin/bash -c "chmod -R 700 $XDG_RUNTIME_DIR"
+
+# these are set by udev rules, but udev is slow
+ExecStart=/bin/bash -c "chgrp gpu /dev/ion /dev/kgsl-3d0"
+ExecStart=/bin/bash -c "chmod 660 /dev/ion /dev/kgsl-3d0"
+
+ExecStart=/bin/echo "turning on display"
+ExecStart=/bin/bash -c "echo 500 > /sys/class/backlight/panel0-backlight/brightness"
+
+[Install]
+WantedBy=multi-user.target
diff --git a/userspace/files/weston.service b/userspace/files/weston.service
new file mode 100644
index 0000000..52ecd20
--- /dev/null
+++ b/userspace/files/weston.service
@@ -0,0 +1,31 @@
+[Unit]
+Description=Weston
+Conflicts=getty@tty1.service
+
+[Service]
+Type=simple
+Restart=no
+KillSignal=SIGKILL
+Environment="XDG_RUNTIME_DIR=/var/tmp/weston"
+
+UtmpIdentifier=tty1
+TTYPath=/dev/tty1
+TTYReset=yes
+TTYVHangup=yes
+TTYVTDisallocate=yes
+
+ExecStartPre=/bin/bash -c "/usr/local/venv/bin/python -c 'import fcntl; KDSETMODE = 0x4B3A; KD_TEXT = 0x00; fd = open(\"/dev/tty1\", \"w\"); fcntl.ioctl(fd, KDSETMODE, KD_TEXT); fd.close()'"
+ExecStartPre=/bin/bash -c "/usr/local/venv/bin/python -c 'from PIL import Image; img=Image.open(\"/usr/comma/bg.jpg\"); (img.rotate(180) if open(\"/sys/devices/platform/vendor/vendor:gpio-som-id/som_id\").read().strip() == \"1\" else img).save(\"/tmp/bg.jpg\")'"
+ExecStartPre=/bin/bash -c "mkdir -p $XDG_RUNTIME_DIR"
+ExecStartPre=/bin/bash -c "chown -R comma: $XDG_RUNTIME_DIR"
+ExecStartPre=/bin/bash -c "chmod -R 700 $XDG_RUNTIME_DIR"
+
+ExecStartPre=/bin/bash -c "mkdir -p /data/misc/display || true"
+ExecStartPre=/bin/bash -c "echo 0 > /data/misc/display/sdm_dbg_cfg.txt || true"
+ExecStartPre=/bin/bash -c "echo 0 > /data/misc/display/gbm_dbg_cfg.txt || true"
+
+ExecStartPre=/bin/chvt 1
+ExecStart=/usr/bin/weston --idle-time=0 --tty=1 --config=/usr/comma/weston.ini
+
+[Install]
+WantedBy=multi-user.target
diff --git a/userspace/libinput/NOTES b/userspace/libinput/NOTES
new file mode 100644
index 0000000..e021625
--- /dev/null
+++ b/userspace/libinput/NOTES
@@ -0,0 +1,3 @@
+The Thundercomm version of Weston has a bug where it doesn't allow opening the input devices.
+This patch bypasses that.
+Source used to build: libinput commit f0997536a7a3e384bfe64b67c5c1f874656042c6
diff --git a/userspace/libinput/patch.diff b/userspace/libinput/patch.diff
new file mode 100644
index 0000000..ddb09b4
--- /dev/null
+++ b/userspace/libinput/patch.diff
@@ -0,0 +1,97 @@
+diff --git a/src/evdev.c b/src/evdev.c
+index c3c02d2a..ef773e6a 100644
+--- a/src/evdev.c
++++ b/src/evdev.c
+@@ -1991,7 +1991,7 @@ evdev_notify_added_device(struct evdev_device *device)
+ static bool
+ evdev_device_have_same_syspath(struct udev_device *udev_device, int fd)
+ {
+- struct udev *udev = udev_device_get_udev(udev_device);
++ struct udev *udev = udev_device_get_udev(udev_device);
+ struct udev_device *udev_device_new = NULL;
+ struct stat st;
+ bool rc = false;
+@@ -1999,9 +1999,13 @@ evdev_device_have_same_syspath(struct udev_device *udev_device, int fd)
+ if (fstat(fd, &st) < 0)
+ goto out;
+
++ printf("st_rdev: %d\n", st.st_rdev);
+ udev_device_new = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
+ if (!udev_device_new)
+ goto out;
++
++ printf("same syspath: %s %s\n", udev_device_get_syspath(udev_device_new),
++ udev_device_get_syspath(udev_device));
+
+ rc = streq(udev_device_get_syspath(udev_device_new),
+ udev_device_get_syspath(udev_device));
+@@ -2174,6 +2178,8 @@ evdev_device_create(struct libinput_seat *seat,
+ return NULL;
+ }
+
++ log_error(libinput, "%s: evdev_device_create\n", sysname);
++
+ if (udev_device_should_be_ignored(udev_device)) {
+ log_debug(libinput, "%s: device is ignored\n", sysname);
+ return NULL;
+@@ -2182,7 +2188,8 @@ evdev_device_create(struct libinput_seat *seat,
+ /* Use non-blocking mode so that we can loop on read on
+ * evdev_device_data() until all events on the fd are
+ * read. mtdev_get() also expects this. */
+- fd = open_restricted(libinput, devnode,
++ //fd = open_restricted(libinput, devnode,
++ fd = open(devnode,
+ O_RDWR | O_NONBLOCK | O_CLOEXEC);
+ if (fd < 0) {
+ log_info(libinput,
+@@ -2193,8 +2200,11 @@ evdev_device_create(struct libinput_seat *seat,
+ return NULL;
+ }
+
+- if (!evdev_device_have_same_syspath(udev_device, fd))
++ printf("Opened fd: %d from devnode %s\n", fd, devnode);
++ if (!evdev_device_have_same_syspath(udev_device, fd)){
++ log_error(libinput, "%s: not same syspath\n", sysname);
+ goto err;
++ }
+
+ device = zalloc(sizeof *device);
+
+@@ -2204,8 +2214,10 @@ evdev_device_create(struct libinput_seat *seat,
+ evdev_drain_fd(fd);
+
+ rc = libevdev_new_from_fd(fd, &device->evdev);
+- if (rc != 0)
++ if (rc != 0){
++ log_error(libinput, "%s: new_from_fd failed\n", sysname);
+ goto err;
++ }
+
+ libevdev_set_clock_id(device->evdev, CLOCK_MONOTONIC);
+ libevdev_set_device_log_function(device->evdev,
+@@ -2241,16 +2253,22 @@ evdev_device_create(struct libinput_seat *seat,
+ evdev_pre_configure_model_quirks(device);
+
+ device->dispatch = evdev_configure_device(device);
+- if (device->dispatch == NULL || device->seat_caps == 0)
++ if (device->dispatch == NULL || device->seat_caps == 0){
++ log_error(libinput, "%s: device->dispatch or device->seat_caps %d failed\n", sysname, device->seat_caps);
+ goto err;
++ }
+
+ device->source =
+ libinput_add_fd(libinput, fd, evdev_device_dispatch, device);
+- if (!device->source)
++ if (!device->source){
++ log_error(libinput, "%s: device->source failed\n", sysname);
+ goto err;
++ }
+
+- if (!evdev_set_device_group(device, udev_device))
++ if (!evdev_set_device_group(device, udev_device)){
++ log_error(libinput, "%s: set device group failed\n", sysname);
+ goto err;
++ }
+
+ list_insert(seat->devices_list.prev, &device->base.link);
+
diff --git a/userspace/libs/libffi.so.6 b/userspace/libs/libffi.so.6
deleted file mode 120000
index c6cc6fd..0000000
--- a/userspace/libs/libffi.so.6
+++ /dev/null
@@ -1 +0,0 @@
-libffi.so.6.0.4
\ No newline at end of file
diff --git a/userspace/libs/libffi.so.6.0.4 b/userspace/libs/libffi.so.6.0.4
deleted file mode 100644
index 217a6dc..0000000
Binary files a/userspace/libs/libffi.so.6.0.4 and /dev/null differ
diff --git a/userspace/libs/libqmapboxgl.so b/userspace/libs/libqmapboxgl.so
new file mode 100755
index 0000000..99dfaa4
Binary files /dev/null and b/userspace/libs/libqmapboxgl.so differ
diff --git a/userspace/qtwayland/README b/userspace/qtwayland/README
new file mode 100644
index 0000000..1910295
--- /dev/null
+++ b/userspace/qtwayland/README
@@ -0,0 +1,80 @@
+# Ubuntu 24.04 + "old" weston
+
+The following need to work together in Ubuntu 24.04 (noble):
+- "old" weston
+- libwayland
+- qtwayland
+- qt
+
+The "old" weston is built with:
+- libwayland-dev_1.9.0-1
+- libwayland-server_1.9.0-1
+- libwayland-client_1.9.0-1
+- libwayland-cursor_1.9.0-1
+
+These are roughly from Xenial (16.04 - https://launchpad.net/ubuntu/xenial/arm64/libwayland-dev/1.9.0-1).
+
+In Ubuntu 20.04 (focal) even if libwayland is 1.18.0-1, the protocol between
+the server (1.9.0-1) and client (1.18.0-1) was still compatible. Unfortunately,
+this is not the case anymore in Ubuntu 24.04 (noble), where libwayland 1.22.0
+is not compatible anymore with 1.9.0.
+
+Because of this:
+- libwayland-*_1.9.0-1 packages can't be installed anymore from noble, but a
+custom deb has been built (libwayland-1.9.0-1.deb) - this includes all
+libwayland packages in one package
+- libwayland has a dependency (libffi6)
+- libwayland-1.9.0-1.deb can be rebuilt with `build-libwayland-deb.sh`
+
+Also, Qt 5.15 from Ubuntu 24.04 (noble) doesn't compile with these old
+dependencies, 5.12 being the last major being able to be compiled, so:
+- a custom qt-5.12.8.deb has been built, since qt from focal has a lot of
+dependencies not existing in Ubuntu 24.04 (noble)
+- qt has two non-qt related dependencies (libicu66, libssl1.1)
+- qt-5.12.8.deb can be rebuilt with `build-qt-deb.sh`
+
+The dependencies for the two custom debs can be downloaded from Launchpad:
+```
+curl -LO https://launchpad.net/ubuntu/+archive/primary/+files/libffi6_3.2.1-8_arm64.deb
+curl -LO https://launchpad.net/ubuntu/+archive/primary/+files/libicu66_66.1-2ubuntu2.1_arm64.deb
+curl -LO https://launchpad.net/ubuntu/+archive/primary/+files/libssl1.1_1.1.1f-1ubuntu2.22_arm64.deb
+```
+\* libffi6_armhf is also needed, but already exits in libs32
+
+# When updating weston & removing custom debs
+After removing qt-5.12.8.deb add these back:
+```
+libqt5opengl5-dev \
+libqt5sql5-sqlite \
+libqt5svg5-dev \
+libqt5multimedia5-plugins \
+qml-module-qtquick2 \
+qtbase5-dev \
+qtchooser \
+qt5-qmake \
+qtbase5-dev-tools \
+qtbase5-private-dev \
+qtdeclarative5-dev \
+qtdeclarative5-private-dev \
+qtlocation5-dev \
+qtmultimedia5-dev \
+qtpositioning5-dev \
+qtwayland5 \
+```
+
+In case of uncertainty, qt5-default was a metapackage for:
+```
+qtbase5-dev
+qtchooser
+qt5-qmake
+qtbase5-dev-tools
+```
+More info: https://packages.ubuntu.com/focal/qt5-default
+
+After removing libwayland-1.9.0-1.deb add these back:
+```
+libwayland-client0:armhf \
+libwayland-cursor0:armhf \
+libwayland-server0:armhf \
+libwayland-dev \
+```
diff --git a/userspace/qtwayland/build-libwayland-deb.sh b/userspace/qtwayland/build-libwayland-deb.sh
new file mode 100755
index 0000000..4b2714f
--- /dev/null
+++ b/userspace/qtwayland/build-libwayland-deb.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+set -e
+
+################################################################################
+# Custom libwayland is created by combining libwayland client0, cursor0, server0
+# and dev 1.9.0-1 from Ubuntu 16.04 (xenial) for both aarch64 and armhf, without
+# getting into dependency hell.
+################################################################################
+
+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
+TMP=$DIR/tmp
+TMP_SRC=$TMP/libwayland-src-debs
+
+# Create a new folder `libwayland-1.9.0-1` and put the metadata in
+# `libwayland-1.9.0-1/DEBIAN/control`:
+
+mkdir -p $TMP
+cd $TMP
+mkdir -p libwayland-1.9.0-1/DEBIAN
+
+cat << EOF > libwayland-1.9.0-1/DEBIAN/control
+Package: libwayland-xenial
+Version: 1.9.0-1
+Architecture: all
+Maintainer: Andrei Radulescu andi.radulescu@gmail.com
+Depends: libc6 (>= 2.17), libexpat1 (>= 2.0.1), libffi6 (>= 3.2)
+Replaces: libwayland-dev, libwayland-client0, libwayland-cursor0, libwayland-server0
+Installed-Size: 0
+Homepage: https://comma.ai
+Description: libwayland client0, cursor0, server0 and dev 1.9.0-1 from Ubuntu Xenial
+EOF
+
+# Download the official debs:
+mkdir -p $TMP_SRC
+cd $TMP_SRC
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-dev_1.9.0-1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-dev_1.9.0-1_armhf.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-client0_1.9.0-1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-client0_1.9.0-1_armhf.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-cursor0_1.9.0-1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-cursor0_1.9.0-1_armhf.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-server0_1.9.0-1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libwayland-server0_1.9.0-1_armhf.deb
+
+# And unpack them:
+for deb in *.deb; do dpkg-deb -R "$deb" "${deb%.deb}"; done
+
+# Copy all files in libwayland-1.9.0-1
+cd $TMP
+cp -a $TMP_SRC/*/usr libwayland-1.9.0-1
+
+# Package the deb and clean up everything else
+dpkg-deb --root-owner-group --build "libwayland-1.9.0-1" "libwayland-1.9.0-1.deb"
+mv libwayland-1.9.0-1.deb $DIR
+rm -rf libwayland-1.9.0-1 $TMP_SRC
diff --git a/userspace/qtwayland/build-qt-deb.sh b/userspace/qtwayland/build-qt-deb.sh
new file mode 100755
index 0000000..cfa6b45
--- /dev/null
+++ b/userspace/qtwayland/build-qt-deb.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+set -e
+
+################################################################################
+# Custom qt is created by combining qt packages from from Ubuntu 20.04 (focal)
+# without getting into dependency hell.
+################################################################################
+
+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
+TMP=$DIR/tmp
+TMP_SRC=$TMP/qt-src-debs
+
+# Create a new folder `qt-5.12.8` and put the metadata in
+# `qt-5.12.8/DEBIAN/control`:
+
+mkdir -p $TMP
+cd $TMP
+mkdir -p qt-5.12.8/DEBIAN
+
+cat << EOF > qt-5.12.8/DEBIAN/control
+Package: qt-focal
+Version: 5.12.8
+Architecture: all
+Maintainer: Andrei Radulescu andi.radulescu@gmail.com
+Depends: libicu66 (>= 66.1-1~), libdouble-conversion3 (>= 2.0.0), libssl1.1
+Replaces: qtbase5-dev, qtchooser, qt5-qmake, qtbase5-dev-tools
+Installed-Size: 0
+Homepage: https://comma.ai
+Description: Qt 5.12.8 from Ubuntu 20.04
+EOF
+
+# Download the official debs:
+mkdir -p $TMP_SRC
+cd $TMP_SRC
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtbase5-dev_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtbase5-dev-tools_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtbase5-private-dev_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qt5-qmake_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qt5-qmake-bin_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtdeclarative5-dev-tools_5.12.8-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5core5a_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5network5_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5gui5_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5dbus5_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5concurrent5_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5widgets5_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5xml5_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5opengl5-dev_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5opengl5_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5svg5-dev_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5svg5_5.12.8-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5multimedia5-plugins_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5multimedia5_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5multimediagsttools5_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5multimediawidgets5_5.12.8-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtdeclarative5-dev_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtdeclarative5-private-dev_5.12.8-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtlocation5-dev_5.12.8+dfsg-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5location5_5.12.8+dfsg-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5location5-plugins_5.12.8+dfsg-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5location5-plugin-mapboxgl_5.12.8+dfsg-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtmultimedia5-dev_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5multimedia5_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5multimediaquick5_5.12.8-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5waylandclient5_5.12.8-0ubuntu1_arm64.deb
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/libqt5waylandcompositor5_5.12.8-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtwayland5_5.12.8-0ubuntu1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qt5-default_5.12.8+dfsg-0ubuntu2.1_arm64.deb
+
+curl -sSLO https://launchpad.net/ubuntu/+archive/primary/+files/qtchooser_66-2build1_arm64.deb
+
+# And unpack them:
+for deb in *.deb; do dpkg-deb -R "$deb" "${deb%.deb}"; done
+
+# Copy all files in qt-5.12.8
+cd $TMP
+cp -a $TMP_SRC/*/usr qt-5.12.8
+
+# Package the deb and clean up everything else
+dpkg-deb --root-owner-group --build "qt-5.12.8" "qt-5.12.8.deb"
+mv qt-5.12.8.deb $DIR
+rm -rf qt-5.12.8 $TMP_SRC
diff --git a/userspace/qtwayland/libffi6_3.2.1-8_arm64.deb b/userspace/qtwayland/libffi6_3.2.1-8_arm64.deb
new file mode 100644
index 0000000..b906114
--- /dev/null
+++ b/userspace/qtwayland/libffi6_3.2.1-8_arm64.deb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d0f8d2b7613167317ec4f9bf65125a2e13c5f357e5acb5cc1fa9ed488c3c88b0
+size 17016
diff --git a/userspace/qtwayland/libicu66_66.1-2ubuntu2.1_arm64.deb b/userspace/qtwayland/libicu66_66.1-2ubuntu2.1_arm64.deb
new file mode 100644
index 0000000..757254e
--- /dev/null
+++ b/userspace/qtwayland/libicu66_66.1-2ubuntu2.1_arm64.deb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ccfbd8e68fadcf4cc3975cdae42d1786733963f75d0b180f96c13782e185635b
+size 8359564
diff --git a/userspace/qtwayland/libssl1.1_1.1.1f-1ubuntu2.22_arm64.deb b/userspace/qtwayland/libssl1.1_1.1.1f-1ubuntu2.22_arm64.deb
new file mode 100644
index 0000000..c42ff55
--- /dev/null
+++ b/userspace/qtwayland/libssl1.1_1.1.1f-1ubuntu2.22_arm64.deb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:36b33bc85a8c75d539f00dcda80cf9d618a0ee56aec46761347409caeebb9028
+size 1158832
diff --git a/userspace/qtwayland/libwayland-1.9.0-1.deb b/userspace/qtwayland/libwayland-1.9.0-1.deb
new file mode 100644
index 0000000..491baa2
--- /dev/null
+++ b/userspace/qtwayland/libwayland-1.9.0-1.deb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4b06c0ea60c33fb5bb2e16e0d340296dec22e178af5210b5405d7bf26e1c6527
+size 160312
diff --git a/userspace/qtwayland/patch-qtwayland-v5.12 b/userspace/qtwayland/patch-qtwayland-v5.12
new file mode 100644
index 0000000..ac5024d
--- /dev/null
+++ b/userspace/qtwayland/patch-qtwayland-v5.12
@@ -0,0 +1,25 @@
+diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp
+index 1fe0125e..7899c94e 100644
+--- a/src/client/qwaylandscreen.cpp
++++ b/src/client/qwaylandscreen.cpp
+@@ -94,6 +94,7 @@ QString QWaylandScreen::model() const
+
+ QRect QWaylandScreen::geometry() const
+ {
++ return QRect(0, 0, 2160, 1080);
+ if (zxdg_output_v1::isInitialized()) {
+ return mXdgGeometry;
+ } else {
+diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
+index 4b3a635c..d0e70f29 100644
+--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
++++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
+@@ -76,7 +76,7 @@ QWaylandEglClientBufferIntegration::~QWaylandEglClientBufferIntegration()
+
+ void QWaylandEglClientBufferIntegration::initialize(QWaylandDisplay *display)
+ {
+- if (q_hasEglExtension(EGL_NO_DISPLAY, "EGL_EXT_platform_base")) {
++ if (false && q_hasEglExtension(EGL_NO_DISPLAY, "EGL_EXT_platform_base")) {
+ if (q_hasEglExtension(EGL_NO_DISPLAY, "EGL_KHR_platform_wayland") ||
+ q_hasEglExtension(EGL_NO_DISPLAY, "EGL_EXT_platform_wayland") ||
+ q_hasEglExtension(EGL_NO_DISPLAY, "EGL_MESA_platform_wayland")) {
diff --git a/userspace/qtwayland/qt-5.12.8.deb b/userspace/qtwayland/qt-5.12.8.deb
new file mode 100644
index 0000000..c971fc5
--- /dev/null
+++ b/userspace/qtwayland/qt-5.12.8.deb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8f10abc73eafab7e1e26a912b0cd5eece3df708f94868cd37b5bb717c6003fac
+size 18782360
diff --git a/userspace/usr/comma/power_drop_monitor.py b/userspace/usr/comma/power_drop_monitor.py
index c4c3d45..4dd7379 100755
--- a/userspace/usr/comma/power_drop_monitor.py
+++ b/userspace/usr/comma/power_drop_monitor.py
@@ -95,7 +95,7 @@ def perform_controlled_shutdown():
# Kill services that draw a lot of power
printk("Killing services")
- subprocess.call(["/usr/bin/systemctl", "kill", "--signal=9", "comma"])
+ subprocess.call(["/usr/bin/systemctl", "kill", "--signal=9", "weston", "comma"])
set_screen_power(False)
printk("Halt")
diff --git a/userspace/usr/comma/tests/analyze-boot-time.py b/userspace/usr/comma/tests/analyze-boot-time.py
index 2bcd15c..75e66f2 100755
--- a/userspace/usr/comma/tests/analyze-boot-time.py
+++ b/userspace/usr/comma/tests/analyze-boot-time.py
@@ -5,6 +5,7 @@ from tabulate import tabulate
# serial with timestamps:
# grabserial -d /dev/serial/by-id/usb-FTDI_FT230X* -t
+# systemd-analyze critical-chain weston.service
# systemd-analyze critical-chain comma.service
# boot chart:
@@ -35,6 +36,8 @@ if __name__ == "__main__":
ts['kernel'] = float(l[3][:-1])
#ts['systemd'] = float(l[6][:-1])
+ # includes /sbin/init -> weston being ready to display stuff
+ ts['weston'] = get_journal_time("Finished weston-ready.service") - tot_since_kern()
ts['comma'] = get_journal_time("Starting comma.service") - tot_since_kern()
# print
diff --git a/userspace/usr/comma/tests/benchmark_weston.py b/userspace/usr/comma/tests/benchmark_weston.py
new file mode 100755
index 0000000..8362f89
--- /dev/null
+++ b/userspace/usr/comma/tests/benchmark_weston.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+import os
+import time
+import subprocess
+
+def run(cmd):
+ subprocess.check_call(cmd, shell=True)
+
+def timestamp_cmd(cmd):
+ cnt = 0
+ while True:
+ cnt += 1
+ print("try ", cnt)
+ run("sudo chmod -R 700 /var/tmp/weston/")
+ proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ t = time.monotonic()
+ time.sleep(0.5)
+ r = proc.poll()
+ if r is not None:
+ continue
+ break
+ print("r", r)
+ return t
+
+if __name__ == "__main__":
+
+ run("sudo systemctl stop weston")
+ run("sudo rm -rf /var/tmp/weston/wayland-0")
+ time.sleep(0.5)
+ #run("sudo systemctl restart weston-ready")
+
+ run("sudo systemctl restart weston --no-block")
+ st = time.monotonic()
+ #ts = defaultdict()
+
+ cnt = 0
+ while not os.path.exists("/var/tmp/weston/wayland-0"):
+ time.sleep(0.1)
+ cnt += 1
+ t = time.monotonic()
+ print(f"- socket at {t - st:.2f}s")
+
+ t = timestamp_cmd('/usr/comma/setup')
+ print(f"- setup works {t - st:.2f}s")
+
+ t = timestamp_cmd('cd /data/openpilot/selfdrive/ui/ && ./spinner')
+ print(f"- spinner works {t - st:.2f}s")
diff --git a/userspace/usr/comma/tests/test_agnos.py b/userspace/usr/comma/tests/test_agnos.py
index 8ca6647..1db914e 100755
--- a/userspace/usr/comma/tests/test_agnos.py
+++ b/userspace/usr/comma/tests/test_agnos.py
@@ -44,6 +44,10 @@ def test_wifi():
networks = out.strip().splitlines()[1:]
assert len(networks) > 5
+def test_color_calibration():
+ out = subprocess.check_output("journalctl -u weston", shell=True, encoding='utf8')
+ assert out.count("Successfully setup color correction") == 3
+
def test_python_shims():
subprocess.check_call("cd /data/openpilot && scons -h", shell=True, stdout=subprocess.DEVNULL)
@@ -60,4 +64,7 @@ def test_boot_time():
a = out.splitlines()[0]
print(out, a)
+ # check weston service
+
# check comma service
+
diff --git a/userspace/usr/comma/tests/test_weston.py b/userspace/usr/comma/tests/test_weston.py
new file mode 100755
index 0000000..0595577
--- /dev/null
+++ b/userspace/usr/comma/tests/test_weston.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+import os
+import time
+import hashlib
+import subprocess
+
+"""
+journalctl -o short-monotonic -u weston -u weston-ready -u agnos-tests
+"""
+
+if __name__ == "__main__":
+ socket_exists = os.path.exists("/var/tmp/weston/wayland-0")
+ is_active = subprocess.check_output("systemctl is-active weston", shell=True, encoding='utf8').strip()
+
+ d = b""
+ for fn in ('/lib/systemd/system/weston.service', '/lib/systemd/system/weston-ready.service'):
+ with open(fn, 'rb') as f:
+ d += f.read()
+ h = hashlib.sha1(d).hexdigest()
+
+ # weston should be ready to go at this point
+ cmd = '/usr/comma/setup'
+ cmd = 'cd /data/openpilot/selfdrive/ui/ && ./ui'
+ proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ for i in range(10):
+ r = proc.poll()
+ if r is not None:
+ break
+ time.sleep(1)
+
+ rc = proc.returncode
+ proc.kill()
+ out, err = proc.stdout.read(), proc.stderr.read()
+
+ with open('/data/weston_log', 'a') as f:
+ f.write(f"{is_active=}, {socket_exists=}, {rc=} / {h} / {cmd}\n")
+ if rc is not None:
+ f.write(f" stdout: {out}\n")
+ f.write(f" stderr: {err}\n")
+ os.sync()
+
+ os.system("sudo su -c 'tail /data/weston_log > /dev/console'")
+ os.system("sudo su -c 'wc -l /data/weston_log > /dev/console'")
+
+ if rc is None:
+ time.sleep(2)
+ os.system("sudo reboot")
diff --git a/userspace/usr/comma/weston.ini b/userspace/usr/comma/weston.ini
new file mode 100644
index 0000000..9f1f991
--- /dev/null
+++ b/userspace/usr/comma/weston.ini
@@ -0,0 +1,4 @@
+[shell]
+background-image=/tmp/bg.jpg
+background-type=scale-crop
+close-animation=none