1{ lib, ... }:
2{
3 name = "lomiri-camera-app-standalone";
4 meta.maintainers = lib.teams.lomiri.members;
5
6 nodes.machine =
7 { config, pkgs, ... }:
8 {
9 imports = [ ./common/x11.nix ];
10
11 services.xserver.enable = true;
12
13 environment = {
14 systemPackages =
15 with pkgs;
16 [
17 feh # view photo result
18 ffmpeg # fake webcam stream
19 gnome-text-editor # somewhere to paste QR result
20 (imagemagick.override { ghostscriptSupport = true; }) # add label for OCR
21 qrtool # generate QR code
22 xdotool # clicking on QR button
23 ]
24 ++ (with pkgs.lomiri; [
25 suru-icon-theme
26 lomiri-camera-app
27 ]);
28 variables = {
29 UITK_ICON_THEME = "suru";
30 };
31 };
32
33 i18n.supportedLocales = [ "all" ];
34
35 fonts = {
36 packages = with pkgs; [
37 # Intended font & helps with OCR
38 ubuntu-classic
39 ];
40 };
41
42 # Fake camera
43 boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
44 };
45
46 enableOCR = true;
47
48 testScript =
49 let
50 qrLabel = "Feed";
51 qrContent = "Test";
52 in
53 ''
54 machine.wait_for_x()
55
56 with subtest("lomiri camera launches"):
57 machine.succeed("lomiri-camera-app >&2 &")
58 machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet")
59 machine.sleep(10)
60 machine.send_key("alt-f10")
61 machine.sleep(5)
62 machine.wait_for_text("Cannot access")
63 machine.screenshot("lomiri-camera_open")
64
65 machine.succeed("pkill -f lomiri-camera-app")
66
67 # Setup fake v4l2 camera
68 machine.succeed("modprobe v4l2loopback video_nr=10 card_label=Video-Loopback exclusive_caps=1")
69 machine.succeed("qrtool encode '${qrContent}' -s 20 -m 10 > qr.png")
70 # Horizontal flip, add text, flip back. Camera displays image mirrored, so need reversed text for OCR
71 machine.succeed("magick qr.png -flop -pointsize 30 -fill black -annotate +100+100 '${qrLabel}' -flop output.png")
72 machine.succeed("ffmpeg -re -loop 1 -i output.png -vf format=yuv420p -f v4l2 /dev/video10 -loglevel fatal >&2 &")
73
74 with subtest("lomiri camera uses camera"):
75 machine.succeed("lomiri-camera-app >&2 &")
76 machine.wait_for_console_text("updateViewfinderResolution: For target resolution")
77 machine.sleep(10)
78 machine.send_key("alt-f10")
79 machine.sleep(5)
80 machine.wait_for_text("${qrLabel}")
81 machine.screenshot("lomiri-camera_feed")
82
83 machine.succeed("xdotool mousemove 510 670 click 1") # take photo
84 machine.wait_until_succeeds("ls /root/Pictures/camera.ubports | grep '\\.jpg$'")
85
86 # Check that the image is correct
87 machine.send_key("ctrl-alt-right")
88 machine.succeed("magick /root/Pictures/camera.ubports/IMG_00000001.jpg -flop photo_flip.png")
89 machine.succeed("feh photo_flip.png >&2 &")
90 machine.sleep(10)
91 machine.wait_for_text("${qrLabel}")
92 machine.screenshot("lomiri-camera_photo")
93
94 machine.succeed("pkill -f feh")
95 machine.send_key("ctrl-alt-left")
96 machine.succeed("pkill -f lomiri-camera-app")
97
98 with subtest("lomiri barcode scanner uses camera"):
99 machine.succeed("lomiri-camera-app --mode=barcode-reader >&2 &")
100 machine.wait_for_console_text("updateViewfinderResolution: For target resolution")
101 machine.sleep(10)
102 machine.send_key("alt-f10")
103 machine.sleep(5)
104 machine.wait_for_text("${qrLabel}")
105 machine.succeed("xdotool mousemove 510 670 click 1") # open up QR decode result
106
107 # OCR is struggling to recognise the text. Click the clipboard button and paste the result somewhere else
108 machine.sleep(5)
109 machine.screenshot("lomiri-barcode_decode")
110 machine.succeed("xdotool mousemove 540 590 click 1")
111 machine.sleep(5)
112
113 # Need to make a new window without closing camera app, otherwise clipboard content gets lost?
114 machine.send_key("ctrl-alt-right")
115 machine.succeed("gnome-text-editor >&2 &")
116 machine.sleep(10)
117 machine.send_key("alt-f10")
118 machine.sleep(5)
119 machine.wait_for_text("New")
120
121 # Font size up to help with OCR
122 machine.send_key("ctrl-kp_add")
123 machine.send_key("ctrl-kp_add")
124 machine.send_key("ctrl-kp_add")
125 machine.send_key("ctrl-kp_add")
126 machine.send_key("ctrl-kp_add")
127 machine.send_key("ctrl-kp_add")
128 machine.send_key("ctrl-kp_add")
129 machine.send_key("ctrl-kp_add")
130 machine.send_key("ctrl-kp_add")
131 machine.send_key("ctrl-kp_add")
132 machine.send_key("ctrl-kp_add")
133 machine.send_key("ctrl-kp_add")
134 machine.send_key("ctrl-kp_add")
135 machine.send_key("ctrl-kp_add")
136 machine.send_key("ctrl-kp_add")
137 machine.send_key("ctrl-kp_add")
138
139 machine.send_key("ctrl-v")
140 machine.wait_for_text("${qrContent}")
141
142 machine.succeed("pkill -f gnome-text-editor")
143 machine.send_key("ctrl-alt-left")
144 machine.succeed("pkill -f lomiri-camera-app")
145
146 with subtest("lomiri camera localisation works"):
147 machine.succeed("env LANG=de_DE.UTF-8 lomiri-camera-app >&2 &")
148 machine.wait_for_console_text("updateViewfinderResolution: For target resolution")
149 machine.sleep(10)
150 machine.send_key("alt-f10")
151 machine.sleep(5)
152 machine.wait_for_text("Kamera")
153 machine.screenshot("lomiri-camera_localised")
154 '';
155}