1{ pkgs, lib, ... }:
2let
3 user = "alice";
4in
5{
6 name = "ayatana-indicators";
7
8 meta = {
9 maintainers = lib.teams.lomiri.members;
10 };
11
12 nodes.machine =
13 { config, ... }:
14 {
15 imports = [
16 ./common/auto.nix
17 ./common/user-account.nix
18 ];
19
20 test-support.displayManager.auto = {
21 enable = true;
22 inherit user;
23 };
24
25 services.xserver = {
26 enable = true;
27 desktopManager.mate.enable = true;
28 };
29 services.displayManager.defaultSession = lib.mkForce "mate";
30
31 services.ayatana-indicators = {
32 enable = true;
33 packages =
34 with pkgs;
35 [
36 ayatana-indicator-bluetooth
37 ayatana-indicator-datetime
38 ayatana-indicator-display
39 ayatana-indicator-messages
40 ayatana-indicator-power
41 ayatana-indicator-session
42 ayatana-indicator-sound
43 ]
44 ++ (with pkgs.lomiri; [
45 lomiri-indicator-network
46 lomiri-telephony-service
47 ]);
48 };
49
50 # Setup needed by some indicators
51
52 services.accounts-daemon.enable = true; # messages
53
54 # Lomiri-ish setup for Lomiri indicators
55 # TODO move into a Lomiri module, once the package set is far enough for the DE to start
56
57 networking.networkmanager.enable = true; # lomiri-network-indicator
58 # TODO potentially urfkill for lomiri-network-indicator?
59
60 services.dbus.packages = with pkgs.lomiri; [ libusermetrics ];
61
62 environment.systemPackages = with pkgs.lomiri; [ lomiri-schemas ];
63
64 services.telepathy.enable = true;
65
66 users.users.usermetrics = {
67 group = "usermetrics";
68 home = "/var/lib/usermetrics";
69 createHome = true;
70 isSystemUser = true;
71 };
72
73 users.groups.usermetrics = { };
74 };
75
76 # TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready?
77 testScript =
78 { nodes, ... }:
79 let
80 runCommandOverServiceList = list: command: lib.strings.concatMapStringsSep "\n" command list;
81
82 runCommandOverAyatanaIndicators = runCommandOverServiceList nodes.machine.systemd.user.targets.ayatana-indicators.wants;
83
84 runCommandOverLomiriIndicators = runCommandOverServiceList nodes.machine.systemd.user.targets.lomiri-indicators.wants;
85 in
86 ''
87 start_all()
88 machine.wait_for_x()
89
90 # Desktop environment should reach graphical-session.target
91 machine.wait_for_unit("graphical-session.target", "${user}")
92
93 # MATE relies on XDG autostart to bring up the indicators.
94 # Not sure *when* XDG autostart fires them up, and awaiting pgrep success seems to misbehave?
95 machine.sleep(10)
96
97 # Now check if all indicators were brought up successfully, and kill them for later
98 ''
99 + (runCommandOverAyatanaIndicators (
100 service:
101 let
102 serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service;
103 in
104 ''
105 machine.wait_until_succeeds("pgrep -u ${user} -f ${serviceExec}")
106 machine.succeed("pkill -f ${serviceExec}")
107 ''
108 ))
109 + ''
110
111 # Ayatana target is the preferred way of starting up indicators on SystemD session, the graphical session is responsible for starting this if it supports them.
112 # Mate currently doesn't do this, so start it manually for checking (https://github.com/mate-desktop/mate-indicator-applet/issues/63)
113 machine.systemctl("start ayatana-indicators.target", "${user}")
114 machine.wait_for_unit("ayatana-indicators.target", "${user}")
115
116 # Let all indicator services do their startups, potential post-launch crash & restart cycles so we can properly check for failures
117 # Not sure if there's a better way of awaiting this without false-positive potential
118 machine.sleep(10)
119
120 # Now check if all indicator services were brought up successfully
121 ''
122 + runCommandOverAyatanaIndicators (service: ''
123 machine.wait_for_unit("${service}", "${user}")
124 '')
125 + ''
126 # Stop the target
127 machine.systemctl("stop ayatana-indicators.target", "${user}")
128
129 # Let all indicator services do their shutdowns
130 # Not sure if there's a better way of awaiting this without false-positive potential
131 machine.sleep(10)
132
133 # Lomiri uses a different target, which launches a slightly different set of indicators
134 machine.systemctl("start lomiri-indicators.target", "${user}")
135 machine.wait_for_unit("lomiri-indicators.target", "${user}")
136
137 # Let all indicator services do their startups, potential post-launch crash & restart cycles so we can properly check for failures
138 # Not sure if there's a better way of awaiting this without false-positive potential
139 machine.sleep(10)
140
141 # Now check if all indicator services were brought up successfully
142 ''
143 + runCommandOverLomiriIndicators (service: ''
144 machine.wait_for_unit("${service}", "${user}")
145 '');
146}