~lightdm-team/lightdm/1.4

« back to all changes in this revision

Viewing changes to tests/src/test-runner.c

  • Committer: Robert Ancell
  • Date: 2013-08-22 03:18:34 UTC
  • Revision ID: robert.ancell@canonical.com-20130822031834-50l2i7tedbs1lre3
Backport test improvements from trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#include <pwd.h>
13
13
 
14
14
/* Timeout in ms waiting for the status we expect */
15
 
#define STATUS_TIMEOUT 4000
 
15
static int status_timeout_ms = 4000;
16
16
 
17
17
/* Timeout in ms to wait for SIGTERM to be handled by a child process */
18
18
#define KILL_TIMEOUT 2000
55
55
    gchar *language;
56
56
    gchar *xsession;
57
57
    gchar **layouts;
 
58
    gboolean hidden;
58
59
} AccountsUser;
59
60
static GList *accounts_users = NULL;
60
61
static void handle_user_call (GDBusConnection       *connection,
84
85
    gchar *cookie;
85
86
    gchar *path;
86
87
    guint id;
 
88
    gboolean locked;
87
89
} CKSession;
88
90
static GList *ck_sessions = NULL;
89
91
static gint ck_session_index = 0;
99
101
{
100
102
    handle_ck_session_call,
101
103
};
 
104
 
 
105
typedef struct
 
106
{
 
107
    gchar *path;
 
108
    guint pid;
 
109
    gboolean locked;
 
110
} Login1Session;
 
111
 
 
112
static GList *login1_sessions = NULL;
 
113
static gint login1_session_index = 0;
 
114
 
102
115
typedef struct
103
116
{
104
117
    GSocket *socket;
109
122
static void run_lightdm (void);
110
123
static void quit (int status);
111
124
static void check_status (const gchar *status);
 
125
static AccountsUser *get_accounts_user_by_uid (guint uid);
 
126
static AccountsUser *get_accounts_user_by_name (const gchar *username);
 
127
static void accounts_user_set_hidden (AccountsUser *user, gboolean hidden, gboolean emit_signal);
112
128
 
113
129
static gboolean
114
130
kill_timeout_cb (gpointer data)
138
154
{
139
155
    Process *process;
140
156
    gchar *status_text;
141
 
  
 
157
 
142
158
    if (getenv ("DEBUG"))
143
159
    {
144
160
        if (WIFEXITED (status))
177
193
static Process *
178
194
watch_process (pid_t pid)
179
195
{
180
 
    Process *process;  
 
196
    Process *process;
181
197
 
182
198
    process = g_malloc0 (sizeof (Process));
183
199
    process->pid = pid;
381
397
    {
382
398
        sleep (1);
383
399
    }
 
400
    else if (strcmp (name, "LIST-SEATS") == 0)
 
401
    {
 
402
        GVariant *result, *value;
 
403
        GString *status;
 
404
        GVariantIter *iter;
 
405
        const gchar *path;
 
406
        int i = 0;
 
407
 
 
408
        result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
409
                                              "org.freedesktop.DisplayManager",
 
410
                                              "/org/freedesktop/DisplayManager",
 
411
                                              "org.freedesktop.DBus.Properties",
 
412
                                              "Get",
 
413
                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Seats"),
 
414
                                              G_VARIANT_TYPE ("(v)"),
 
415
                                              G_DBUS_CALL_FLAGS_NONE,
 
416
                                              1000,
 
417
                                              NULL,
 
418
                                              NULL);
 
419
 
 
420
        status = g_string_new ("RUNNER LIST-SEATS SEATS=");
 
421
        g_variant_get (result, "(v)", &value);
 
422
        g_variant_get (value, "ao", &iter);
 
423
        while (g_variant_iter_loop (iter, "&o", &path))
 
424
        {
 
425
            if (i != 0)
 
426
                g_string_append (status, ",");
 
427
            g_string_append (status, path);
 
428
            i++;
 
429
        }
 
430
        g_variant_unref (value);
 
431
        g_variant_unref (result);
 
432
 
 
433
        check_status (status->str);
 
434
        g_string_free (status, TRUE);
 
435
    }
 
436
    else if (strcmp (name, "LIST-SESSIONS") == 0)
 
437
    {
 
438
        GVariant *result, *value;
 
439
        GString *status;
 
440
        GVariantIter *iter;
 
441
        const gchar *path;
 
442
        int i = 0;
 
443
 
 
444
        result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
445
                                              "org.freedesktop.DisplayManager",
 
446
                                              "/org/freedesktop/DisplayManager",
 
447
                                              "org.freedesktop.DBus.Properties",
 
448
                                              "Get",
 
449
                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Sessions"),
 
450
                                              G_VARIANT_TYPE ("(v)"),
 
451
                                              G_DBUS_CALL_FLAGS_NONE,
 
452
                                              1000,
 
453
                                              NULL,
 
454
                                              NULL);
 
455
 
 
456
        status = g_string_new ("RUNNER LIST-SESSIONS SESSIONS=");
 
457
        g_variant_get (result, "(v)", &value);
 
458
        g_variant_get (value, "ao", &iter);
 
459
        while (g_variant_iter_loop (iter, "&o", &path))
 
460
        {
 
461
            if (i != 0)
 
462
                g_string_append (status, ",");
 
463
            g_string_append (status, path);
 
464
            i++;
 
465
        }
 
466
        g_variant_unref (value);
 
467
        g_variant_unref (result);
 
468
 
 
469
        check_status (status->str);
 
470
        g_string_free (status, TRUE);
 
471
    }
384
472
    else if (strcmp (name, "SWITCH-TO-GREETER") == 0)
385
473
    {
386
474
        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
399
487
    else if (strcmp (name, "SWITCH-TO-USER") == 0)
400
488
    {
401
489
        gchar *status_text, *username;
402
 
          
 
490
 
403
491
        username = g_hash_table_lookup (params, "USERNAME");
404
492
        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
405
493
                                     "org.freedesktop.DisplayManager",
484
572
            g_hash_table_insert (children, GINT_TO_POINTER (process->pid), process);
485
573
        }
486
574
    }
 
575
    else if (strcmp (name, "ADD-USER") == 0)
 
576
    {
 
577
        gchar *status_text, *username;
 
578
        AccountsUser *user;
 
579
 
 
580
        username = g_hash_table_lookup (params, "USERNAME");
 
581
        user = get_accounts_user_by_name (username);
 
582
        if (user)
 
583
            accounts_user_set_hidden (user, FALSE, TRUE);
 
584
        else
 
585
            g_warning ("Unknown user %s", username);
 
586
 
 
587
        status_text = g_strdup_printf ("RUNNER ADD-USER USERNAME=%s", username);
 
588
        check_status (status_text);
 
589
        g_free (status_text);
 
590
    }
 
591
    else if (strcmp (name, "DELETE-USER") == 0)
 
592
    {
 
593
        gchar *status_text, *username;
 
594
        AccountsUser *user;
 
595
 
 
596
        username = g_hash_table_lookup (params, "USERNAME");
 
597
        user = get_accounts_user_by_name (username);
 
598
        if (user)
 
599
            accounts_user_set_hidden (user, TRUE, TRUE);
 
600
        else
 
601
            g_warning ("Unknown user %s", username);
 
602
 
 
603
        status_text = g_strdup_printf ("RUNNER DELETE-USER USERNAME=%s", username);
 
604
        check_status (status_text);
 
605
        g_free (status_text);
 
606
    }
487
607
    /* Forward to external processes */
488
608
    else if (g_str_has_prefix (name, "SESSION-") ||
489
609
             g_str_has_prefix (name, "GREETER-") ||
495
615
            StatusClient *client = link->data;
496
616
            int length;
497
617
            GError *error = NULL;
498
 
      
 
618
 
499
619
            length = strlen (command);
500
 
            g_socket_send (client->socket, (gchar *) &length, sizeof (length), NULL, &error);
501
 
            g_socket_send (client->socket, command, strlen (command), NULL, &error);
502
 
            if (error)
 
620
            if (g_socket_send (client->socket, (gchar *) &length, sizeof (length), NULL, &error) < 0 ||
 
621
                g_socket_send (client->socket, command, strlen (command), NULL, &error) < 0)
503
622
                g_printerr ("Failed to write to client socket: %s\n", error->message);
504
623
            g_clear_error (&error);
505
 
        }     
 
624
        }
506
625
    }
507
626
    else
508
627
    {
509
628
        g_printerr ("Unknown command '%s'\n", name);
510
629
        quit (EXIT_FAILURE);
511
630
    }
512
 
  
 
631
 
513
632
    g_free (name);
514
633
    g_hash_table_unref (params);
515
634
}
558
677
 
559
678
    if (stop)
560
679
        return;
561
 
  
 
680
 
562
681
    statuses = g_list_append (statuses, g_strdup (status));
563
 
  
 
682
 
564
683
    if (getenv ("DEBUG"))
565
684
        g_print ("%s\n", status);
566
685
 
574
693
        result = g_regex_match_simple (full_pattern, status, 0, 0);
575
694
        g_free (full_pattern);
576
695
    }
577
 
  
 
696
 
578
697
    if (!result)
579
698
    {
580
699
        if (line == NULL)
587
706
 
588
707
    /* Restart timeout */
589
708
    g_source_remove (status_timeout);
590
 
    status_timeout = g_timeout_add (STATUS_TIMEOUT, status_timeout_cb, NULL);
 
709
    status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
591
710
 
592
711
    run_commands ();
593
712
}
679
798
    g_strfreev (lines);
680
799
}
681
800
 
 
801
static void
 
802
handle_upower_call (GDBusConnection       *connection,
 
803
                    const gchar           *sender,
 
804
                    const gchar           *object_path,
 
805
                    const gchar           *interface_name,
 
806
                    const gchar           *method_name,
 
807
                    GVariant              *parameters,
 
808
                    GDBusMethodInvocation *invocation,
 
809
                    gpointer               user_data)
 
810
{
 
811
    if (strcmp (method_name, "SuspendAllowed") == 0)
 
812
    {
 
813
        check_status ("UPOWER SUSPEND-ALLOWED");
 
814
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", TRUE));
 
815
    }
 
816
    else if (strcmp (method_name, "Suspend") == 0)
 
817
    {
 
818
        check_status ("UPOWER SUSPEND");
 
819
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
820
    }
 
821
    else if (strcmp (method_name, "HibernateAllowed") == 0)
 
822
    {
 
823
        check_status ("UPOWER HIBERNATE-ALLOWED");
 
824
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", TRUE));
 
825
    }
 
826
    else if (strcmp (method_name, "Hibernate") == 0)
 
827
    {
 
828
        check_status ("UPOWER HIBERNATE");
 
829
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
830
    }
 
831
    else
 
832
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
 
833
}
 
834
 
 
835
static void
 
836
upower_name_acquired_cb (GDBusConnection *connection,
 
837
                         const gchar     *name,
 
838
                         gpointer         user_data)
 
839
{
 
840
    const gchar *upower_interface =
 
841
        "<node>"
 
842
        "  <interface name='org.freedesktop.UPower'>"
 
843
        "    <method name='SuspendAllowed'>"
 
844
        "      <arg name='allowed' direction='out' type='b'/>"
 
845
        "    </method>"
 
846
        "    <method name='Suspend'/>"
 
847
        "    <method name='HibernateAllowed'>"
 
848
        "      <arg name='allowed' direction='out' type='b'/>"
 
849
        "    </method>"
 
850
        "    <method name='Hibernate'/>"
 
851
        "  </interface>"
 
852
        "</node>";
 
853
    static const GDBusInterfaceVTable upower_vtable =
 
854
    {
 
855
        handle_upower_call,
 
856
    };
 
857
    GDBusNodeInfo *upower_info;
 
858
    GError *error = NULL;
 
859
 
 
860
    upower_info = g_dbus_node_info_new_for_xml (upower_interface, &error);
 
861
    if (error)
 
862
        g_warning ("Failed to parse D-Bus interface: %s", error->message);
 
863
    g_clear_error (&error);
 
864
    if (!upower_info)
 
865
        return;
 
866
    g_dbus_connection_register_object (connection,
 
867
                                       "/org/freedesktop/UPower",
 
868
                                       upower_info->interfaces[0],
 
869
                                       &upower_vtable,
 
870
                                       NULL, NULL,
 
871
                                       &error);
 
872
    if (error)
 
873
        g_warning ("Failed to register UPower service: %s", error->message);
 
874
    g_clear_error (&error);
 
875
    g_dbus_node_info_unref (upower_info);
 
876
 
 
877
    service_count--;
 
878
    if (service_count == 0)
 
879
        run_lightdm ();
 
880
}
 
881
 
 
882
static void
 
883
start_upower_daemon (void)
 
884
{
 
885
    service_count++;
 
886
    g_bus_own_name (G_BUS_TYPE_SYSTEM,
 
887
                    "org.freedesktop.UPower",
 
888
                    G_BUS_NAME_OWNER_FLAGS_NONE,
 
889
                    upower_name_acquired_cb,
 
890
                    NULL,
 
891
                    NULL,
 
892
                    NULL,
 
893
                    NULL);
 
894
}
 
895
 
682
896
static CKSession *
683
897
open_ck_session (GVariant *params)
684
898
{
798
1012
                        GDBusMethodInvocation *invocation,
799
1013
                        gpointer               user_data)
800
1014
{
 
1015
    CKSession *session = user_data;
 
1016
 
801
1017
    if (strcmp (method_name, "Lock") == 0)
 
1018
    { 
 
1019
        if (!session->locked)
 
1020
            check_status ("CONSOLE-KIT LOCK-SESSION");
 
1021
        session->locked = TRUE;
802
1022
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1023
    }
803
1024
    else if (strcmp (method_name, "Unlock") == 0)
 
1025
    {
 
1026
        if (session->locked)
 
1027
            check_status ("CONSOLE-KIT UNLOCK-SESSION");
 
1028
        session->locked = FALSE;
804
1029
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1030
    }
805
1031
    else
806
1032
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
807
1033
}
863
1089
 
864
1090
    ck_info = g_dbus_node_info_new_for_xml (ck_interface, &error);
865
1091
    if (error)
866
 
        g_warning ("Failed to parse D-Bus interface: %s", error->message);  
 
1092
        g_warning ("Failed to parse D-Bus interface: %s", error->message);
867
1093
    g_clear_error (&error);
868
1094
    if (!ck_info)
869
1095
        return;
870
1096
    ck_session_info = g_dbus_node_info_new_for_xml (ck_session_interface, &error);
871
1097
    if (error)
872
 
        g_warning ("Failed to parse D-Bus interface: %s", error->message);  
 
1098
        g_warning ("Failed to parse D-Bus interface: %s", error->message);
873
1099
    g_clear_error (&error);
874
1100
    if (!ck_session_info)
875
1101
        return;
904
1130
}
905
1131
 
906
1132
static void
 
1133
handle_login1_session_call (GDBusConnection       *connection,
 
1134
                            const gchar           *sender,
 
1135
                            const gchar           *object_path,
 
1136
                            const gchar           *interface_name,
 
1137
                            const gchar           *method_name,
 
1138
                            GVariant              *parameters,
 
1139
                            GDBusMethodInvocation *invocation,
 
1140
                            gpointer               user_data)
 
1141
{
 
1142
    Login1Session *session = user_data;
 
1143
 
 
1144
    if (strcmp (method_name, "Lock") == 0)
 
1145
    {
 
1146
        if (!session->locked)
 
1147
            check_status ("LOGIN1 LOCK-SESSION");
 
1148
        session->locked = TRUE;
 
1149
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1150
    }
 
1151
    else if (strcmp (method_name, "Unlock") == 0)
 
1152
    {
 
1153
        if (session->locked)
 
1154
            check_status ("LOGIN1 UNLOCK-SESSION");
 
1155
        session->locked = FALSE;
 
1156
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1157
    }
 
1158
    else
 
1159
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
 
1160
}
 
1161
 
 
1162
static Login1Session *
 
1163
open_login1_session (GDBusConnection *connection,
 
1164
                     GVariant *params)
 
1165
{
 
1166
    Login1Session *session;
 
1167
    GError *error = NULL;
 
1168
    GDBusNodeInfo *login1_session_info;
 
1169
 
 
1170
    const gchar *login1_session_interface =
 
1171
        "<node>"
 
1172
        "  <interface name='org.freedesktop.login1.Session'>"
 
1173
        "    <method name='Lock'/>"
 
1174
        "    <method name='Unlock'/>"
 
1175
        "  </interface>"
 
1176
        "</node>";
 
1177
    static const GDBusInterfaceVTable login1_session_vtable =
 
1178
    {
 
1179
        handle_login1_session_call,
 
1180
    };
 
1181
 
 
1182
    session = g_malloc0 (sizeof (Login1Session));
 
1183
    login1_sessions = g_list_append (login1_sessions, session);
 
1184
 
 
1185
    session->path = g_strdup_printf("/org/freedesktop/login1/Session/c%d",
 
1186
                                    login1_session_index++);
 
1187
 
 
1188
 
 
1189
 
 
1190
    login1_session_info = g_dbus_node_info_new_for_xml (login1_session_interface,
 
1191
                                                        &error);
 
1192
    if (error)
 
1193
        g_warning ("Failed to parse login1 session D-Bus interface: %s",
 
1194
                   error->message);
 
1195
    g_clear_error (&error);
 
1196
    if (!login1_session_info)
 
1197
        return NULL;
 
1198
 
 
1199
    g_dbus_connection_register_object (connection,
 
1200
                                       session->path,
 
1201
                                       login1_session_info->interfaces[0],
 
1202
                                       &login1_session_vtable,
 
1203
                                       session,
 
1204
                                       NULL,
 
1205
                                       &error);
 
1206
    if (error)
 
1207
        g_warning ("Failed to register login1 session: %s", error->message);
 
1208
    g_clear_error (&error);
 
1209
    g_dbus_node_info_unref (login1_session_info);
 
1210
 
 
1211
    return session;
 
1212
}
 
1213
 
 
1214
 
 
1215
static void
 
1216
handle_login1_call (GDBusConnection       *connection,
 
1217
                    const gchar           *sender,
 
1218
                    const gchar           *object_path,
 
1219
                    const gchar           *interface_name,
 
1220
                    const gchar           *method_name,
 
1221
                    GVariant              *parameters,
 
1222
                    GDBusMethodInvocation *invocation,
 
1223
                    gpointer               user_data)
 
1224
{
 
1225
 
 
1226
    if (strcmp (method_name, "GetSessionByPID") == 0)
 
1227
    {
 
1228
        /* Look for a session with our PID, and create one if we don't have one
 
1229
           already. */
 
1230
        GList *link;
 
1231
        guint pid;
 
1232
        Login1Session *ret = NULL;
 
1233
 
 
1234
        g_variant_get (parameters, "(u)", &pid);
 
1235
 
 
1236
        for (link = login1_sessions; link; link = link->next)
 
1237
        {
 
1238
            Login1Session *session;
 
1239
            session = link->data;
 
1240
            if (session->pid == pid)
 
1241
            {
 
1242
                ret = session;
 
1243
                break;
 
1244
            }
 
1245
        }
 
1246
        /* Not found */
 
1247
        if (!ret)
 
1248
            ret = open_login1_session (connection, parameters);
 
1249
 
 
1250
        g_dbus_method_invocation_return_value (invocation,
 
1251
                                               g_variant_new("(o)", ret->path));
 
1252
 
 
1253
    }
 
1254
    else if (strcmp (method_name, "CanReboot") == 0)
 
1255
    {
 
1256
        check_status ("LOGIN1 CAN-REBOOT");
 
1257
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "yes"));
 
1258
    }
 
1259
    else if (strcmp (method_name, "Reboot") == 0)
 
1260
    {
 
1261
        gboolean interactive;
 
1262
        g_variant_get (parameters, "(b)", &interactive);
 
1263
        check_status ("LOGIN1 REBOOT");
 
1264
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1265
    }
 
1266
    else if (strcmp (method_name, "CanPowerOff") == 0)
 
1267
    {
 
1268
        check_status ("LOGIN1 CAN-POWER-OFF");
 
1269
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "yes"));
 
1270
    }
 
1271
    else if (strcmp (method_name, "Suspend") == 0)
 
1272
    {
 
1273
        gboolean interactive;
 
1274
        g_variant_get (parameters, "(b)", &interactive);
 
1275
        check_status ("LOGIN1 SUSPEND");
 
1276
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1277
    }
 
1278
    else if (strcmp (method_name, "CanSuspend") == 0)
 
1279
    {
 
1280
        check_status ("LOGIN1 CAN-SUSPEND");
 
1281
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "yes"));
 
1282
    }
 
1283
    else if (strcmp (method_name, "PowerOff") == 0)
 
1284
    {
 
1285
        gboolean interactive;
 
1286
        g_variant_get (parameters, "(b)", &interactive);
 
1287
        check_status ("LOGIN1 POWER-OFF");
 
1288
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1289
    }
 
1290
    else if (strcmp (method_name, "CanHibernate") == 0)
 
1291
    {
 
1292
        check_status ("LOGIN1 CAN-HIBERNATE");
 
1293
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "yes"));
 
1294
    }
 
1295
    else if (strcmp (method_name, "Hibernate") == 0)
 
1296
    {
 
1297
        gboolean interactive;
 
1298
        g_variant_get (parameters, "(b)", &interactive);
 
1299
        check_status ("LOGIN1 HIBERNATE");
 
1300
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1301
    }
 
1302
    else
 
1303
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
 
1304
}
 
1305
 
 
1306
static void
 
1307
login1_name_acquired_cb (GDBusConnection *connection,
 
1308
                         const gchar     *name,
 
1309
                         gpointer         user_data)
 
1310
{
 
1311
    const gchar *login1_interface =
 
1312
        "<node>"
 
1313
        "  <interface name='org.freedesktop.login1.Manager'>"
 
1314
        "    <method name='GetSessionByPID'>"
 
1315
        "      <arg name='pid' type='u' direction='in'/>"
 
1316
        "      <arg name='session' type='o' direction='out'/>"
 
1317
        "    </method>"
 
1318
        "    <method name='CanReboot'>"
 
1319
        "      <arg name='result' direction='out' type='s'/>"
 
1320
        "    </method>"
 
1321
        "    <method name='Reboot'>"
 
1322
        "      <arg name='interactive' direction='in' type='b'/>"
 
1323
        "    </method>"
 
1324
        "    <method name='CanPowerOff'>"
 
1325
        "      <arg name='result' direction='out' type='s'/>"
 
1326
        "    </method>"
 
1327
        "    <method name='PowerOff'>"
 
1328
        "      <arg name='interactive' direction='in' type='b'/>"
 
1329
        "    </method>"
 
1330
        "    <method name='CanSuspend'>"
 
1331
        "      <arg name='result' direction='out' type='s'/>"
 
1332
        "    </method>"
 
1333
        "    <method name='Suspend'>"
 
1334
        "      <arg name='interactive' direction='in' type='b'/>"
 
1335
        "    </method>"
 
1336
        "    <method name='CanHibernate'>"
 
1337
        "      <arg name='result' direction='out' type='s'/>"
 
1338
        "    </method>"
 
1339
        "    <method name='Hibernate'>"
 
1340
        "      <arg name='interactive' direction='in' type='b'/>"
 
1341
        "    </method>"
 
1342
        "  </interface>"
 
1343
        "</node>";
 
1344
    static const GDBusInterfaceVTable login1_vtable =
 
1345
    {
 
1346
        handle_login1_call,
 
1347
    };
 
1348
    GDBusNodeInfo *login1_info;
 
1349
    GError *error = NULL;
 
1350
 
 
1351
    login1_info = g_dbus_node_info_new_for_xml (login1_interface, &error);
 
1352
    if (error)
 
1353
        g_warning ("Failed to parse login1 D-Bus interface: %s", error->message);
 
1354
    g_clear_error (&error);
 
1355
    if (!login1_info)
 
1356
        return;
 
1357
    g_dbus_connection_register_object (connection,
 
1358
                                       "/org/freedesktop/login1",
 
1359
                                       login1_info->interfaces[0],
 
1360
                                       &login1_vtable,
 
1361
                                       NULL, NULL,
 
1362
                                       &error);
 
1363
    if (error)
 
1364
        g_warning ("Failed to register login1 service: %s", error->message);
 
1365
    g_clear_error (&error);
 
1366
    g_dbus_node_info_unref (login1_info);
 
1367
 
 
1368
    service_count--;
 
1369
    if (service_count == 0)
 
1370
        run_lightdm ();
 
1371
}
 
1372
 
 
1373
static void
 
1374
start_login1_daemon (void)
 
1375
{
 
1376
    service_count++;
 
1377
    g_bus_own_name (G_BUS_TYPE_SYSTEM,
 
1378
                    "org.freedesktop.login1",
 
1379
                    G_BUS_NAME_OWNER_FLAGS_NONE,
 
1380
                    login1_name_acquired_cb,
 
1381
                    NULL,
 
1382
                    NULL,
 
1383
                    NULL,
 
1384
                    NULL);
 
1385
}
 
1386
 
 
1387
static AccountsUser *
 
1388
get_accounts_user_by_uid (guint uid)
 
1389
{
 
1390
    GList *link;
 
1391
 
 
1392
    for (link = accounts_users; link; link = link->next)
 
1393
    {
 
1394
        AccountsUser *u = link->data;
 
1395
        if (u->uid == uid)
 
1396
            return u;
 
1397
    }
 
1398
  
 
1399
    return NULL;
 
1400
}
 
1401
 
 
1402
static AccountsUser *
 
1403
get_accounts_user_by_name (const gchar *username)
 
1404
{
 
1405
    GList *link;
 
1406
 
 
1407
    for (link = accounts_users; link; link = link->next)
 
1408
    {
 
1409
        AccountsUser *u = link->data;
 
1410
        if (strcmp (u->user_name, username) == 0)
 
1411
            return u;
 
1412
    }
 
1413
 
 
1414
    return NULL;
 
1415
}
 
1416
 
 
1417
static void
 
1418
accounts_user_set_hidden (AccountsUser *user, gboolean hidden, gboolean emit_signal)
 
1419
{
 
1420
    GError *error = NULL;
 
1421
 
 
1422
    user->hidden = hidden;
 
1423
 
 
1424
    if (user->hidden && user->id != 0)
 
1425
    {
 
1426
        g_dbus_connection_unregister_object (accounts_connection, user->id);
 
1427
        g_dbus_connection_emit_signal (accounts_connection,
 
1428
                                       NULL,
 
1429
                                       "/org/freedesktop/Accounts",
 
1430
                                       "org.freedesktop.Accounts",
 
1431
                                       "UserDeleted",
 
1432
                                       g_variant_new ("(o)", user->path),
 
1433
                                       &error);
 
1434
        if (error)
 
1435
            g_warning ("Failed to emit UserDeleted: %s", error->message);
 
1436
        g_clear_error (&error);
 
1437
 
 
1438
        user->id = 0;
 
1439
    }
 
1440
    if (!user->hidden && user->id == 0)
 
1441
    {
 
1442
        user->id = g_dbus_connection_register_object (accounts_connection,
 
1443
                                                      user->path,
 
1444
                                                      user_info->interfaces[0],
 
1445
                                                      &user_vtable,
 
1446
                                                      user,
 
1447
                                                      NULL,
 
1448
                                                      &error);
 
1449
        if (error)
 
1450
            g_warning ("Failed to register user: %s", error->message);
 
1451
        g_clear_error (&error);
 
1452
 
 
1453
        g_dbus_connection_emit_signal (accounts_connection,
 
1454
                                       NULL,
 
1455
                                       "/org/freedesktop/Accounts",
 
1456
                                       "org.freedesktop.Accounts",
 
1457
                                       "UserAdded",
 
1458
                                       g_variant_new ("(o)", user->path),
 
1459
                                       &error);
 
1460
        if (error)
 
1461
            g_warning ("Failed to emit UserAdded: %s", error->message);
 
1462
        g_clear_error (&error);
 
1463
    }
 
1464
}
 
1465
 
 
1466
static void
907
1467
load_passwd_file (void)
908
1468
{
909
1469
    gchar *path, *data, **lines;
 
1470
    gchar **user_filter = NULL;
910
1471
    int i;
911
1472
 
 
1473
    if (g_key_file_has_key (config, "test-runner-config", "accounts-service-user-filter", NULL))
 
1474
    {
 
1475
        gchar *filter;
 
1476
 
 
1477
        filter = g_key_file_get_string (config, "test-runner-config", "accounts-service-user-filter", NULL);
 
1478
        user_filter = g_strsplit (filter, " ", -1);
 
1479
        g_free (filter);
 
1480
    }
 
1481
 
912
1482
    path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "passwd", NULL);
913
1483
    g_file_get_contents (path, &data, NULL, NULL);
914
1484
    g_free (path);
920
1490
        gchar **fields;
921
1491
        guint uid;
922
1492
        gchar *user_name, *real_name;
923
 
        GList *link;
924
1493
        AccountsUser *user = NULL;
925
 
        GError *error = NULL;
926
1494
 
927
1495
        fields = g_strsplit (lines[i], ":", -1);
928
1496
        if (fields == NULL || g_strv_length (fields) < 7)
935
1503
        uid = atoi (fields[2]);
936
1504
        real_name = fields[4];
937
1505
 
938
 
        for (link = accounts_users; link; link = link->next)
939
 
        {
940
 
            AccountsUser *u = link->data;
941
 
            if (u->uid == uid)
942
 
            {
943
 
                user = u;
944
 
                break;
945
 
            }
946
 
        }
 
1506
        user = get_accounts_user_by_uid (uid);
947
1507
        if (!user)
948
1508
        {
949
1509
            gchar *path;
952
1512
            user = g_malloc0 (sizeof (AccountsUser));
953
1513
            accounts_users = g_list_append (accounts_users, user);
954
1514
 
 
1515
            /* Only allow users in whitelist */
 
1516
            user->hidden = FALSE;
 
1517
            if (user_filter)
 
1518
            {
 
1519
                int j;
 
1520
 
 
1521
                user->hidden = TRUE;
 
1522
                for (j = 0; user_filter[j] != NULL; j++)
 
1523
                    if (strcmp (user_name, user_filter[j]) == 0)
 
1524
                        user->hidden = FALSE;
 
1525
            }
 
1526
 
955
1527
            dmrc_file = g_key_file_new ();
956
1528
            path = g_build_filename (temp_dir, "home", user_name, ".dmrc", NULL);
957
1529
            g_key_file_load_from_file (dmrc_file, path, G_KEY_FILE_NONE, NULL);
972
1544
            user->xsession = g_key_file_get_string (dmrc_file, "Desktop", "Session", NULL);
973
1545
            user->layouts = g_key_file_get_string_list (dmrc_file, "X-Accounts", "Layouts", NULL, NULL);
974
1546
            user->path = g_strdup_printf ("/org/freedesktop/Accounts/User%d", uid);
975
 
            user->id = g_dbus_connection_register_object (accounts_connection,
976
 
                                                          user->path,
977
 
                                                          user_info->interfaces[0],
978
 
                                                          &user_vtable,
979
 
                                                          user,
980
 
                                                          NULL,
981
 
                                                          &error);
982
 
            if (error)
983
 
                g_warning ("Failed to register user: %s", error->message);
984
 
            g_clear_error (&error);
 
1547
            accounts_user_set_hidden (user, user->hidden, FALSE);
985
1548
 
986
1549
            g_key_file_free (dmrc_file);
987
1550
        }
1009
1572
 
1010
1573
        g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
1011
1574
 
1012
 
        load_passwd_file ();      
 
1575
        load_passwd_file ();
1013
1576
        for (link = accounts_users; link; link = link->next)
1014
1577
        {
1015
1578
            AccountsUser *user = link->data;
1016
 
            g_variant_builder_add_value (&builder, g_variant_new_object_path (user->path));
 
1579
            if (!user->hidden)
 
1580
                g_variant_builder_add_value (&builder, g_variant_new_object_path (user->path));
1017
1581
        }
1018
1582
 
1019
1583
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ao)", &builder));
1020
1584
    }
1021
1585
    else if (strcmp (method_name, "FindUserByName") == 0)
1022
1586
    {
1023
 
        GList *link;
1024
1587
        AccountsUser *user = NULL;
1025
1588
        gchar *user_name;
1026
1589
 
1027
1590
        g_variant_get (parameters, "(&s)", &user_name);
1028
1591
 
1029
1592
        load_passwd_file ();
1030
 
        for (link = accounts_users; link; link = link->next)
1031
 
        {
1032
 
            AccountsUser *u = link->data;
1033
 
            if (strcmp (u->user_name, user_name) == 0)
1034
 
            {
1035
 
                user = u;
1036
 
                break;
1037
 
            }
1038
 
        }
1039
 
        if (user)
 
1593
        user = get_accounts_user_by_name (user_name);
 
1594
        if (user && !user->hidden)
1040
1595
            g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", user->path));
1041
1596
        else
1042
1597
            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such user: %s", user_name);
1043
1598
    }
1044
1599
    else
1045
 
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);    
 
1600
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
1046
1601
}
1047
1602
 
1048
1603
static void
1123
1678
        "      <arg name='name' direction='in' type='s'/>"
1124
1679
        "      <arg name='user' direction='out' type='o'/>"
1125
1680
        "    </method>"
 
1681
        "    <signal name='UserAdded'>"
 
1682
        "      <arg name='user' type='o'/>"
 
1683
        "    </signal>"
 
1684
        "    <signal name='UserDeleted'>"
 
1685
        "      <arg name='user' type='o'/>"
 
1686
        "    </signal>"
1126
1687
        "  </interface>"
1127
1688
        "</node>";
1128
1689
    static const GDBusInterfaceVTable accounts_vtable =
1151
1712
 
1152
1713
    accounts_info = g_dbus_node_info_new_for_xml (accounts_interface, &error);
1153
1714
    if (error)
1154
 
        g_warning ("Failed to parse D-Bus interface: %s", error->message);  
 
1715
        g_warning ("Failed to parse D-Bus interface: %s", error->message);
1155
1716
    g_clear_error (&error);
1156
1717
    if (!accounts_info)
1157
1718
        return;
1158
1719
    user_info = g_dbus_node_info_new_for_xml (user_interface, &error);
1159
1720
    if (error)
1160
 
        g_warning ("Failed to parse D-Bus interface: %s", error->message);  
 
1721
        g_warning ("Failed to parse D-Bus interface: %s", error->message);
1161
1722
    g_clear_error (&error);
1162
1723
    if (!user_info)
1163
1724
        return;
1202
1763
 
1203
1764
    run_commands ();
1204
1765
 
1205
 
    status_timeout = g_timeout_add (STATUS_TIMEOUT, status_timeout_cb, NULL);
 
1766
    status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
1206
1767
 
1207
1768
    command_line = g_string_new ("lightdm");
1208
1769
    if (getenv ("DEBUG"))
1209
1770
        g_string_append (command_line, " --debug");
1210
1771
    g_string_append_printf (command_line, " --cache-dir %s/cache", temp_dir);
1211
 
    g_string_append_printf (command_line, " --xsessions-dir=%s/usr/share/xsessions", temp_dir);
1212
 
    g_string_append_printf (command_line, " --remote-sessions-dir=%s/usr/share/remote-sessions", temp_dir);
1213
 
    g_string_append_printf (command_line, " --xgreeters-dir=%s/usr/share/xgreeters", temp_dir);
1214
1772
 
1215
1773
    test_runner_command = g_strdup_printf ("PATH=%s LD_PRELOAD=%s LD_LIBRARY_PATH=%s LIGHTDM_TEST_ROOT=%s DBUS_SESSION_BUS_ADDRESS=%s %s\n",
1216
1774
                                           g_getenv ("PATH"), g_getenv ("LD_PRELOAD"), g_getenv ("LD_LIBRARY_PATH"), g_getenv ("LIGHTDM_TEST_ROOT"), g_getenv ("DBUS_SESSION_BUS_ADDRESS"),
1284
1842
        g_critical ("Error getting current directory: %s", strerror (errno));
1285
1843
        quit (EXIT_FAILURE);
1286
1844
    }
1287
 
  
 
1845
 
1288
1846
    /* Don't contact our X server */
1289
1847
    g_unsetenv ("DISPLAY");
1290
1848
 
1299
1857
    g_free (path);
1300
1858
 
1301
1859
    /* Use locally built libraries */
1302
 
    path1 = g_build_filename (BUILDDIR, "liblightdm-gobject", ".libs", NULL);  
 
1860
    path1 = g_build_filename (BUILDDIR, "liblightdm-gobject", ".libs", NULL);
1303
1861
    path2 = g_build_filename (BUILDDIR, "liblightdm-qt", ".libs", NULL);
1304
1862
    ld_library_path = g_strdup_printf ("%s:%s", path1, path2);
1305
1863
    g_free (path1);
1369
1927
    g_mkdir_with_parents (g_strdup_printf ("%s/etc", temp_dir), 0755);
1370
1928
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share", temp_dir), 0755);
1371
1929
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/xsessions", temp_dir), 0755);
1372
 
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/remote-sessions", temp_dir), 0755);
 
1930
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/remote-sessions", temp_dir), 0755);
1373
1931
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/xgreeters", temp_dir), 0755);
1374
1932
    g_mkdir_with_parents (g_strdup_printf ("%s/tmp", temp_dir), 0755);
1375
1933
    g_mkdir_with_parents (g_strdup_printf ("%s/var/run", temp_dir), 0755);
1383
1941
 
1384
1942
    /* Always copy the script */
1385
1943
    if (system (g_strdup_printf ("cp %s %s/script", config_path, temp_dir)))
1386
 
        perror ("Failed to copy configuration");  
 
1944
        perror ("Failed to copy configuration");
1387
1945
 
1388
1946
    /* Copy over the greeter files */
1389
1947
    if (system (g_strdup_printf ("cp %s/xsessions/* %s/usr/share/xsessions", DATADIR, temp_dir)))
1390
 
        perror ("Failed to copy xsessions");
1391
 
    if (system (g_strdup_printf ("cp %s/remote-sessions/* %s/usr/share/remote-sessions", DATADIR, temp_dir)))
 
1948
        perror ("Failed to copy sessions");
 
1949
    if (system (g_strdup_printf ("cp %s/remote-sessions/* %s/usr/share/lightdm/remote-sessions", DATADIR, temp_dir)))
1392
1950
        perror ("Failed to copy remote sessions");
1393
1951
    if (system (g_strdup_printf ("cp %s/xgreeters/* %s/usr/share/xgreeters", DATADIR, temp_dir)))
1394
 
        perror ("Failed to copy xgreeters");
 
1952
        perror ("Failed to copy greeters");
1395
1953
 
1396
1954
    /* Set up the default greeter */
1397
1955
    path = g_build_filename (temp_dir, "usr", "share", "xgreeters", "default.desktop", NULL);
1441
1999
        /* This account has a set of keyboard layouts */
1442
2000
        {"have-layouts",     "",         TRUE,  "Layouts User",       NULL,  "ru", "fr\toss;ru;", NULL,          1010},
1443
2001
        /* This account has a language set */
1444
 
        {"have-language",    "",         TRUE,  "Language User",      NULL,  NULL, NULL,          "en_AU.utf8",  1011},      
 
2002
        {"have-language",    "",         TRUE,  "Language User",      NULL,  NULL, NULL,          "en_AU.utf8",  1011},
1445
2003
        /* This account has a preconfigured session */
1446
2004
        {"have-session",            "",  TRUE,  "Session User", "alternative", NULL, NULL,        NULL,          1012},
1447
2005
        /* This account has the home directory mounted on login */
1529
2087
            data = g_key_file_to_data (dmrc_file, NULL, NULL);
1530
2088
            g_file_set_contents (path, data, -1, NULL);
1531
2089
            g_free (data);
1532
 
            g_free (path);         
 
2090
            g_free (path);
1533
2091
        }
1534
2092
 
1535
2093
        g_key_file_free (dmrc_file);
1553
2111
    g_free (path);
1554
2112
    g_string_free (group_data, TRUE);
1555
2113
 
 
2114
    if (g_key_file_has_key (config, "test-runner-config", "timeout", NULL))
 
2115
        status_timeout_ms = g_key_file_get_integer (config, "test-runner-config", "timeout", NULL) * 1000;
 
2116
 
1556
2117
    /* Start D-Bus services */
 
2118
    if (!g_key_file_get_boolean (config, "test-runner-config", "disable-upower", NULL))
 
2119
        start_upower_daemon ();
1557
2120
    if (!g_key_file_get_boolean (config, "test-runner-config", "disable-console-kit", NULL))
1558
2121
        start_console_kit_daemon ();
 
2122
    if (!g_key_file_get_boolean (config, "test-runner-config", "disable-login1", NULL))
 
2123
        start_login1_daemon ();
1559
2124
    if (!g_key_file_get_boolean (config, "test-runner-config", "disable-accounts-service", NULL))
1560
2125
        start_accounts_service_daemon ();
1561
2126