]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Support logind in liblightdm. Fixes: https://bugs.launchpad.net/bugs/1152185.
authorRex Dieter <rdieter@fedoraproject.org>
Mon, 15 Apr 2013 21:51:36 +0000 (21:51 +0000)
committerTarmac <Unknown>
Mon, 15 Apr 2013 21:51:36 +0000 (21:51 +0000)
Approved by PS Jenkins bot.

liblightdm-gobject/power.c
liblightdm-qt/power.cpp
tests/Makefile.am
tests/scripts/no-console-kit-or-login1.conf [new file with mode: 0644]
tests/scripts/no-login1.conf [new file with mode: 0644]
tests/src/test-runner.c
tests/test-no-console-kit-or-login1 [new file with mode: 0755]
tests/test-no-login1 [new file with mode: 0755]

index 7d5e18cdf5a479ee793da257e4f1ffcdb789ca7a..739362cd95c30f6e6a22236574c55c36e75b79d3 100644 (file)
@@ -17,6 +17,7 @@
 
 static GDBusProxy *upower_proxy = NULL;
 static GDBusProxy *ck_proxy = NULL;
+static GDBusProxy *login1_proxy = NULL;
 
 static gboolean
 upower_call_function (const gchar *function, gboolean default_result, GError **error)
@@ -109,11 +110,10 @@ lightdm_hibernate (GError **error)
     return upower_call_function ("Hibernate", TRUE, error);
 }
 
-static gboolean
-ck_call_function (const gchar *function, gboolean default_result, GError **error)
+static GVariant *
+ck_call_function (const gchar *function, GError **error)
 {
-    GVariant *result;
-    gboolean function_result = FALSE;
+    GVariant *r;
 
     if (!ck_proxy)
     {
@@ -129,22 +129,46 @@ ck_call_function (const gchar *function, gboolean default_result, GError **error
             return FALSE;
     }
 
-    result = g_dbus_proxy_call_sync (ck_proxy,
-                                     function,
-                                     NULL,
-                                     G_DBUS_CALL_FLAGS_NONE,
-                                     -1,
-                                     NULL,
-                                     error);
+    r = g_dbus_proxy_call_sync (ck_proxy,
+                                function,
+                                NULL,
+                                G_DBUS_CALL_FLAGS_NONE,
+                                -1,
+                                NULL,
+                                error);
 
-    if (!result)
-        return default_result;
+    return r;
+}
 
-    if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
-        g_variant_get (result, "(b)", &function_result);
+static GVariant *
+login1_call_function (const gchar *function, GVariant *parameters, GError **error)
+{
+    GVariant *r;
+    gchar *str_result;
 
-    g_variant_unref (result);
-    return function_result;
+    if (!login1_proxy)
+    {
+        login1_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                                      G_DBUS_PROXY_FLAGS_NONE,
+                                                      NULL,
+                                                      "org.freedesktop.login1",
+                                                      "/org/freedesktop/login1",
+                                                      "org.freedesktop.login1.Manager",
+                                                      NULL,
+                                                      error);
+        if (!login1_proxy)
+            return NULL;
+    }
+
+    r = g_dbus_proxy_call_sync (login1_proxy,
+                                function,
+                                parameters,
+                                G_DBUS_CALL_FLAGS_NONE,
+                                -1,
+                                NULL,
+                                error);
+
+    return r;
 }
 
 /**
@@ -157,7 +181,29 @@ ck_call_function (const gchar *function, gboolean default_result, GError **error
 gboolean
 lightdm_get_can_restart (void)
 {
-    return ck_call_function ("CanRestart", FALSE, NULL);
+    gboolean can_restart = FALSE;
+    GVariant *r;
+
+    r = login1_call_function ("CanReboot", NULL, NULL);
+    if (r)
+    {
+        gchar *result;
+        if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)")))
+        {
+            g_variant_get (r, "(&s)", &result);
+            can_restart = g_strcmp0 (result, "yes") == 0;
+        }
+    }
+    else
+    {
+        r = ck_call_function ("CanRestart", NULL);
+        if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)")))
+            g_variant_get (r, "(b)", &can_restart);
+    }
+    if (r)
+        g_variant_unref (r);
+
+    return can_restart;
 }
 
 /**
@@ -171,7 +217,20 @@ lightdm_get_can_restart (void)
 gboolean
 lightdm_restart (GError **error)
 {
-    return ck_call_function ("Restart", TRUE, error);
+    GVariant *r;
+    gboolean restarted;
+
+    r = login1_call_function ("Reboot", g_variant_new("(b)", FALSE), error);
+    if (!r)
+    {
+        g_clear_error (error);
+        r = ck_call_function ("Restart", error);
+    }
+    restarted = r != NULL;
+    if (r)
+        g_variant_unref (r);
+
+    return restarted;
 }
 
 /**
@@ -184,7 +243,29 @@ lightdm_restart (GError **error)
 gboolean
 lightdm_get_can_shutdown (void)
 {
-    return ck_call_function ("CanStop", FALSE, NULL);
+    gboolean can_shutdown = FALSE;
+    GVariant *r;
+  
+    r = login1_call_function ("CanPowerOff", NULL, NULL);
+    if (r)
+    {
+        gchar *result;
+        if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)")))
+        {
+            g_variant_get (r, "(&s)", &result);
+            can_shutdown = g_strcmp0 (result, "yes") == 0;
+        }
+    }
+    else
+    {
+        r = ck_call_function ("CanStop", NULL);
+        if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)")))
+            g_variant_get (r, "(b)", &can_shutdown);
+    }
+    if (r)
+        g_variant_unref (r);
+
+    return can_shutdown;
 }
 
 /**
@@ -198,5 +279,18 @@ lightdm_get_can_shutdown (void)
 gboolean
 lightdm_shutdown (GError **error)
 {
-    return ck_call_function ("Stop", TRUE, error);
+    GVariant *r;
+    gboolean shutdown;
+
+    r = login1_call_function ("PowerOff", g_variant_new("(b)", FALSE), error);
+    if (!r)
+    {
+        g_clear_error (error);
+        r = ck_call_function ("Stop", error);
+    }
+    shutdown = r != NULL;
+    if (r)
+        g_variant_unref (r);
+
+    return shutdown;
 }
index 3df5cbd5047b3f89a8f0153e1539b66e5ff48bbd..3eabc23f8283a91c9b783c7b6b8cfbf5a57a141a 100644 (file)
@@ -15,6 +15,7 @@
 #include <QtCore/QVariant>
 #include <QtDBus/QDBusInterface>
 #include <QtDBus/QDBusReply>
+#include <QDebug>
 
 #include "config.h"
 
@@ -26,11 +27,13 @@ public:
     PowerInterfacePrivate();
     QScopedPointer<QDBusInterface> powerManagementInterface;
     QScopedPointer<QDBusInterface> consoleKitInterface;
+    QScopedPointer<QDBusInterface> login1Interface;
 };
 
 PowerInterface::PowerInterfacePrivate::PowerInterfacePrivate() :
     powerManagementInterface(new QDBusInterface("org.freedesktop.UPower","/org/freedesktop/UPower", "org.freedesktop.UPower", QDBusConnection::systemBus())),
-    consoleKitInterface(new QDBusInterface("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus()))
+    consoleKitInterface(new QDBusInterface("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus())),
+    login1Interface(new QDBusInterface("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus()))
 {
 }
 
@@ -80,34 +83,54 @@ void PowerInterface::hibernate()
 
 bool PowerInterface::canShutdown()
 {
+    if (d->login1Interface->isValid()) {
+        QDBusReply<QString> reply1 = d->login1Interface->call("CanPowerOff");
+        if (reply1.isValid()) {
+            return reply1.value() == "yes";
+        }
+    }
+    qWarning() << d->login1Interface->lastError();
+
     QDBusReply<bool> reply = d->consoleKitInterface->call("CanStop");
     if (reply.isValid()) {
         return reply.value();
     }
-    else {
-        return false;
-    }
+
+    return false;
 }
 
 void PowerInterface::shutdown()
 {
-    d->consoleKitInterface->call("Stop");
+    if (d->login1Interface->isValid())
+        d->login1Interface->call("PowerOff", false);
+    else
+        d->consoleKitInterface->call("Stop");
 }
 
 bool PowerInterface::canRestart()
 {
+    if (d->login1Interface->isValid()) {
+        QDBusReply<QString> reply1 = d->login1Interface->call("CanReboot");
+        if (reply1.isValid()) {
+            return reply1.value() == "yes";
+        }
+    }
+    qWarning() << d->login1Interface->lastError();
+  
     QDBusReply<bool> reply = d->consoleKitInterface->call("CanRestart");
     if (reply.isValid()) {
         return reply.value();
     }
-    else {
-        return false;
-    }
+
+    return false;
 }
 
 void PowerInterface::restart()
 {
-    d->consoleKitInterface->call("Restart");
+    if (d->login1Interface->isValid())
+        d->login1Interface->call("Reboot", false);
+    else
+        d->consoleKitInterface->call("Restart");
 }
 
 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
index cc6e46373133c5f031933c7e3c42f1fda3a9ff1e..1301d95080fc3210c9465210db23ec20ba7bb2da 100644 (file)
@@ -135,6 +135,8 @@ TESTS = \
        test-no-accounts-service \
        test-console-kit \
        test-no-console-kit \
+       test-no-login1 \
+       test-no-console-kit-or-login1 \
        test-open-file-descriptors \
        test-xdmcp-open-file-descriptors
 
@@ -284,8 +286,10 @@ EXTRA_DIST = \
        scripts/no-accounts-service.conf \
        scripts/no-config.conf \
        scripts/no-console-kit.conf \
+       scripts/no-console-kit-or-login1.conf \
        scripts/no-keyboard-layout.conf \
        scripts/no-language.conf \
+       scripts/no-login1.conf \
        scripts/open-file-descriptors.conf \
        scripts/pam.conf \
        scripts/plymouth-active-vt.conf \
diff --git a/tests/scripts/no-console-kit-or-login1.conf b/tests/scripts/no-console-kit-or-login1.conf
new file mode 100644 (file)
index 0000000..c6c045d
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# Check still works when neither ConsoleKit or login1 is available
+#
+
+[test-runner-config]
+disable-console-kit=true
+disable-login1=true
+
+[LightDM]
+minimum-display-number=50
+
+[SeatDefaults]
+autologin-user=have-password1
+
+#?RUNNER DAEMON-START
+
+# X server starts
+#?XSERVER :50 START
+#?XSERVER :50 INDICATE-READY
+
+# LightDM connects to X server
+#?XSERVER :50 ACCEPT-CONNECT
+
+# Session starts
+#?SESSION :50 START USER=have-password1
+#?XSERVER :50 ACCEPT-CONNECT
+#?SESSION :50 CONNECT-XSERVER
+
+# Cleanup
+#?*STOP-DAEMON
+# Don't know what order they will terminate
+#?(SESSION :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
+#?(SESSION :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
+#?RUNNER DAEMON-EXIT STATUS=0
diff --git a/tests/scripts/no-login1.conf b/tests/scripts/no-login1.conf
new file mode 100644 (file)
index 0000000..2447b8b
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# Check still works when login1 is not available
+#
+
+[test-runner-config]
+disable-login1=true
+
+[LightDM]
+minimum-display-number=50
+
+[SeatDefaults]
+autologin-user=have-password1
+
+#?RUNNER DAEMON-START
+
+# X server starts
+#?XSERVER :50 START
+#?XSERVER :50 INDICATE-READY
+
+# LightDM connects to X server
+#?XSERVER :50 ACCEPT-CONNECT
+
+# Session starts
+#?SESSION :50 START USER=have-password1
+#?XSERVER :50 ACCEPT-CONNECT
+#?SESSION :50 CONNECT-XSERVER
+
+# Cleanup
+#?*STOP-DAEMON
+# Don't know what order they will terminate
+#?(SESSION :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
+#?(SESSION :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
+#?RUNNER DAEMON-EXIT STATUS=0
index 3f58b4cf3f64b5633c545cce12e7c04c87e72562..813a3733a33131417ce30ca33973ce91032b7e3d 100644 (file)
@@ -837,6 +837,101 @@ start_console_kit_daemon ()
                     NULL);
 }
 
+static void
+handle_login1_call (GDBusConnection       *connection,
+                    const gchar           *sender,
+                    const gchar           *object_path,
+                    const gchar           *interface_name,
+                    const gchar           *method_name,
+                    GVariant              *parameters,
+                    GDBusMethodInvocation *invocation,
+                    gpointer               user_data)
+{
+    if (strcmp (method_name, "CanReboot") == 0)
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "yes"));
+    else if (strcmp (method_name, "Reboot") == 0)
+    {
+        gboolean interactive;
+        g_variant_get (parameters, "(b)", &interactive);
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+    }
+    if (strcmp (method_name, "CanPowerOff") == 0)
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "yes"));
+    else if (strcmp (method_name, "PowerOff") == 0)
+    {
+        gboolean interactive;
+        g_variant_get (parameters, "(b)", &interactive);
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+    }
+    else
+        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
+}
+
+static void
+login1_name_acquired_cb (GDBusConnection *connection,
+                         const gchar     *name,
+                         gpointer         user_data)
+{
+    const gchar *login1_interface =
+        "<node>"
+        "  <interface name='org.freedesktop.login1.Manager'>"
+        "    <method name='CanReboot'>"
+        "      <arg name='result' direction='out' type='s'/>"
+        "    </method>"
+        "    <method name='Reboot'>"
+        "      <arg name='interactive' direction='in' type='b'/>"
+        "    </method>"
+        "    <method name='CanPowerOff'>"
+        "      <arg name='result' direction='out' type='s'/>"
+        "    </method>"
+        "    <method name='PowerOff'>"
+        "      <arg name='interactive' direction='in' type='b'/>"
+        "    </method>"
+        "  </interface>"
+        "</node>";
+    static const GDBusInterfaceVTable login1_vtable =
+    {
+        handle_login1_call,
+    };
+    GDBusNodeInfo *login1_info;
+    GError *error = NULL;
+
+    login1_info = g_dbus_node_info_new_for_xml (login1_interface, &error);
+    if (error)
+        g_warning ("Failed to parse D-Bus interface: %s", error->message);  
+    g_clear_error (&error);
+    if (!login1_info)
+        return;
+    g_dbus_connection_register_object (connection,
+                                       "/org/freedesktop/login1",
+                                       login1_info->interfaces[0],
+                                       &login1_vtable,
+                                       NULL, NULL,
+                                       &error);
+    if (error)
+        g_warning ("Failed to register login1 service: %s", error->message);
+    g_clear_error (&error);
+    g_dbus_node_info_unref (login1_info);
+
+    service_count--;
+    if (service_count == 0)
+        run_lightdm ();
+}
+
+static void
+start_login1_daemon ()
+{
+    service_count++;
+    g_bus_own_name (G_BUS_TYPE_SYSTEM,
+                    "org.freedesktop.login1",
+                    G_BUS_NAME_OWNER_FLAGS_NONE,
+                    login1_name_acquired_cb,
+                    NULL,
+                    NULL,
+                    NULL,
+                    NULL);
+}
+
 static void
 load_passwd_file ()
 {
@@ -1474,6 +1569,8 @@ main (int argc, char **argv)
     /* Start D-Bus services */
     if (!g_key_file_get_boolean (config, "test-runner-config", "disable-console-kit", NULL))
         start_console_kit_daemon ();
+    if (!g_key_file_get_boolean (config, "test-runner-config", "disable-login1", NULL))
+        start_login1_daemon ();
     if (!g_key_file_get_boolean (config, "test-runner-config", "disable-accounts-service", NULL))
         start_accounts_service_daemon ();
 
diff --git a/tests/test-no-console-kit-or-login1 b/tests/test-no-console-kit-or-login1
new file mode 100755 (executable)
index 0000000..9963ffc
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+./src/dbus-env ./src/test-runner no-console-kit-or-login1 test-gobject-greeter
diff --git a/tests/test-no-login1 b/tests/test-no-login1
new file mode 100755 (executable)
index 0000000..6db0975
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+./src/dbus-env ./src/test-runner no-login1 test-gobject-greeter