~robert-ancell/lightdm/docstrings

« back to all changes in this revision

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

  • Committer: Robert Ancell
  • Date: 2015-08-10 00:21:57 UTC
  • mfrom: (1709.1.454 trunk)
  • Revision ID: robert.ancell@canonical.com-20150810002157-39tqqq8wv006gwzq
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
    handle_user_call,
82
82
    handle_user_get_property,
83
83
};
84
 
static GDBusConnection *ck_connection = NULL;
85
84
static GDBusNodeInfo *ck_session_info;
86
85
typedef struct
87
86
{
107
106
 
108
107
typedef struct
109
108
{
 
109
    gchar *id;
 
110
    gchar *path;
 
111
    gboolean can_graphical;
 
112
    gboolean can_multi_session;
 
113
    gchar *active_session;
 
114
} Login1Seat;
 
115
 
 
116
static GList *login1_seats = NULL;
 
117
 
 
118
static Login1Seat *add_login1_seat (GDBusConnection *connection, const gchar *id, gboolean emit_signal);
 
119
static Login1Seat *find_login1_seat (const gchar *id);
 
120
static void remove_login1_seat (GDBusConnection *connection, const gchar *id);
 
121
 
 
122
typedef struct
 
123
{
 
124
    gchar *id;
110
125
    gchar *path;
111
126
    guint pid;
112
127
    gboolean locked;
122
137
} StatusClient;
123
138
static GList *status_clients = NULL;
124
139
 
125
 
static void run_lightdm (void);
 
140
static void ready (void);
126
141
static void quit (int status);
 
142
static gboolean status_timeout_cb (gpointer data);
127
143
static void check_status (const gchar *status);
128
144
static AccountsUser *get_accounts_user_by_uid (guint uid);
129
145
static AccountsUser *get_accounts_user_by_name (const gchar *username);
130
146
static void accounts_user_set_hidden (AccountsUser *user, gboolean hidden, gboolean emit_signal);
 
147
static Login1Session *find_login1_session (const gchar *id);
131
148
 
132
149
static gboolean
133
150
kill_timeout_cb (gpointer data)
134
151
{
135
152
    Process *process = data;
136
153
 
 
154
    process->kill_timeout = 0;
 
155
 
137
156
    if (getenv ("DEBUG"))
138
157
        g_print ("Sending SIGKILL to process %d\n", process->pid);
139
158
    kill (process->pid, SIGKILL);
 
159
 
140
160
    return FALSE;
141
161
}
142
162
 
319
339
    return NULL;
320
340
}
321
341
 
 
342
static gboolean
 
343
stop_loop (gpointer user_data)
 
344
{
 
345
    g_main_loop_quit ((GMainLoop *)user_data);
 
346
    return G_SOURCE_REMOVE;
 
347
}
 
348
 
 
349
static void
 
350
switch_to_greeter_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
 
351
{
 
352
    GVariant *r;
 
353
    GError *error = NULL;
 
354
 
 
355
    r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
 
356
    if (error)
 
357
        g_warning ("Failed to switch to greeter: %s\n", error->message);
 
358
    g_clear_error (&error);
 
359
 
 
360
    if (r)
 
361
    {
 
362
        check_status ("RUNNER SWITCH-TO-GREETER");
 
363
        g_variant_unref (r);
 
364
    }
 
365
    else
 
366
        check_status ("RUNNER SWITCH-TO-GREETER FAILED");
 
367
}
 
368
 
 
369
static void
 
370
switch_to_user_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
 
371
{
 
372
    GVariant *r;
 
373
    GError *error = NULL;
 
374
    gchar *username = data, *status_text;
 
375
 
 
376
    r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
 
377
    if (error)
 
378
        g_warning ("Failed to switch to user: %s\n", error->message);
 
379
    g_clear_error (&error);
 
380
 
 
381
    if (r)
 
382
    {
 
383
        status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s", username);
 
384
        g_variant_unref (r);
 
385
    }
 
386
    else
 
387
        status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s FAILED", username);
 
388
    check_status (status_text);
 
389
 
 
390
    g_free (status_text);
 
391
    g_free (username);
 
392
}
 
393
 
 
394
static void
 
395
switch_to_guest_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
 
396
{
 
397
    GVariant *r;
 
398
    GError *error = NULL;
 
399
 
 
400
    r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
 
401
    if (error)
 
402
        g_warning ("Failed to switch to guest: %s\n", error->message);
 
403
    g_clear_error (&error);
 
404
 
 
405
    if (r)
 
406
    {
 
407
        check_status ("RUNNER SWITCH-TO-GUEST");
 
408
        g_variant_unref (r);
 
409
    }
 
410
    else
 
411
        check_status ("RUNNER SWITCH-TO-GUEST FAILED");
 
412
}
 
413
 
322
414
static void
323
415
handle_command (const gchar *command)
324
416
{
396
488
        g_hash_table_insert (params, param_name, param_value);
397
489
    }
398
490
 
399
 
    if (strcmp (name, "WAIT") == 0)
400
 
    {
401
 
        sleep (1);
 
491
    if (strcmp (name, "START-DAEMON") == 0)
 
492
    {
 
493
        GString *command_line;
 
494
        gchar **lightdm_argv;
 
495
        pid_t lightdm_pid;
 
496
        GError *error = NULL;
 
497
 
 
498
        command_line = g_string_new ("lightdm");
 
499
        if (getenv ("DEBUG"))
 
500
            g_string_append (command_line, " --debug");
 
501
        g_string_append_printf (command_line, " --cache-dir %s/cache", temp_dir);
 
502
 
 
503
        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",
 
504
                                               g_getenv ("PATH"), g_getenv ("LD_PRELOAD"), g_getenv ("LD_LIBRARY_PATH"), g_getenv ("LIGHTDM_TEST_ROOT"), g_getenv ("DBUS_SESSION_BUS_ADDRESS"),
 
505
                                               command_line->str);
 
506
 
 
507
        if (!g_shell_parse_argv (command_line->str, NULL, &lightdm_argv, &error))
 
508
        {
 
509
            g_warning ("Error parsing command line: %s", error->message);
 
510
            quit (EXIT_FAILURE);
 
511
        }
 
512
        g_clear_error (&error);
 
513
 
 
514
        if (!g_spawn_async (NULL, lightdm_argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, &lightdm_pid, &error))
 
515
        {
 
516
            g_warning ("Error launching LightDM: %s", error->message);
 
517
            quit (EXIT_FAILURE);
 
518
        }
 
519
        g_clear_error (&error);
 
520
        lightdm_process = watch_process (lightdm_pid);
 
521
 
 
522
        check_status ("RUNNER DAEMON-START");
 
523
    }
 
524
    else if (strcmp (name, "WAIT") == 0)
 
525
    {
 
526
        const gchar *v;
 
527
        int duration;
 
528
 
 
529
        /* Stop status timeout */
 
530
        if (status_timeout)
 
531
            g_source_remove (status_timeout);
 
532
 
 
533
        /* Use a main loop so that our DBus functions are still responsive */
 
534
        GMainLoop *loop = g_main_loop_new (NULL, FALSE);
 
535
        v = g_hash_table_lookup (params, "DURATION");
 
536
        duration = v ? atoi (v) : 1;
 
537
        if (duration < 1)
 
538
            duration = 1;
 
539
        g_timeout_add_seconds (duration, stop_loop, loop);
 
540
        g_main_loop_run (loop);
 
541
        g_main_loop_unref (loop);
 
542
 
 
543
        /* Restart status timeout */
 
544
        status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
 
545
    }
 
546
    else if (strcmp (name, "ADD-SEAT") == 0)
 
547
    {
 
548
        const gchar *id, *v;
 
549
        Login1Seat *seat;
 
550
 
 
551
        id = g_hash_table_lookup (params, "ID");
 
552
        seat = add_login1_seat (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL), id, TRUE);
 
553
        v = g_hash_table_lookup (params, "CAN-GRAPHICAL");
 
554
        if (v)
 
555
            seat->can_graphical = strcmp (v, "TRUE") == 0;
 
556
        v = g_hash_table_lookup (params, "CAN-MULTI-SESSION");
 
557
        if (v)
 
558
            seat->can_multi_session = strcmp (v, "TRUE") == 0;
 
559
    }
 
560
    else if (strcmp (name, "UPDATE-SEAT") == 0)
 
561
    {
 
562
        Login1Seat *seat;
 
563
        const gchar *id;
 
564
 
 
565
        id = g_hash_table_lookup (params, "ID");
 
566
        seat = find_login1_seat (id);
 
567
        if (seat)
 
568
        {
 
569
            const gchar *v;
 
570
            GVariantBuilder invalidated_properties;
 
571
            GError *error = NULL;
 
572
 
 
573
            g_variant_builder_init (&invalidated_properties, G_VARIANT_TYPE_ARRAY);
 
574
 
 
575
            v = g_hash_table_lookup (params, "CAN-GRAPHICAL");
 
576
            if (v)
 
577
            {
 
578
                seat->can_graphical = strcmp (v, "TRUE") == 0;
 
579
                g_variant_builder_add (&invalidated_properties, "s", "CanGraphical");
 
580
            }
 
581
            v = g_hash_table_lookup (params, "CAN-MULTI-SESSION");
 
582
            if (v)
 
583
            {
 
584
                seat->can_multi_session = strcmp (v, "TRUE") == 0;
 
585
                g_variant_builder_add (&invalidated_properties, "s", "CanMultiSession");
 
586
            }
 
587
            v = g_hash_table_lookup (params, "ACTIVE-SESSION");
 
588
            if (v)
 
589
            {
 
590
                g_free (seat->active_session);
 
591
                seat->active_session = g_strdup (v);
 
592
                g_variant_builder_add (&invalidated_properties, "s", "ActiveSession");
 
593
            }
 
594
 
 
595
            g_dbus_connection_emit_signal (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
596
                                           NULL,
 
597
                                           seat->path,
 
598
                                           "org.freedesktop.DBus.Properties",
 
599
                                           "PropertiesChanged",
 
600
                                           g_variant_new ("(sa{sv}as)", "org.freedesktop.login1.Seat", NULL, &invalidated_properties),
 
601
                                           &error);
 
602
            if (error)
 
603
                g_warning ("Failed to emit PropertiesChanged: %s", error->message);
 
604
            g_clear_error (&error);
 
605
        }
 
606
    }
 
607
    else if (strcmp (name, "REMOVE-SEAT") == 0)
 
608
    {
 
609
        const gchar *id;
 
610
        id = g_hash_table_lookup (params, "ID");
 
611
        remove_login1_seat (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL), id);
402
612
    }
403
613
    else if (strcmp (name, "LIST-SEATS") == 0)
404
614
    {
416
626
                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Seats"),
417
627
                                              G_VARIANT_TYPE ("(v)"),
418
628
                                              G_DBUS_CALL_FLAGS_NONE,
419
 
                                              1000,
 
629
                                              G_MAXINT,
420
630
                                              NULL,
421
631
                                              NULL);
422
632
 
452
662
                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Sessions"),
453
663
                                              G_VARIANT_TYPE ("(v)"),
454
664
                                              G_DBUS_CALL_FLAGS_NONE,
455
 
                                              1000,
 
665
                                              G_MAXINT,
456
666
                                              NULL,
457
667
                                              NULL);
458
668
 
472
682
        check_status (status->str);
473
683
        g_string_free (status, TRUE);
474
684
    }
 
685
    else if (strcmp (name, "SEAT-CAN-SWITCH") == 0)
 
686
    {
 
687
        GVariant *result, *value;
 
688
        gchar *status;
 
689
 
 
690
        result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
691
                                              "org.freedesktop.DisplayManager",
 
692
                                              "/org/freedesktop/DisplayManager/Seat0",
 
693
                                              "org.freedesktop.DBus.Properties",
 
694
                                              "Get",
 
695
                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager.Seat", "CanSwitch"),
 
696
                                              G_VARIANT_TYPE ("(v)"),
 
697
                                              G_DBUS_CALL_FLAGS_NONE,
 
698
                                              G_MAXINT,
 
699
                                              NULL,
 
700
                                              NULL);
 
701
 
 
702
        g_variant_get (result, "(v)", &value);
 
703
        status = g_strdup_printf ("RUNNER SEAT-CAN-SWITCH CAN-SWITCH=%s", g_variant_get_boolean (value) ? "TRUE" : "FALSE");
 
704
        g_variant_unref (value);
 
705
        g_variant_unref (result);
 
706
        check_status (status);
 
707
        g_free (status);
 
708
    }
 
709
    else if (strcmp (name, "SEAT-HAS-GUEST-ACCOUNT") == 0)
 
710
    {
 
711
        GVariant *result, *value;
 
712
        gchar *status;
 
713
 
 
714
        result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
715
                                              "org.freedesktop.DisplayManager",
 
716
                                              "/org/freedesktop/DisplayManager/Seat0",
 
717
                                              "org.freedesktop.DBus.Properties",
 
718
                                              "Get",
 
719
                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager.Seat", "HasGuestAccount"),
 
720
                                              G_VARIANT_TYPE ("(v)"),
 
721
                                              G_DBUS_CALL_FLAGS_NONE,
 
722
                                              G_MAXINT,
 
723
                                              NULL,
 
724
                                              NULL);
 
725
 
 
726
        g_variant_get (result, "(v)", &value);
 
727
        status = g_strdup_printf ("RUNNER SEAT-HAS-GUEST-ACCOUNT HAS-GUEST-ACCOUNT=%s", g_variant_get_boolean (value) ? "TRUE" : "FALSE");
 
728
        g_variant_unref (value);
 
729
        g_variant_unref (result);
 
730
        check_status (status);
 
731
        g_free (status);
 
732
    }
475
733
    else if (strcmp (name, "SWITCH-TO-GREETER") == 0)
476
734
    {
477
 
        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
478
 
                                     "org.freedesktop.DisplayManager",
479
 
                                     "/org/freedesktop/DisplayManager/Seat0",
480
 
                                     "org.freedesktop.DisplayManager.Seat",
481
 
                                     "SwitchToGreeter",
482
 
                                     g_variant_new ("()"),
483
 
                                     G_VARIANT_TYPE ("()"),
484
 
                                     G_DBUS_CALL_FLAGS_NONE,
485
 
                                     1000,
486
 
                                     NULL,
487
 
                                     NULL);
488
 
        check_status ("RUNNER SWITCH-TO-GREETER");
 
735
        g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
736
                                "org.freedesktop.DisplayManager",
 
737
                                "/org/freedesktop/DisplayManager/Seat0",
 
738
                                "org.freedesktop.DisplayManager.Seat",
 
739
                                "SwitchToGreeter",
 
740
                                g_variant_new ("()"),
 
741
                                G_VARIANT_TYPE ("()"),
 
742
                                G_DBUS_CALL_FLAGS_NONE,
 
743
                                G_MAXINT,
 
744
                                NULL,
 
745
                                switch_to_greeter_done_cb,
 
746
                                NULL);
489
747
    }
490
748
    else if (strcmp (name, "SWITCH-TO-USER") == 0)
491
749
    {
492
 
        gchar *status_text, *username;
 
750
        const gchar *username;
493
751
 
494
752
        username = g_hash_table_lookup (params, "USERNAME");
495
 
        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
496
 
                                     "org.freedesktop.DisplayManager",
497
 
                                     "/org/freedesktop/DisplayManager/Seat0",
498
 
                                     "org.freedesktop.DisplayManager.Seat",
499
 
                                     "SwitchToUser",
500
 
                                     g_variant_new ("(ss)", username, ""),
501
 
                                     G_VARIANT_TYPE ("()"),
502
 
                                     G_DBUS_CALL_FLAGS_NONE,
503
 
                                     1000,
504
 
                                     NULL,
505
 
                                     NULL);
506
 
        status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s", username);
507
 
        check_status (status_text);
508
 
        g_free (status_text);
 
753
        g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
754
                                "org.freedesktop.DisplayManager",
 
755
                                "/org/freedesktop/DisplayManager/Seat0",
 
756
                                "org.freedesktop.DisplayManager.Seat",
 
757
                                "SwitchToUser",
 
758
                                g_variant_new ("(ss)", username, ""),
 
759
                                G_VARIANT_TYPE ("()"),
 
760
                                G_DBUS_CALL_FLAGS_NONE,
 
761
                                G_MAXINT,
 
762
                                NULL,
 
763
                                switch_to_user_done_cb,
 
764
                                g_strdup (username));
509
765
    }
510
766
    else if (strcmp (name, "SWITCH-TO-GUEST") == 0)
511
767
    {
512
 
        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
513
 
                                     "org.freedesktop.DisplayManager",
514
 
                                     "/org/freedesktop/DisplayManager/Seat0",
515
 
                                     "org.freedesktop.DisplayManager.Seat",
516
 
                                     "SwitchToGuest",
517
 
                                     g_variant_new ("(s)", ""),
518
 
                                     G_VARIANT_TYPE ("()"),
519
 
                                     G_DBUS_CALL_FLAGS_NONE,
520
 
                                     1000,
521
 
                                     NULL,
522
 
                                     NULL);
523
 
        check_status ("RUNNER SWITCH-TO-GUEST");
 
768
        g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
769
                                "org.freedesktop.DisplayManager",
 
770
                                "/org/freedesktop/DisplayManager/Seat0",
 
771
                                "org.freedesktop.DisplayManager.Seat",
 
772
                                "SwitchToGuest",
 
773
                                g_variant_new ("(s)", ""),
 
774
                                G_VARIANT_TYPE ("()"),
 
775
                                G_DBUS_CALL_FLAGS_NONE,
 
776
                                G_MAXINT,
 
777
                                NULL,
 
778
                                switch_to_guest_done_cb,
 
779
                                NULL);
524
780
    }
525
781
    else if (strcmp (name, "STOP-DAEMON") == 0)
526
782
        stop_process (lightdm_process);
651
907
                user->xsession = g_strdup (g_hash_table_lookup (params, "SESSION"));
652
908
                g_string_append_printf (status_text, " SESSION=%s", user->xsession);
653
909
            }
 
910
 
 
911
            g_dbus_connection_emit_signal (accounts_connection,
 
912
                                           NULL,
 
913
                                           user->path,
 
914
                                           "org.freedesktop.Accounts.User",
 
915
                                           "Changed",
 
916
                                           g_variant_new ("()"),
 
917
                                           &error);
654
918
        }
655
919
        else
656
920
            g_warning ("Unknown user %s", username);
657
921
 
658
 
        g_dbus_connection_emit_signal (accounts_connection,
659
 
                                       NULL,
660
 
                                       user->path,
661
 
                                       "org.freedesktop.Accounts.User",
662
 
                                       "Changed",
663
 
                                       g_variant_new ("()"),
664
 
                                       &error);
665
922
        if (error)
666
923
            g_warning ("Failed to emit Changed: %s", error->message);
667
924
        g_clear_error (&error);
685
942
        check_status (status_text);
686
943
        g_free (status_text);
687
944
    }
 
945
    else if (strcmp (name, "UNLOCK-SESSION") == 0)
 
946
    {
 
947
        gchar *status_text, *id;
 
948
        Login1Session *session;
 
949
        
 
950
        id = g_hash_table_lookup (params, "SESSION");
 
951
        session = find_login1_session (id);
 
952
        if (session)
 
953
        {
 
954
            if (!session->locked)
 
955
                g_warning ("Session %s is not locked", id);
 
956
            session->locked = FALSE;
 
957
        }
 
958
        else
 
959
            g_warning ("Unknown session %s", id);
 
960
 
 
961
        status_text = g_strdup_printf ("RUNNER UNLOCK-SESSION SESSION=%s", id);
 
962
        check_status (status_text);
 
963
        g_free (status_text);
 
964
    }
688
965
    /* Forward to external processes */
689
966
    else if (g_str_has_prefix (name, "SESSION-") ||
690
967
             g_str_has_prefix (name, "GREETER-") ||
691
968
             g_str_has_prefix (name, "XSERVER-") ||
 
969
             g_str_has_prefix (name, "XMIR-") ||
 
970
             g_str_has_prefix (name, "XVNC-") ||
692
971
             strcmp (name, "UNITY-SYSTEM-COMPOSITOR") == 0)
693
972
    {
694
973
        GList *link;
787
1066
    line->done = TRUE;
788
1067
 
789
1068
    /* Restart timeout */
790
 
    g_source_remove (status_timeout);
 
1069
    if (status_timeout)
 
1070
        g_source_remove (status_timeout);
791
1071
    status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
792
1072
 
793
1073
    run_commands ();
958
1238
 
959
1239
    service_count--;
960
1240
    if (service_count == 0)
961
 
        run_lightdm ();
 
1241
        ready ();
962
1242
}
963
1243
 
964
1244
static void
976
1256
}
977
1257
 
978
1258
static CKSession *
979
 
open_ck_session (GVariant *params)
 
1259
open_ck_session (GDBusConnection *connection, GVariant *params)
980
1260
{
981
1261
    CKSession *session;
982
1262
    GString *cookie;
1003
1283
    session->cookie = cookie->str;
1004
1284
    g_string_free (cookie, FALSE);
1005
1285
    session->path = g_strdup_printf ("/org/freedesktop/ConsoleKit/Session%d", ck_session_index++);
1006
 
    session->id = g_dbus_connection_register_object (ck_connection,
 
1286
    session->id = g_dbus_connection_register_object (connection,
1007
1287
                                                     session->path,
1008
1288
                                                     ck_session_info->interfaces[0],
1009
1289
                                                     &ck_session_vtable,
1043
1323
    {
1044
1324
        GVariantBuilder params;
1045
1325
        g_variant_builder_init (&params, G_VARIANT_TYPE ("a(sv)"));
1046
 
        CKSession *session = open_ck_session (g_variant_builder_end (&params));
 
1326
        CKSession *session = open_ck_session (connection, g_variant_builder_end (&params));
1047
1327
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", session->cookie));
1048
1328
    }
1049
1329
    else if (strcmp (method_name, "OpenSessionWithParameters") == 0)
1050
1330
    {
1051
 
        CKSession *session = open_ck_session (g_variant_get_child_value (parameters, 0));
 
1331
        CKSession *session = open_ck_session (connection, g_variant_get_child_value (parameters, 0));
1052
1332
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", session->cookie));
1053
1333
    }
1054
1334
    else if (strcmp (method_name, "GetSessionForCookie") == 0)
1061
1341
        for (link = ck_sessions; link; link = link->next)
1062
1342
        {
1063
1343
            CKSession *session = link->data;
1064
 
            if (strcmp (session->cookie, cookie) != 0)
 
1344
            if (strcmp (session->cookie, cookie) == 0)
1065
1345
            {
1066
1346
                g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", session->path));
1067
1347
                return;
1097
1377
    CKSession *session = user_data;
1098
1378
 
1099
1379
    if (strcmp (method_name, "Lock") == 0)
1100
 
    { 
 
1380
    {
1101
1381
        if (!session->locked)
1102
1382
            check_status ("CONSOLE-KIT LOCK-SESSION");
1103
1383
        session->locked = TRUE;
1110
1390
        session->locked = FALSE;
1111
1391
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
1112
1392
    }
 
1393
    else if (strcmp (method_name, "Activate") == 0)
 
1394
    {
 
1395
        gchar *status = g_strdup_printf ("CONSOLE-KIT ACTIVATE-SESSION SESSION=%s", session->cookie);
 
1396
        check_status (status);
 
1397
        g_free (status);
 
1398
 
 
1399
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1400
    }
1113
1401
    else
1114
1402
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
1115
1403
}
1162
1450
        "  <interface name='org.freedesktop.ConsoleKit.Session'>"
1163
1451
        "    <method name='Lock'/>"
1164
1452
        "    <method name='Unlock'/>"
 
1453
        "    <method name='Activate'/>"
1165
1454
        "  </interface>"
1166
1455
        "</node>";
1167
1456
    GDBusNodeInfo *ck_info;
1168
1457
    GError *error = NULL;
1169
1458
 
1170
 
    ck_connection = connection;
1171
 
 
1172
1459
    ck_info = g_dbus_node_info_new_for_xml (ck_interface, &error);
1173
1460
    if (error)
1174
1461
        g_warning ("Failed to parse D-Bus interface: %s", error->message);
1194
1481
 
1195
1482
    service_count--;
1196
1483
    if (service_count == 0)
1197
 
        run_lightdm ();
 
1484
        ready ();
1198
1485
}
1199
1486
 
1200
1487
static void
1204
1491
    g_bus_own_name (G_BUS_TYPE_SYSTEM,
1205
1492
                    "org.freedesktop.ConsoleKit",
1206
1493
                    G_BUS_NAME_OWNER_FLAGS_NONE,
 
1494
                    NULL,
1207
1495
                    ck_name_acquired_cb,
1208
1496
                    NULL,
1209
1497
                    NULL,
1210
 
                    NULL,
1211
1498
                    NULL);
1212
1499
}
1213
1500
 
1214
1501
static void
 
1502
handle_login1_seat_call (GDBusConnection       *connection,
 
1503
                         const gchar           *sender,
 
1504
                         const gchar           *object_path,
 
1505
                         const gchar           *interface_name,
 
1506
                         const gchar           *method_name,
 
1507
                         GVariant              *parameters,
 
1508
                         GDBusMethodInvocation *invocation,
 
1509
                         gpointer               user_data)
 
1510
{
 
1511
    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
 
1512
}
 
1513
 
 
1514
static GVariant *
 
1515
handle_login1_seat_get_property (GDBusConnection       *connection,
 
1516
                                 const gchar           *sender,
 
1517
                                 const gchar           *object_path,
 
1518
                                 const gchar           *interface_name,
 
1519
                                 const gchar           *property_name,
 
1520
                                 GError               **error,
 
1521
                                 gpointer               user_data)
 
1522
{
 
1523
    Login1Seat *seat = user_data;
 
1524
 
 
1525
    if (strcmp (property_name, "CanGraphical") == 0)
 
1526
        return g_variant_new_boolean (seat->can_graphical);
 
1527
    else if (strcmp (property_name, "CanMultiSession") == 0)
 
1528
        return g_variant_new_boolean (seat->can_multi_session);
 
1529
    else if (strcmp (property_name, "Id") == 0)
 
1530
        return g_variant_new_string (seat->id);
 
1531
    else if (strcmp (property_name, "ActiveSession") == 0)
 
1532
    {
 
1533
        if (seat->active_session)
 
1534
        {
 
1535
            gchar *path;
 
1536
            GVariant *ret;
 
1537
            
 
1538
            path = g_strdup_printf ("/org/freedesktop/login1/session/%s", seat->active_session);
 
1539
            ret = g_variant_new ("(so)", seat->active_session, path);
 
1540
            g_free (path);
 
1541
 
 
1542
            return ret;
 
1543
        }
 
1544
        else 
 
1545
            return NULL;
 
1546
    }
 
1547
    else
 
1548
        return NULL;
 
1549
}
 
1550
 
 
1551
static Login1Seat *
 
1552
add_login1_seat (GDBusConnection *connection, const gchar *id, gboolean emit_signal)
 
1553
{
 
1554
    Login1Seat *seat;
 
1555
    GError *error = NULL;
 
1556
    GDBusNodeInfo *login1_seat_info;
 
1557
 
 
1558
    const gchar *login1_seat_interface =
 
1559
        "<node>"
 
1560
        "  <interface name='org.freedesktop.login1.Seat'>"
 
1561
        "    <property name='CanGraphical' type='b' access='read'/>"
 
1562
        "    <property name='CanMultiSession' type='b' access='read'/>"
 
1563
        "    <property name='ActiveSession' type='(so)' access='read'/>"
 
1564
        "    <property name='Id' type='s' access='read'/>"
 
1565
        "  </interface>"
 
1566
        "</node>";
 
1567
    static const GDBusInterfaceVTable login1_seat_vtable =
 
1568
    {
 
1569
        handle_login1_seat_call,
 
1570
        handle_login1_seat_get_property,
 
1571
    };
 
1572
 
 
1573
    seat = g_malloc0 (sizeof (Login1Seat));
 
1574
    login1_seats = g_list_append (login1_seats, seat);
 
1575
    seat->id = g_strdup (id);
 
1576
    seat->path = g_strdup_printf ("/org/freedesktop/login1/seat/%s", seat->id);
 
1577
    seat->can_graphical = TRUE;
 
1578
    seat->can_multi_session = TRUE;
 
1579
    seat->active_session = NULL;
 
1580
 
 
1581
    login1_seat_info = g_dbus_node_info_new_for_xml (login1_seat_interface, &error);
 
1582
    if (error)
 
1583
        g_warning ("Failed to parse login1 seat D-Bus interface: %s", error->message);
 
1584
    g_clear_error (&error);
 
1585
    if (!login1_seat_info)
 
1586
        return NULL;
 
1587
 
 
1588
    g_dbus_connection_register_object (connection,
 
1589
                                       seat->path,
 
1590
                                       login1_seat_info->interfaces[0],
 
1591
                                       &login1_seat_vtable,
 
1592
                                       seat,
 
1593
                                       NULL,
 
1594
                                       &error);
 
1595
    if (error)
 
1596
        g_warning ("Failed to register login1 seat: %s", error->message);
 
1597
    g_clear_error (&error);
 
1598
    g_dbus_node_info_unref (login1_seat_info);
 
1599
 
 
1600
    if (emit_signal)
 
1601
    {
 
1602
        g_dbus_connection_emit_signal (connection,
 
1603
                                       NULL,
 
1604
                                       "/org/freedesktop/login1",
 
1605
                                       "org.freedesktop.login1.Manager",
 
1606
                                       "SeatNew",
 
1607
                                       g_variant_new ("(so)", seat->id, seat->path),
 
1608
                                       &error);
 
1609
        if (error)
 
1610
            g_warning ("Failed to emit SeatNew: %s", error->message);
 
1611
        g_clear_error (&error);
 
1612
    }
 
1613
 
 
1614
    return seat;
 
1615
}
 
1616
 
 
1617
static Login1Seat *
 
1618
find_login1_seat (const gchar *id)
 
1619
{
 
1620
    Login1Seat *seat;
 
1621
    GList *link;
 
1622
 
 
1623
    for (link = login1_seats; link; link = link->next)
 
1624
    {
 
1625
        seat = link->data;
 
1626
        if (strcmp (seat->id, id) == 0)
 
1627
            return seat;
 
1628
    }
 
1629
 
 
1630
    return NULL;
 
1631
}
 
1632
 
 
1633
static void
 
1634
remove_login1_seat (GDBusConnection *connection, const gchar *id)
 
1635
{
 
1636
    Login1Seat *seat;
 
1637
    GError *error = NULL;
 
1638
 
 
1639
    seat = find_login1_seat (id);
 
1640
    if (!seat)
 
1641
        return;
 
1642
 
 
1643
    g_dbus_connection_emit_signal (connection,
 
1644
                                   NULL,
 
1645
                                   "/org/freedesktop/login1",
 
1646
                                   "org.freedesktop.login1.Manager",
 
1647
                                   "SeatRemoved",
 
1648
                                   g_variant_new ("(so)", seat->id, seat->path),
 
1649
                                   &error);
 
1650
    if (error)
 
1651
        g_warning ("Failed to emit SeatNew: %s", error->message);
 
1652
    g_clear_error (&error);
 
1653
 
 
1654
    login1_seats = g_list_remove (login1_seats, seat);
 
1655
    g_free (seat->id);
 
1656
    g_free (seat->path);
 
1657
    g_free (seat->active_session);
 
1658
    g_free (seat);
 
1659
}
 
1660
 
 
1661
static void
1215
1662
handle_login1_session_call (GDBusConnection       *connection,
1216
1663
                            const gchar           *sender,
1217
1664
                            const gchar           *object_path,
1221
1668
                            GDBusMethodInvocation *invocation,
1222
1669
                            gpointer               user_data)
1223
1670
{
1224
 
    Login1Session *session = user_data;
1225
 
 
1226
 
    if (strcmp (method_name, "Lock") == 0)
1227
 
    {
1228
 
        if (!session->locked)
1229
 
            check_status ("LOGIN1 LOCK-SESSION");
1230
 
        session->locked = TRUE;
1231
 
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
1232
 
    }
1233
 
    else if (strcmp (method_name, "Unlock") == 0)
1234
 
    {
1235
 
        if (session->locked)
1236
 
            check_status ("LOGIN1 UNLOCK-SESSION");
1237
 
        session->locked = FALSE;
1238
 
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
1239
 
    }
1240
 
    else
1241
 
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
 
1671
    /*Login1Session *session = user_data;*/
 
1672
    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
1242
1673
}
1243
1674
 
1244
1675
static Login1Session *
1245
 
open_login1_session (GDBusConnection *connection,
1246
 
                     GVariant *params)
 
1676
create_login1_session (GDBusConnection *connection)
1247
1677
{
1248
1678
    Login1Session *session;
1249
1679
    GError *error = NULL;
1252
1682
    const gchar *login1_session_interface =
1253
1683
        "<node>"
1254
1684
        "  <interface name='org.freedesktop.login1.Session'>"
1255
 
        "    <method name='Lock'/>"
1256
 
        "    <method name='Unlock'/>"
1257
1685
        "  </interface>"
1258
1686
        "</node>";
1259
1687
    static const GDBusInterfaceVTable login1_session_vtable =
1264
1692
    session = g_malloc0 (sizeof (Login1Session));
1265
1693
    login1_sessions = g_list_append (login1_sessions, session);
1266
1694
 
1267
 
    session->path = g_strdup_printf("/org/freedesktop/login1/Session/c%d",
1268
 
                                    login1_session_index++);
1269
 
 
1270
 
 
1271
 
 
1272
 
    login1_session_info = g_dbus_node_info_new_for_xml (login1_session_interface,
1273
 
                                                        &error);
 
1695
    session->id = g_strdup_printf ("c%d", login1_session_index++);
 
1696
    session->path = g_strdup_printf ("/org/freedesktop/login1/Session/%s", session->id);
 
1697
 
 
1698
    login1_session_info = g_dbus_node_info_new_for_xml (login1_session_interface, &error);
1274
1699
    if (error)
1275
 
        g_warning ("Failed to parse login1 session D-Bus interface: %s",
1276
 
                   error->message);
 
1700
        g_warning ("Failed to parse login1 session D-Bus interface: %s", error->message);
1277
1701
    g_clear_error (&error);
1278
1702
    if (!login1_session_info)
1279
1703
        return NULL;
1293
1717
    return session;
1294
1718
}
1295
1719
 
 
1720
static Login1Session *
 
1721
find_login1_session (const gchar *id)
 
1722
{
 
1723
    GList *link;
 
1724
 
 
1725
    for (link = login1_sessions; link; link = link->next)
 
1726
    {
 
1727
        Login1Session *session = link->data;
 
1728
        if (strcmp (session->id, id) == 0)
 
1729
            return session;
 
1730
    }
 
1731
 
 
1732
    return NULL;
 
1733
}
1296
1734
 
1297
1735
static void
1298
1736
handle_login1_call (GDBusConnection       *connection,
1304
1742
                    GDBusMethodInvocation *invocation,
1305
1743
                    gpointer               user_data)
1306
1744
{
1307
 
 
1308
 
    if (strcmp (method_name, "GetSessionByPID") == 0)
 
1745
    if (strcmp (method_name, "ListSeats") == 0)
1309
1746
    {
1310
 
        /* Look for a session with our PID, and create one if we don't have one
1311
 
           already. */
 
1747
        GVariantBuilder seats;
1312
1748
        GList *link;
1313
 
        guint pid;
1314
 
        Login1Session *ret = NULL;
1315
 
 
1316
 
        g_variant_get (parameters, "(u)", &pid);
1317
 
 
1318
 
        for (link = login1_sessions; link; link = link->next)
1319
 
        {
1320
 
            Login1Session *session;
1321
 
            session = link->data;
1322
 
            if (session->pid == pid)
1323
 
            {
1324
 
                ret = session;
1325
 
                break;
1326
 
            }
1327
 
        }
1328
 
        /* Not found */
1329
 
        if (!ret)
1330
 
            ret = open_login1_session (connection, parameters);
1331
 
 
1332
 
        g_dbus_method_invocation_return_value (invocation,
1333
 
                                               g_variant_new("(o)", ret->path));
1334
 
 
 
1749
 
 
1750
        g_variant_builder_init (&seats, G_VARIANT_TYPE ("a(so)"));
 
1751
        for (link = login1_seats; link; link = link->next)
 
1752
        {
 
1753
            Login1Seat *seat = link->data;
 
1754
            g_variant_builder_add (&seats, "(so)", seat->id, seat->path);
 
1755
        }
 
1756
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &seats));
 
1757
    }
 
1758
    else if (strcmp (method_name, "CreateSession") == 0)
 
1759
    {
 
1760
        /* Note: this is not the full CreateSession as used by logind, we just
 
1761
           need one so our fake PAM stack can communicate with this service */
 
1762
        Login1Session *session = create_login1_session (connection);
 
1763
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(so)", session->id, session->path));
 
1764
 
 
1765
    }
 
1766
    else if (strcmp (method_name, "LockSession") == 0)
 
1767
    {
 
1768
        const gchar *id;
 
1769
        Login1Session *session;
 
1770
 
 
1771
        g_variant_get (parameters, "(&s)", &id);
 
1772
        session = find_login1_session (id);
 
1773
        if (!session)
 
1774
        {
 
1775
            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
 
1776
            return;
 
1777
        }
 
1778
 
 
1779
        if (!session->locked)
 
1780
        {
 
1781
            gchar *status = g_strdup_printf ("LOGIN1 LOCK-SESSION SESSION=%s", id);
 
1782
            check_status (status);
 
1783
            g_free (status);
 
1784
        }
 
1785
        session->locked = TRUE;
 
1786
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1787
    }
 
1788
    else if (strcmp (method_name, "UnlockSession") == 0)
 
1789
    {
 
1790
        const gchar *id;
 
1791
        Login1Session *session;
 
1792
 
 
1793
        g_variant_get (parameters, "(&s)", &id);
 
1794
        session = find_login1_session (id);
 
1795
        if (!session)
 
1796
        {
 
1797
            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
 
1798
            return;
 
1799
        }
 
1800
 
 
1801
        if (session->locked)
 
1802
        {
 
1803
            gchar *status = g_strdup_printf ("LOGIN1 UNLOCK-SESSION SESSION=%s", id);
 
1804
            check_status (status);
 
1805
            g_free (status);
 
1806
        }
 
1807
        session->locked = FALSE;
 
1808
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
1809
    }
 
1810
    else if (strcmp (method_name, "ActivateSession") == 0)
 
1811
    {
 
1812
        const gchar *id;
 
1813
        Login1Session *session;
 
1814
 
 
1815
        g_variant_get (parameters, "(&s)", &id);
 
1816
        session = find_login1_session (id);
 
1817
        if (!session)
 
1818
        {
 
1819
            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
 
1820
            return;
 
1821
        }
 
1822
 
 
1823
        gchar *status = g_strdup_printf ("LOGIN1 ACTIVATE-SESSION SESSION=%s", id);
 
1824
        check_status (status);
 
1825
        g_free (status);
 
1826
 
 
1827
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
1335
1828
    }
1336
1829
    else if (strcmp (method_name, "CanReboot") == 0)
1337
1830
    {
1393
1886
    const gchar *login1_interface =
1394
1887
        "<node>"
1395
1888
        "  <interface name='org.freedesktop.login1.Manager'>"
1396
 
        "    <method name='GetSessionByPID'>"
1397
 
        "      <arg name='pid' type='u' direction='in'/>"
1398
 
        "      <arg name='session' type='o' direction='out'/>"
 
1889
        "    <method name='ListSeats'>"
 
1890
        "      <arg name='seats' type='a(so)' direction='out'/>"
 
1891
        "    </method>"
 
1892
        "    <method name='CreateSession'>"
 
1893
        "      <arg name='id' type='s' direction='out'/>"
 
1894
        "      <arg name='path' type='o' direction='out'/>"
 
1895
        "    </method>"
 
1896
        "    <method name='LockSession'>"
 
1897
        "      <arg name='id' type='s' direction='in'/>"
 
1898
        "    </method>"
 
1899
        "    <method name='UnlockSession'>"
 
1900
        "      <arg name='id' type='s' direction='in'/>"
 
1901
        "    </method>"
 
1902
        "    <method name='ActivateSession'>"
 
1903
        "      <arg name='id' type='s' direction='in'/>"
1399
1904
        "    </method>"
1400
1905
        "    <method name='CanReboot'>"
1401
1906
        "      <arg name='result' direction='out' type='s'/>"
1421
1926
        "    <method name='Hibernate'>"
1422
1927
        "      <arg name='interactive' direction='in' type='b'/>"
1423
1928
        "    </method>"
 
1929
        "    <signal name='SeatNew'>"
 
1930
        "      <arg name='seat' type='so'/>"
 
1931
        "    </signal>"
 
1932
        "    <signal name='SeatRemoved'>"
 
1933
        "      <arg name='seat' type='so'/>"
 
1934
        "    </signal>"
1424
1935
        "  </interface>"
1425
1936
        "</node>";
1426
1937
    static const GDBusInterfaceVTable login1_vtable =
1428
1939
        handle_login1_call,
1429
1940
    };
1430
1941
    GDBusNodeInfo *login1_info;
 
1942
    Login1Seat *seat0;
1431
1943
    GError *error = NULL;
1432
1944
 
1433
1945
    login1_info = g_dbus_node_info_new_for_xml (login1_interface, &error);
1447
1959
    g_clear_error (&error);
1448
1960
    g_dbus_node_info_unref (login1_info);
1449
1961
 
 
1962
    /* We always have seat0 */
 
1963
    seat0 = add_login1_seat (connection, "seat0", FALSE);
 
1964
    if (g_key_file_has_key (config, "test-runner-config", "seat0-can-graphical", NULL))
 
1965
        seat0->can_graphical = g_key_file_get_boolean (config, "test-runner-config", "seat0-can-graphical", NULL);
 
1966
    if (g_key_file_has_key (config, "test-runner-config", "seat0-can-multi-session", NULL))
 
1967
        seat0->can_multi_session = g_key_file_get_boolean (config, "test-runner-config", "seat0-can-multi-session", NULL);
 
1968
 
1450
1969
    service_count--;
1451
1970
    if (service_count == 0)
1452
 
        run_lightdm ();
 
1971
        ready ();
1453
1972
}
1454
1973
 
1455
1974
static void
1459
1978
    g_bus_own_name (G_BUS_TYPE_SYSTEM,
1460
1979
                    "org.freedesktop.login1",
1461
1980
                    G_BUS_NAME_OWNER_FLAGS_NONE,
 
1981
                    NULL,
1462
1982
                    login1_name_acquired_cb,
1463
1983
                    NULL,
1464
1984
                    NULL,
1465
 
                    NULL,
1466
1985
                    NULL);
1467
1986
}
1468
1987
 
1477
1996
        if (u->uid == uid)
1478
1997
            return u;
1479
1998
    }
1480
 
  
 
1999
 
1481
2000
    return NULL;
1482
2001
}
1483
2002
 
1665
2184
        for (link = accounts_users; link; link = link->next)
1666
2185
        {
1667
2186
            AccountsUser *user = link->data;
1668
 
            if (!user->hidden)
 
2187
            if (!user->hidden && user->uid >= 1000)
1669
2188
                g_variant_builder_add_value (&builder, g_variant_new_object_path (user->path));
1670
2189
        }
1671
2190
 
1680
2199
 
1681
2200
        load_passwd_file ();
1682
2201
        user = get_accounts_user_by_name (user_name);
1683
 
        if (user && !user->hidden)
 
2202
        if (user)
 
2203
        {
 
2204
            if (user->hidden)
 
2205
                accounts_user_set_hidden (user, FALSE, TRUE);
1684
2206
            g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", user->path));
 
2207
        }
1685
2208
        else
1686
2209
            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such user: %s", user_name);
1687
2210
    }
1711
2234
        user->xsession = g_strdup (xsession);
1712
2235
 
1713
2236
        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
2237
 
 
2238
        /* And notify others that it took */
 
2239
        g_dbus_connection_emit_signal (accounts_connection,
 
2240
                                       NULL,
 
2241
                                       user->path,
 
2242
                                       "org.freedesktop.Accounts.User",
 
2243
                                       "Changed",
 
2244
                                       g_variant_new ("()"),
 
2245
                                       NULL);
1714
2246
    }
1715
2247
    else
1716
2248
        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
1733
2265
        return g_variant_new_string (user->real_name);
1734
2266
    else if (strcmp (property_name, "HomeDirectory") == 0)
1735
2267
        return g_variant_new_string (user->home_directory);
 
2268
    else if (strcmp (property_name, "SystemAccount") == 0)
 
2269
        return g_variant_new_boolean (user->uid < 1000);
1736
2270
    else if (strcmp (property_name, "BackgroundFile") == 0)
1737
2271
        return g_variant_new_string (user->background ? user->background : "");
1738
2272
    else if (strcmp (property_name, "Language") == 0)
1739
2273
        return g_variant_new_string (user->language ? user->language : "");
1740
2274
    else if (strcmp (property_name, "IconFile") == 0)
1741
2275
        return g_variant_new_string (user->image ? user->image : "");
 
2276
    else if (strcmp (property_name, "Shell") == 0)
 
2277
        return g_variant_new_string ("/bin/sh");
 
2278
    else if (strcmp (property_name, "Uid") == 0)
 
2279
        return g_variant_new_uint64 (user->uid);
1742
2280
    else if (strcmp (property_name, "XSession") == 0)
1743
2281
        return g_variant_new_string (user->xsession ? user->xsession : "");
1744
2282
    else if (strcmp (property_name, "XKeyboardLayouts") == 0)
1790
2328
        "    <property name='UserName' type='s' access='read'/>"
1791
2329
        "    <property name='RealName' type='s' access='read'/>"
1792
2330
        "    <property name='HomeDirectory' type='s' access='read'/>"
 
2331
        "    <property name='SystemAccount' type='b' access='read'/>"
1793
2332
        "    <property name='BackgroundFile' type='s' access='read'/>"
1794
2333
        "    <property name='Language' type='s' access='read'/>"
1795
2334
        "    <property name='IconFile' type='s' access='read'/>"
 
2335
        "    <property name='Shell' type='s' access='read'/>"
 
2336
        "    <property name='Uid' type='t' access='read'/>"
1796
2337
        "    <property name='XSession' type='s' access='read'/>"
1797
2338
        "    <property name='XKeyboardLayouts' type='as' access='read'/>"
1798
2339
        "    <property name='XHasMessages' type='b' access='read'/>"
1829
2370
 
1830
2371
    service_count--;
1831
2372
    if (service_count == 0)
1832
 
        run_lightdm ();
 
2373
        ready ();
1833
2374
}
1834
2375
 
1835
2376
static void
1847
2388
}
1848
2389
 
1849
2390
static void
1850
 
run_lightdm (void)
 
2391
ready (void)
1851
2392
{
1852
 
    GString *command_line;
1853
 
    gchar **lightdm_argv;
1854
 
    pid_t lightdm_pid;
1855
 
    GError *error = NULL;
1856
 
 
1857
2393
    run_commands ();
1858
 
 
1859
 
    status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
1860
 
 
1861
 
    command_line = g_string_new ("lightdm");
1862
 
    if (getenv ("DEBUG"))
1863
 
        g_string_append (command_line, " --debug");
1864
 
    g_string_append_printf (command_line, " --cache-dir %s/cache", temp_dir);
1865
 
 
1866
 
    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",
1867
 
                                           g_getenv ("PATH"), g_getenv ("LD_PRELOAD"), g_getenv ("LD_LIBRARY_PATH"), g_getenv ("LIGHTDM_TEST_ROOT"), g_getenv ("DBUS_SESSION_BUS_ADDRESS"),
1868
 
                                           command_line->str);
1869
 
 
1870
 
    if (!g_shell_parse_argv (command_line->str, NULL, &lightdm_argv, &error))
1871
 
    {
1872
 
        g_warning ("Error parsing command line: %s", error->message);
1873
 
        quit (EXIT_FAILURE);
1874
 
    }
1875
 
    g_clear_error (&error);
1876
 
 
1877
 
    if (!g_spawn_async (NULL, lightdm_argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, &lightdm_pid, &error))
1878
 
    {
1879
 
        g_warning ("Error launching LightDM: %s", error->message);
1880
 
        quit (EXIT_FAILURE);
1881
 
    }
1882
 
    g_clear_error (&error);
1883
 
    lightdm_process = watch_process (lightdm_pid);
1884
 
 
1885
 
    check_status ("RUNNER DAEMON-START");
1886
2394
}
1887
2395
 
1888
2396
static gboolean
1893
2401
    return FALSE;
1894
2402
}
1895
2403
 
 
2404
static void
 
2405
properties_changed_cb (GDBusConnection *connection,
 
2406
                       const gchar *sender_name,
 
2407
                       const gchar *object_path,
 
2408
                       const gchar *interface_name,
 
2409
                       const gchar *signal_name,
 
2410
                       GVariant *parameters,
 
2411
                       gpointer user_data)
 
2412
{
 
2413
    const gchar *interface, *name;
 
2414
    GString *status;
 
2415
    GVariant *value;
 
2416
    GVariantIter *changed_properties, *invalidated_properties;
 
2417
    int i;
 
2418
 
 
2419
    g_variant_get (parameters, "(&sa{sv}as)", &interface, &changed_properties, &invalidated_properties);
 
2420
 
 
2421
    status = g_string_new ("RUNNER DBUS-PROPERTIES-CHANGED");
 
2422
    g_string_append_printf (status, " PATH=%s", object_path);
 
2423
    g_string_append_printf (status, " INTERFACE=%s", interface);
 
2424
    for (i = 0; g_variant_iter_loop (changed_properties, "{&sv}", &name, &value); i++)
 
2425
    {
 
2426
        if (i == 0)
 
2427
            g_string_append (status, " CHANGED=");
 
2428
        else
 
2429
            g_string_append (status, ",");
 
2430
        g_string_append (status, name);
 
2431
        if (g_variant_is_of_type (value, G_VARIANT_TYPE ("ao")))
 
2432
        {
 
2433
            GVariantIter iter;
 
2434
            const gchar *path;
 
2435
 
 
2436
            g_variant_iter_init (&iter, value);
 
2437
            while (g_variant_iter_loop (&iter, "&o", &path))
 
2438
                g_string_append_printf (status, ":%s", path);
 
2439
        }
 
2440
    }
 
2441
    for (i = 0; g_variant_iter_loop (invalidated_properties, "&s", &name); i++)
 
2442
    {
 
2443
        if (i == 0)
 
2444
            g_string_append (status, " INVALIDATED=");
 
2445
        else
 
2446
            g_string_append (status, ",");
 
2447
        g_string_append (status, name);
 
2448
    }
 
2449
 
 
2450
    check_status (status->str);
 
2451
    g_string_free (status, TRUE);
 
2452
}
 
2453
 
 
2454
static void
 
2455
dbus_signal_cb (GDBusConnection *connection,
 
2456
                const gchar *sender_name,
 
2457
                const gchar *object_path,
 
2458
                const gchar *interface_name,
 
2459
                const gchar *signal_name,
 
2460
                GVariant *parameters,
 
2461
                gpointer user_data)
 
2462
{
 
2463
    GString *status;
 
2464
 
 
2465
    status = g_string_new ("RUNNER DBUS-SIGNAL");
 
2466
    g_string_append_printf (status, " PATH=%s", object_path);
 
2467
    g_string_append_printf (status, " INTERFACE=%s", interface_name);
 
2468
    g_string_append_printf (status, " NAME=%s", signal_name);
 
2469
 
 
2470
    check_status (status->str);
 
2471
    g_string_free (status, TRUE);
 
2472
}
 
2473
 
1896
2474
int
1897
2475
main (int argc, char **argv)
1898
2476
{
1940
2518
    /* Don't contact our X server */
1941
2519
    g_unsetenv ("DISPLAY");
1942
2520
 
 
2521
    /* Don't let XDG vars from system affect tests */
 
2522
    g_unsetenv ("XDG_CONFIG_DIRS");
 
2523
    g_unsetenv ("XDG_DATA_DIRS");
 
2524
 
1943
2525
    /* Override system calls */
1944
2526
    ld_preload = g_build_filename (BUILDDIR, "tests", "src", ".libs", "libsystem.so", NULL);
1945
2527
    g_setenv ("LD_PRELOAD", ld_preload, TRUE);
1975
2557
        if (!g_file_test (temp_dir, G_FILE_TEST_EXISTS))
1976
2558
            break;
1977
2559
        i++;
1978
 
    }  
 
2560
    }
1979
2561
    g_mkdir_with_parents (temp_dir, 0755);
1980
2562
    g_setenv ("LIGHTDM_TEST_ROOT", temp_dir, TRUE);
1981
2563
 
2019
2601
 
2020
2602
    /* Set up a skeleton file system */
2021
2603
    g_mkdir_with_parents (g_strdup_printf ("%s/etc", temp_dir), 0755);
 
2604
    g_mkdir_with_parents (g_strdup_printf ("%s/run", temp_dir), 0755);
2022
2605
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share", temp_dir), 0755);
2023
2606
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/sessions", temp_dir), 0755);
2024
2607
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/remote-sessions", temp_dir), 0755);
2025
2608
    g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/greeters", temp_dir), 0755);
2026
2609
    g_mkdir_with_parents (g_strdup_printf ("%s/tmp", temp_dir), 0755);
 
2610
    g_mkdir_with_parents (g_strdup_printf ("%s/var/lib/lightdm-data", temp_dir), 0755);
2027
2611
    g_mkdir_with_parents (g_strdup_printf ("%s/var/run", temp_dir), 0755);
2028
2612
    g_mkdir_with_parents (g_strdup_printf ("%s/var/log", temp_dir), 0755);
2029
2613
 
2052
2636
    {
2053
2637
        gchar **files;
2054
2638
 
2055
 
        g_mkdir_with_parents (g_strdup_printf ("%s/etc/lightdm/lightdm.conf.d", temp_dir), 0755);
 
2639
        g_mkdir_with_parents (g_strdup_printf ("%s/etc/xdg/lightdm/lightdm.conf.d", temp_dir), 0755);
2056
2640
 
2057
2641
        files = g_strsplit (additional_config, " ", -1);
2058
2642
        for (i = 0; files[i]; i++)
2059
 
            if (system (g_strdup_printf ("cp %s/tests/scripts/%s %s/etc/lightdm/lightdm.conf.d", SRCDIR, files[i], temp_dir)))
 
2643
            if (system (g_strdup_printf ("cp %s/tests/scripts/%s %s/etc/xdg/lightdm/lightdm.conf.d", SRCDIR, files[i], temp_dir)))
2060
2644
                perror ("Failed to copy configuration");
2061
2645
        g_strfreev (files);
2062
2646
    }
2063
2647
 
 
2648
    if (g_key_file_has_key (config, "test-runner-config", "shared-data-dirs", NULL))
 
2649
    {
 
2650
        gchar *dir_string;
 
2651
        gchar **dirs;
 
2652
        gint i;
 
2653
 
 
2654
        dir_string = g_key_file_get_string (config, "test-runner-config", "shared-data-dirs", NULL);
 
2655
        dirs = g_strsplit (dir_string, " ", -1);
 
2656
        g_free (dir_string);
 
2657
 
 
2658
        for (i = 0; dirs[i]; i++)
 
2659
        {
 
2660
            gchar **fields = g_strsplit (dirs[i], ":", -1);
 
2661
            if (g_strv_length (fields) == 4)
 
2662
            {
 
2663
                gchar *path = g_strdup_printf ("%s/var/lib/lightdm-data/%s", temp_dir, fields[0]);
 
2664
                int uid = g_ascii_strtoll (fields[1], NULL, 10);
 
2665
                int gid = g_ascii_strtoll (fields[2], NULL, 10);
 
2666
                int mode = g_ascii_strtoll (fields[3], NULL, 8);
 
2667
                g_mkdir (path, mode);
 
2668
                g_chmod (path, mode); /* mkdir filters by umask, so make sure we have what we want */
 
2669
                if (chown (path, uid, gid) < 0)
 
2670
                  g_warning ("chown (%s) failed: %s", path, strerror (errno));
 
2671
                g_free (path);
 
2672
            }
 
2673
            g_strfreev (fields);
 
2674
        }
 
2675
 
 
2676
        g_strfreev (dirs);
 
2677
    }
 
2678
 
2064
2679
    /* Always copy the script */
2065
2680
    if (system (g_strdup_printf ("cp %s %s/script", config_path, temp_dir)))
2066
2681
        perror ("Failed to copy configuration");
2257
2872
    if (!g_key_file_get_boolean (config, "test-runner-config", "disable-accounts-service", NULL))
2258
2873
        start_accounts_service_daemon ();
2259
2874
 
 
2875
    /* Listen for daemon bus events */
 
2876
    if (g_key_file_get_boolean (config, "test-runner-config", "log-dbus", NULL))
 
2877
    {
 
2878
        g_dbus_connection_signal_subscribe (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
2879
                                            "org.freedesktop.DisplayManager",
 
2880
                                            "org.freedesktop.DBus.Properties",
 
2881
                                            "PropertiesChanged",
 
2882
                                            NULL,
 
2883
                                            NULL,
 
2884
                                            G_DBUS_SIGNAL_FLAGS_NONE,
 
2885
                                            properties_changed_cb,
 
2886
                                            NULL,
 
2887
                                            NULL);
 
2888
        g_dbus_connection_signal_subscribe (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
 
2889
                                            "org.freedesktop.DisplayManager",
 
2890
                                            "org.freedesktop.DisplayManager",
 
2891
                                            NULL,
 
2892
                                            NULL,
 
2893
                                            NULL,
 
2894
                                            G_DBUS_SIGNAL_FLAGS_NONE,
 
2895
                                            dbus_signal_cb,
 
2896
                                            NULL,
 
2897
                                            NULL);
 
2898
    }
 
2899
 
2260
2900
    g_main_loop_run (loop);
2261
2901
 
2262
2902
    return EXIT_FAILURE;