1let
2 makeTest = import ./make-test-python.nix;
3 feedLabel = "Image";
4 feedQrContent = "Test";
5 feedImageFile = "feed.png";
6 makeFeedImage =
7 pkgs:
8 pkgs.runCommand feedImageFile
9 {
10 nativeBuildInputs = with pkgs; [
11 (imagemagick.override { ghostscriptSupport = true; }) # add label for OCR
12 qrtool # generate QR code
13 ];
14 }
15 ''
16 qrtool encode '${feedQrContent}' -s 20 -m 10 > qr.png
17
18 # Horizontal flip, add text, flip back. Camera displays image mirrored, so need reversed text for OCR
19 magick qr.png \
20 -flop \
21 -pointsize 30 -fill black -annotate +100+100 '${feedLabel}' \
22 -flop \
23 $out
24 '';
25in
26{
27 basic = makeTest (
28 { lib, ... }:
29 {
30 name = "lomiri-camera-app-basic";
31 meta.maintainers = lib.teams.lomiri.members;
32
33 nodes.machine =
34 { config, pkgs, ... }:
35 {
36 imports = [ ./common/x11.nix ];
37
38 services.xserver.enable = true;
39
40 environment = {
41 systemPackages = with pkgs.lomiri; [
42 suru-icon-theme
43 lomiri-camera-app
44 ];
45 variables = {
46 UITK_ICON_THEME = "suru";
47 };
48 };
49
50 i18n.supportedLocales = [ "all" ];
51
52 fonts = {
53 packages = with pkgs; [
54 # Intended font & helps with OCR
55 ubuntu-classic
56 ];
57 };
58 };
59
60 enableOCR = true;
61
62 testScript =
63 let
64 qrLabel = "Feed";
65 qrContent = "Test";
66 in
67 ''
68 machine.wait_for_x()
69
70 with subtest("lomiri camera launches"):
71 machine.succeed("lomiri-camera-app >&2 &")
72 # emitted twice
73 machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet")
74 machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet")
75 machine.sleep(10)
76 machine.send_key("alt-f10")
77 machine.sleep(5)
78 machine.wait_for_text("Cannot access")
79 machine.screenshot("lomiri-camera_open")
80
81 machine.succeed("pgrep -afx lomiri-camera-app >&2")
82 machine.succeed("pkill -efx lomiri-camera-app >&2")
83 machine.wait_until_fails("pgrep -afx lomiri-camera-app >&2")
84
85 # Sometimes, GStreamer errors out on camera init with: CameraBin error: "Failed to allocate required memory."
86 # Adding more VM memory didn't affect this. Maybe flaky in general?
87 # Current assumption: Camera access gets requested in a weird/still-in-use state, so sleep abit
88 machine.sleep(10)
89
90 with subtest("lomiri camera localisation works"):
91 machine.succeed("env LANG=de_DE.UTF-8 lomiri-camera-app >&2 &")
92 # emitted twice
93 machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet")
94 machine.wait_for_console_text("updateViewfinderResolution: viewfinder resolutions is not known yet")
95 machine.sleep(10)
96 machine.send_key("alt-f10")
97 machine.sleep(5)
98 machine.wait_for_text("Zugriff auf")
99 machine.screenshot("lomiri-camera_localised")
100 '';
101 }
102 );
103
104 v4l2-photo = makeTest (
105 { lib, ... }:
106 {
107 name = "lomiri-camera-app-v4l2-photo";
108 meta.maintainers = lib.teams.lomiri.members;
109
110 nodes.machine =
111 { config, pkgs, ... }:
112 {
113 imports = [ ./common/x11.nix ];
114
115 services.xserver.enable = true;
116
117 environment = {
118 etc."${feedImageFile}".source = makeFeedImage pkgs;
119 systemPackages =
120 with pkgs;
121 [
122 feh # view photo result
123 ffmpeg # fake webcam stream
124 imagemagick # unflip webcam photo
125 xdotool # clicking on camera button
126 ]
127 ++ (with pkgs.lomiri; [
128 suru-icon-theme
129 lomiri-camera-app
130 ]);
131 variables = {
132 UITK_ICON_THEME = "suru";
133 };
134 };
135
136 i18n.supportedLocales = [ "all" ];
137
138 fonts = {
139 packages = with pkgs; [
140 # Intended font & helps with OCR
141 ubuntu-classic
142 ];
143 };
144
145 # Fake camera
146 boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
147 };
148
149 enableOCR = true;
150
151 testScript = ''
152 machine.wait_for_x()
153
154 # Setup fake v4l2 camera
155 machine.succeed("modprobe v4l2loopback video_nr=10 card_label=Video-Loopback exclusive_caps=1")
156 machine.succeed("ffmpeg -re -loop 1 -i /etc/${feedImageFile} -vf format=yuv420p -f v4l2 /dev/video10 -loglevel fatal >&2 &")
157
158 with subtest("lomiri camera uses camera"):
159 machine.succeed("lomiri-camera-app >&2 &")
160 # emitted twice
161 machine.wait_for_console_text("No flash control support")
162 machine.wait_for_console_text("No flash control support")
163 machine.sleep(10)
164 machine.send_key("alt-f10")
165 machine.sleep(5)
166 machine.wait_for_text("${feedLabel}")
167 machine.screenshot("lomiri-camera_feed")
168
169 machine.succeed("xdotool mousemove 510 670 click 1") # take photo
170 machine.wait_until_succeeds("ls /root/Pictures/camera.ubports | grep '\\.jpg$'")
171
172 # Check that the image is correct
173 machine.send_key("ctrl-alt-right")
174 machine.succeed("magick /root/Pictures/camera.ubports/IMG_00000001.jpg -flop photo_flip.png")
175 machine.succeed("feh photo_flip.png >&2 &")
176 machine.sleep(10)
177 machine.send_key("alt-f10")
178 machine.sleep(5)
179 machine.wait_for_text("${feedLabel}")
180 machine.screenshot("lomiri-camera_photo")
181 '';
182 }
183 );
184
185 v4l2-qr = makeTest (
186 { lib, ... }:
187 {
188 name = "lomiri-camera-app-v4l2-qr";
189 meta.maintainers = lib.teams.lomiri.members;
190
191 nodes.machine =
192 { config, pkgs, ... }:
193 {
194 imports = [ ./common/x11.nix ];
195
196 services.xserver.enable = true;
197
198 environment = {
199 etc."${feedImageFile}".source = makeFeedImage pkgs;
200 systemPackages =
201 with pkgs;
202 [
203 ffmpeg # fake webcam stream
204 xclip # inspect QR contents copied into clipboard
205 xdotool # clicking on QR button
206 ]
207 ++ (with pkgs.lomiri; [
208 suru-icon-theme
209 lomiri-camera-app
210 ]);
211 variables = {
212 UITK_ICON_THEME = "suru";
213 };
214 };
215
216 i18n.supportedLocales = [ "all" ];
217
218 fonts = {
219 packages = with pkgs; [
220 # Intended font & helps with OCR
221 ubuntu-classic
222 ];
223 };
224
225 # Fake camera
226 boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
227 };
228
229 enableOCR = true;
230
231 testScript = ''
232 machine.wait_for_x()
233
234 # Setup fake v4l2 camera
235 machine.succeed("modprobe v4l2loopback video_nr=10 card_label=Video-Loopback exclusive_caps=1")
236 machine.succeed("ffmpeg -re -loop 1 -i /etc/${feedImageFile} -vf format=yuv420p -f v4l2 /dev/video10 -loglevel fatal >&2 &")
237
238 with subtest("lomiri barcode scanner uses camera"):
239 machine.succeed("lomiri-camera-app --mode=barcode-reader >&2 &")
240 # emitted twice
241 machine.wait_for_console_text("No flash control support")
242 machine.wait_for_console_text("No flash control support")
243 machine.sleep(10)
244 machine.send_key("alt-f10")
245 machine.sleep(5)
246 machine.wait_for_text("${feedLabel}")
247 machine.succeed("xdotool mousemove 510 670 click 1") # open up QR decode result
248
249 # OCR is struggling to recognise the text. Click the clipboard button, check what got copied
250 machine.sleep(5)
251 machine.screenshot("lomiri-barcode_decode")
252 machine.succeed("xdotool mousemove 540 590 click 1")
253 machine.wait_until_succeeds("env DISPLAY=:0 xclip -selection clipboard -o | grep -q '${feedQrContent}'")
254 '';
255 }
256 );
257}