]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - tests/src/test-qt-greeter.cpp
6c6e4cab6aedb5dd139adbc14bd6b0941aaaf7ca
[sojka/lightdm.git] / tests / src / test-qt-greeter.cpp
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <signal.h>
5 #include <glib-object.h>
6 #include <xcb/xcb.h>
7 #include <QLightDM/Greeter>
8 #include <QLightDM/Power>
9 #include <QLightDM/UsersModel>
10 #include <QtCore/QSettings>
11 #include <QtCore/QDebug>
12 #include <QtCore/QCoreApplication>
13
14 #include "test-qt-greeter.h"
15 #include "status.h"
16
17 static gchar *greeter_id;
18 static QCoreApplication *app = NULL;
19 static QSettings *config = NULL;
20 static QLightDM::PowerInterface *power = NULL;
21 static TestGreeter *greeter = NULL;
22 static QLightDM::UsersModel *users_model = NULL;
23
24 TestGreeter::TestGreeter ()
25 {
26     connect (this, SIGNAL(showMessage(QString, QLightDM::Greeter::MessageType)), SLOT(showMessage(QString, QLightDM::Greeter::MessageType)));
27     connect (this, SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)), SLOT(showPrompt(QString, QLightDM::Greeter::PromptType)));
28     connect (this, SIGNAL(authenticationComplete()), SLOT(authenticationComplete()));
29     connect (this, SIGNAL(autologinTimerExpired()), SLOT(autologinTimerExpired()));
30 }
31
32 void TestGreeter::showMessage (QString text, QLightDM::Greeter::MessageType type)
33 {
34     status_notify ("%s SHOW-MESSAGE TEXT=\"%s\"", greeter_id, text.toAscii ().constData ());
35 }
36
37 void TestGreeter::showPrompt (QString text, QLightDM::Greeter::PromptType type)
38 {
39     status_notify ("%s SHOW-PROMPT TEXT=\"%s\"", greeter_id, text.toAscii ().constData ());
40 }
41
42 void TestGreeter::authenticationComplete ()
43 {
44     if (authenticationUser () != "")
45         status_notify ("%s AUTHENTICATION-COMPLETE USERNAME=%s AUTHENTICATED=%s",
46                        greeter_id,
47                        authenticationUser ().toAscii ().constData (), isAuthenticated () ? "TRUE" : "FALSE");
48     else
49         status_notify ("%s AUTHENTICATION-COMPLETE AUTHENTICATED=%s", greeter_id, isAuthenticated () ? "TRUE" : "FALSE");
50 }
51
52 void TestGreeter::autologinTimerExpired ()
53 {
54 }
55
56 void TestGreeter::printHints ()
57 {
58     if (selectUserHint() != "")
59         status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, greeter->selectUserHint ().toAscii ().constData ());
60     if (selectGuestHint())
61         status_notify ("%s SELECT-GUEST-HINT", greeter_id);
62     if (lockHint())
63         status_notify ("%s LOCK-HINT", greeter_id);
64     if (!hasGuestAccountHint ())
65         status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
66     if (hideUsersHint ())
67         status_notify ("%s HIDE-USERS-HINT", greeter_id);
68     if (showManualLoginHint ())
69         status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
70     if (!showRemoteLoginHint ())
71         status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
72     int timeout = autologinTimeoutHint ();
73     if (autologinUserHint () != "")
74     {
75         if (timeout != 0)
76             status_notify ("%s AUTOLOGIN-USER USERNAME=%s TIMEOUT=%d", greeter_id, greeter->autologinUserHint ().toAscii ().constData (), timeout);
77         else
78             status_notify ("%s AUTOLOGIN-USER USERNAME=%s", greeter_id, greeter->autologinUserHint ().toAscii ().constData ());
79     }
80     else if (autologinGuestHint ())
81     {
82         if (timeout != 0)
83             status_notify ("%s AUTOLOGIN-GUEST TIMEOUT=%d", greeter_id, timeout);
84         else
85             status_notify ("%s AUTOLOGIN-GUEST", greeter_id);
86     }
87 }
88
89 void TestGreeter::idle ()
90 {
91     status_notify ("%s IDLE", greeter_id);
92 }
93
94 void TestGreeter::reset ()
95 {
96     status_notify ("%s RESET", greeter_id);
97     printHints ();
98 }
99
100 void TestGreeter::userRowsInserted (const QModelIndex & parent, int start, int end)
101 {
102     for (int i = start; i <= end; i++)
103     {
104         QString name = users_model->data (users_model->index (i, 0), QLightDM::UsersModel::NameRole).toString ();
105         status_notify ("%s USER-ADDED USERNAME=%s", greeter_id, qPrintable (name));
106     }
107 }
108
109 void TestGreeter::userRowsRemoved (const QModelIndex & parent, int start, int end)
110 {
111     for (int i = start; i <= end; i++)
112     {
113         QString name = users_model->data (users_model->index (i, 0), QLightDM::UsersModel::NameRole).toString ();
114         status_notify ("%s USER-REMOVED USERNAME=%s", greeter_id, qPrintable (name));
115     }
116 }
117
118 static void
119 signal_cb (int signum)
120 {
121     status_notify ("%s TERMINATE SIGNAL=%d", greeter_id, signum);
122     _exit (EXIT_SUCCESS);
123 }
124
125 static void
126 request_cb (const gchar *name, GHashTable *params)
127 {
128     gchar *r;
129
130     if (!name)
131     {
132         app->quit ();
133         return;
134     }
135   
136     if (strcmp (name, "AUTHENTICATE") == 0)
137     {
138         if (g_hash_table_lookup (params, "USERNAME"))
139             greeter->authenticate ((const gchar *) g_hash_table_lookup (params, "USERNAME"));
140         else
141             greeter->authenticate ();
142     }
143
144     else if (strcmp (name, "AUTHENTICATE-GUEST") == 0)
145         greeter->authenticateAsGuest ();
146   
147     else if (strcmp (name, "AUTHENTICATE-AUTOLOGIN") == 0)
148         greeter->authenticateAutologin ();
149
150     else if (strcmp (name, "AUTHENTICATE-REMOTE") == 0)
151         greeter->authenticateRemote ((const gchar *) g_hash_table_lookup (params, "SESSION"), NULL);
152
153     else if (strcmp (name, "RESPOND") == 0)
154         greeter->respond ((const gchar *) g_hash_table_lookup (params, "TEXT"));
155
156     else if (strcmp (name, "CANCEL-AUTHENTICATION") == 0)
157         greeter->cancelAuthentication ();
158
159     else if (strcmp (name, "START-SESSION") == 0)
160     {
161         if (g_hash_table_lookup (params, "SESSION"))
162         {
163             if (!greeter->startSessionSync ((const gchar *) g_hash_table_lookup (params, "SESSION")))
164                 status_notify ("%s SESSION-FAILED", greeter_id);
165         }
166         else
167         {
168             if (!greeter->startSessionSync ())
169                 status_notify ("%s SESSION-FAILED", greeter_id);
170         }
171     }
172
173     else if (strcmp (name, "LOG-USER-LIST-LENGTH") == 0)
174         status_notify ("%s LOG-USER-LIST-LENGTH N=%d", greeter_id, users_model->rowCount (QModelIndex ()));
175
176     else if (strcmp (name, "LOG-USER") == 0)
177     {
178         const gchar *username = (const gchar *) g_hash_table_lookup (params, "USERNAME");
179         for (int i = 0; i < users_model->rowCount (QModelIndex ()); i++)
180         {
181             QString name = users_model->data (users_model->index (i, 0), QLightDM::UsersModel::NameRole).toString ();
182             if (name == username)
183                 status_notify ("%s LOG-USER USERNAME=%s", greeter_id, qPrintable (name));
184         }
185     }
186
187     else if (strcmp (name, "LOG-USER-LIST") == 0)
188     {
189         for (int i = 0; i < users_model->rowCount (QModelIndex ()); i++)
190         {
191             QString name = users_model->data (users_model->index (i, 0), QLightDM::UsersModel::NameRole).toString ();
192             status_notify ("%s LOG-USER USERNAME=%s", greeter_id, qPrintable (name));
193         }
194     }
195
196     else if (strcmp (name, "GET-CAN-SUSPEND") == 0)
197     {
198         gboolean can_suspend = power->canSuspend ();
199         status_notify ("%s CAN-SUSPEND ALLOWED=%s", greeter_id, can_suspend ? "TRUE" : "FALSE");
200     }
201
202     else if (strcmp (name, "SUSPEND") == 0)
203     {
204         if (!power->suspend ())
205             status_notify ("%s FAIL-SUSPEND", greeter_id);
206     }
207
208     else if (strcmp (name, "GET-CAN-HIBERNATE") == 0)
209     {
210         gboolean can_hibernate = power->canHibernate ();
211         status_notify ("%s CAN-HIBERNATE ALLOWED=%s", greeter_id, can_hibernate ? "TRUE" : "FALSE");
212     }
213
214     else if (strcmp (name, "HIBERNATE") == 0)
215     {
216         if (!power->hibernate ())
217             status_notify ("%s FAIL-HIBERNATE", greeter_id);
218     }
219
220     else if (strcmp (name, "GET-CAN-RESTART") == 0)
221     {
222         gboolean can_restart = power->canRestart ();
223         status_notify ("%s CAN-RESTART ALLOWED=%s", greeter_id, can_restart ? "TRUE" : "FALSE");
224     }
225
226     else if (strcmp (name, "RESTART") == 0)
227     {
228         if (!power->restart ())
229             status_notify ("%s FAIL-RESTART", greeter_id);
230     }
231
232     else if (strcmp (name, "GET-CAN-SHUTDOWN") == 0)
233     {
234         gboolean can_shutdown = power->canShutdown ();
235         status_notify ("%s CAN-SHUTDOWN ALLOWED=%s", greeter_id, can_shutdown ? "TRUE" : "FALSE");
236     }
237
238     else if (strcmp (name, "SHUTDOWN") == 0)
239     {
240         if (!power->shutdown ())
241             status_notify ("%s FAIL-SHUTDOWN", greeter_id);
242     }
243 }
244
245 int
246 main(int argc, char *argv[])
247 {
248     gchar *display, *xdg_seat, *xdg_vtnr, *xdg_session_cookie, *xdg_session_class;
249     GString *status_text;   
250
251 #if !defined(GLIB_VERSION_2_36)
252     g_type_init ();
253 #endif
254
255     display = getenv ("DISPLAY");
256     xdg_seat = getenv ("XDG_SEAT");
257     xdg_vtnr = getenv ("XDG_VTNR");
258     xdg_session_cookie = getenv ("XDG_SESSION_COOKIE");
259     xdg_session_class = getenv ("XDG_SESSION_CLASS");
260     if (display)
261     {
262         if (display[0] == ':')
263             greeter_id = g_strdup_printf ("GREETER-X-%s", display + 1);
264         else
265             greeter_id = g_strdup_printf ("GREETER-X-%s", display);
266     }
267     else
268         greeter_id = g_strdup ("GREETER-?");
269
270     status_connect (request_cb, greeter_id);
271
272     /* Workaround for Qt being confused by libsystem */
273 #if QT_VERSION >= QT_VERSION_CHECK (5, 3, 0)
274     QCoreApplication::setSetuidAllowed (true);
275 #endif  
276
277     app = new QCoreApplication (argc, argv);
278
279     signal (SIGINT, signal_cb);
280     signal (SIGTERM, signal_cb);
281
282     status_text = g_string_new ("");
283     g_string_printf (status_text, "%s START", greeter_id);
284     if (xdg_seat)
285         g_string_append_printf (status_text, " XDG_SEAT=%s", xdg_seat);
286     if (xdg_vtnr)
287         g_string_append_printf (status_text, " XDG_VTNR=%s", xdg_vtnr);
288     if (xdg_session_cookie)
289         g_string_append_printf (status_text, " XDG_SESSION_COOKIE=%s", xdg_session_cookie);
290     if (xdg_session_class)
291         g_string_append_printf (status_text, " XDG_SESSION_CLASS=%s", xdg_session_class);
292     status_notify ("%s", status_text->str);
293     g_string_free (status_text, TRUE);
294
295     config = new QSettings (g_build_filename (getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), QSettings::IniFormat);
296
297     if (display)
298     {
299         xcb_connection_t *connection = xcb_connect (NULL, NULL);
300         if (xcb_connection_has_error (connection))
301         {
302             status_notify ("%s FAIL-CONNECT-XSERVER", greeter_id);
303             return EXIT_FAILURE;
304         }
305         status_notify ("%s CONNECT-XSERVER", greeter_id);
306     }
307
308     power = new QLightDM::PowerInterface();
309
310     greeter = new TestGreeter();
311     if (config->value ("test-greeter-config/resettable", "false") == "true")
312     {
313         greeter->setResettable (true);
314         QObject::connect (greeter, SIGNAL(idle()), greeter, SLOT(idle()));
315         QObject::connect (greeter, SIGNAL(reset()), greeter, SLOT(reset()));
316     }
317
318     users_model = new QLightDM::UsersModel();
319     if (config->value ("test-greeter-config/log-user-changes", "false") == "true")
320     {
321         QObject::connect (users_model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), greeter, SLOT(userRowsInserted(const QModelIndex&, int, int)));
322         QObject::connect (users_model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), greeter, SLOT(userRowsRemoved(const QModelIndex&, int, int)));
323     }
324
325     status_notify ("%s CONNECT-TO-DAEMON", greeter_id);
326     if (!greeter->connectSync())
327     {
328         status_notify ("%s FAIL-CONNECT-DAEMON", greeter_id);
329         return EXIT_FAILURE;
330     }
331
332     status_notify ("%s CONNECTED-TO-DAEMON", greeter_id);
333
334     greeter->printHints();
335
336     return app->exec();
337 }