]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
First pass at reset support
authorMichael Terry <michael.terry@canonical.com>
Thu, 24 Apr 2014 18:36:40 +0000 (14:36 -0400)
committerMichael Terry <michael.terry@canonical.com>
Thu, 24 Apr 2014 18:36:40 +0000 (14:36 -0400)
14 files changed:
configure.ac
debian/changelog
debian/liblightdm-gobject-1-0.symbols
liblightdm-gobject/greeter.c
liblightdm-gobject/lightdm/greeter.h
liblightdm-qt/QLightDM/greeter.h
liblightdm-qt/greeter.cpp
src/greeter.c
src/greeter.h
src/seat.c
tests/src/test-gobject-greeter.c
tests/src/test-python-greeter
tests/src/test-qt-greeter.cpp
tests/src/test-qt-greeter.h

index 9ded6cad92982b954a4a1de1c8f08fde20184738..0de08ad32450530100c3e6f2f72d32dbcaaaf6a9 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 
-AC_INIT(lightdm, 1.10.0)
+AC_INIT(lightdm, 1.10.1)
 AC_CONFIG_MACRO_DIR(m4)
 AC_CONFIG_HEADER(config.h)
 AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz foreign])
index f8c1d2e01cee46e11fdbbcad2085a9c67ce06643..c558ccf9b4a0de3d52de3ed482a0e591da82e717 100644 (file)
@@ -1,3 +1,9 @@
+lightdm (1.10.1-0ubuntu1) UNRELEASED; urgency=medium
+
+  * Add lightdm_greeter_set_resettable
+
+ -- Michael Terry <mterry@ubuntu.com>  Wed, 23 Apr 2014 19:21:30 -0400
+
 lightdm (1.10.0-0ubuntu3) trusty; urgency=medium
 
   * debian/patches/06_apparmor_chromium_updates.patch: allow oxide based
index e9afdffa6de7da4992e3a85ddc6b736a175389d7..770e824edb650fe0837512bbbb059ba464242de7 100644 (file)
@@ -37,6 +37,7 @@ liblightdm-gobject-1.so.0 liblightdm-gobject-1-0 #MINVER#
  lightdm_greeter_new@Base 0.9.2
  lightdm_greeter_respond@Base 0.9.2
  lightdm_greeter_set_language@Base 0.9.8
+ lightdm_greeter_set_resettable@Base 1.10.1
  lightdm_greeter_start_session_sync@Base 0.9.2
  lightdm_hibernate@Base 0.9.2
  lightdm_language_get_code@Base 0.9.2
index c02f73ef7e51ff95d9f922a4362c58323b0a5acc..2f28464bbafd5988fcf5b9cd7b6baa26ee20b1d3 100644 (file)
@@ -39,6 +39,8 @@ enum {
     SHOW_MESSAGE,
     AUTHENTICATION_COMPLETE,
     AUTOLOGIN_TIMER_EXPIRED,
+    IDLE,
+    RESET,
     LAST_SIGNAL
 };
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -83,6 +85,7 @@ typedef enum
     GREETER_MESSAGE_SET_LANGUAGE,
     GREETER_MESSAGE_AUTHENTICATE_REMOTE,
     GREETER_MESSAGE_ENSURE_SHARED_DIR,
+    GREETER_MESSAGE_SET_RESETTABLE,
 } GreeterMessage;
 
 /* Messages from the server to the greeter */
@@ -93,6 +96,8 @@ typedef enum
     SERVER_MESSAGE_END_AUTHENTICATION,
     SERVER_MESSAGE_SESSION_RESULT,
     SERVER_MESSAGE_SHARED_DIR_RESULT,
+    SERVER_MESSAGE_IDLE,
+    SERVER_MESSAGE_RESET,
 } ServerMessage;
 
 /**
@@ -381,6 +386,31 @@ handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize messa
     g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
 }
 
+static void
+handle_reset (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
+{
+    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    GString *hint_string;
+
+    g_hash_table_remove_all (priv->hints);
+
+    hint_string = g_string_new ("");
+    while (*offset < message_length)
+    {
+        gchar *name, *value;
+
+        name = read_string (message, message_length, offset);
+        value = read_string (message, message_length, offset);
+        g_hash_table_insert (priv->hints, name, value);
+        g_string_append_printf (hint_string, " %s=%s", name, value);
+    }
+
+    g_debug ("Reset%s", hint_string->str);
+    g_string_free (hint_string, TRUE);
+
+    g_signal_emit (G_OBJECT (greeter), signals[RESET], 0);
+}
+
 static guint8 *
 read_message (LightDMGreeter *greeter, gsize *length, gboolean block)
 {
@@ -460,6 +490,12 @@ from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
     case SERVER_MESSAGE_END_AUTHENTICATION:
         handle_end_authentication (greeter, message, message_length, &offset);
         break;
+    case SERVER_MESSAGE_IDLE:
+        g_signal_emit (G_OBJECT (greeter), signals[IDLE], 0);
+        break;
+    case SERVER_MESSAGE_RESET:
+        handle_reset (greeter, message, message_length, &offset);
+        break;
     default:
         g_warning ("Unknown message from server: %d", id);
         break;
@@ -1056,6 +1092,31 @@ lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
     write_message (greeter, message, offset);
 }
 
+/**
+ * lightdm_greeter_set_resettable:
+ * @greeter: A #LightDMGreeter
+ * @resettable: Whether the greeter wants to be reset instead of killed after the user logs in
+ *
+ * Set whether the greeter will be reset instead of killed after the user logs in.
+ **/
+void
+lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable)
+{
+    LightDMGreeterPrivate *priv;
+    guint8 message[MAX_MESSAGE_LENGTH];
+    gsize offset = 0;
+
+    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+
+    priv = GET_PRIVATE (greeter);
+
+    g_return_if_fail (priv->connected);
+
+    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_RESETTABLE, int_length (), &offset);
+    write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset);
+    write_message (greeter, message, offset);
+}
+
 /**
  * lightdm_greeter_start_session_sync:
  * @greeter: A #LightDMGreeter
@@ -1460,4 +1521,42 @@ lightdm_greeter_class_init (LightDMGreeterClass *klass)
                       NULL, NULL,
                       NULL,
                       G_TYPE_NONE, 0);
+
+    /**
+     * LightDMGreeter::idle:
+     * @greeter: A #LightDMGreeter
+     *
+     * The ::idle signal gets emitted when the user has logged in and the
+     * greeter is no longer needed.
+     *
+     * This signal only matters if the greeter has marked itself as
+     * resettable using lightdm_greeter_set_resettable().
+     **/
+    signals[IDLE] =
+        g_signal_new ("idle",
+                      G_TYPE_FROM_CLASS (klass),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (LightDMGreeterClass, idle),
+                      NULL, NULL,
+                      NULL,
+                      G_TYPE_NONE, 0);
+
+    /**
+     * LightDMGreeter::reset:
+     * @greeter: A #LightDMGreeter
+     *
+     * The ::reset signal gets emitted when the user is returning to a greeter
+     * that was previously marked idle.
+     *
+     * This signal only matters if the greeter has marked itself as
+     * resettable using lightdm_greeter_set_resettable().
+     **/
+    signals[RESET] =
+        g_signal_new ("reset",
+                      G_TYPE_FROM_CLASS (klass),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (LightDMGreeterClass, reset),
+                      NULL, NULL,
+                      NULL,
+                      G_TYPE_NONE, 0);
 }
index ca1b26fb5777c3a9184cac47464c1e7a1a5910fa..438fb755d70fcfe5819a77eab7bf9aadea75c43c 100644 (file)
@@ -57,14 +57,14 @@ typedef struct
     void (*show_prompt)(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type);
     void (*authentication_complete)(LightDMGreeter *greeter);
     void (*autologin_timer_expired)(LightDMGreeter *greeter);
+    void (*idle)(LightDMGreeter *greeter);
+    void (*reset)(LightDMGreeter *greeter);
 
     /* Reserved */
     void (*reserved1) (void);
     void (*reserved2) (void);
     void (*reserved3) (void);
     void (*reserved4) (void);
-    void (*reserved5) (void);
-    void (*reserved6) (void);
 } LightDMGreeterClass;
 
 GType lightdm_greeter_get_type (void);
@@ -119,6 +119,8 @@ const gchar *lightdm_greeter_get_authentication_user (LightDMGreeter *greeter);
 
 void lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language);
 
+void lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable);
+
 gboolean lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error);
 
 gchar *lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username);
index 82916d00b1299d914e8f40fdbe5594b15ba7154b..8abf5e9260ba686ca4cc4c0ae4335cdfc94384af 100644 (file)
@@ -79,6 +79,7 @@ public Q_SLOTS:
     void respond(const QString &response);
     void cancelAuthentication();
     void setLanguage (const QString &language);
+    void setResettable (bool resettable);
     bool startSessionSync(const QString &session=QString());
     QString ensureSharedDataDirSync(const QString &username);
 
@@ -87,6 +88,8 @@ Q_SIGNALS:
     void showPrompt(QString text, QLightDM::Greeter::PromptType type);
     void authenticationComplete();
     void autologinTimerExpired();
+    void idle();
+    void reset();
 
 private:
     GreeterPrivate *d_ptr;
index 12e2db4c8e16191a38ffb2aeac3cf7fb19e9ff63..406a6321b02c7f12921fdcc6feb8fe3c2115fd56 100644 (file)
@@ -33,6 +33,8 @@ protected:
     static void cb_showMessage(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type, gpointer data);
     static void cb_authenticationComplete(LightDMGreeter *greeter, gpointer data);
     static void cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data);
+    static void cb_idle(LightDMGreeter *greeter, gpointer data);
+    static void cb_reset(LightDMGreeter *greeter, gpointer data);
     
 private:
     Q_DECLARE_PUBLIC(Greeter)
@@ -50,6 +52,8 @@ GreeterPrivate::GreeterPrivate(Greeter *parent) :
     g_signal_connect (ldmGreeter, "show-message", G_CALLBACK (cb_showMessage), this);
     g_signal_connect (ldmGreeter, "authentication-complete", G_CALLBACK (cb_authenticationComplete), this);
     g_signal_connect (ldmGreeter, "autologin-timer-expired", G_CALLBACK (cb_autoLoginExpired), this);
+    g_signal_connect (ldmGreeter, "idle", G_CALLBACK (cb_idle), this);
+    g_signal_connect (ldmGreeter, "reset", G_CALLBACK (cb_reset), this);
 }
 
 void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data)
@@ -88,6 +92,20 @@ void GreeterPrivate::cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data)
     Q_EMIT that->q_func()->autologinTimerExpired();
 }
 
+void GreeterPrivate::cb_idle(LightDMGreeter *greeter, gpointer data)
+{
+    Q_UNUSED(greeter);
+    GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
+    Q_EMIT that->q_func()->idle();
+}
+
+void GreeterPrivate::cb_reset(LightDMGreeter *greeter, gpointer data)
+{
+    Q_UNUSED(greeter);
+    GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
+    Q_EMIT that->q_func()->reset();
+}
+
 Greeter::Greeter(QObject *parent) :
     QObject(parent),
     d_ptr(new GreeterPrivate(this))
@@ -166,6 +184,12 @@ void Greeter::setLanguage (const QString &language)
     lightdm_greeter_set_language(d->ldmGreeter, language.toLocal8Bit().constData());
 }
 
+void Greeter::setResettable (bool resettable)
+{
+    Q_D(Greeter);
+    lightdm_greeter_set_resettable(d->ldmGreeter, resettable);
+}
+
 bool Greeter::startSessionSync(const QString &session)
 {
     Q_D(Greeter);
index 9c68556a3771415dd6bdb1dbfac305c1ce62d2de..7643fb53aa3e78fd29d230a846a81cfca72ca8e8 100644 (file)
@@ -63,6 +63,9 @@ struct GreeterPrivate
     /* PAM session being constructed by the greeter */
     Session *authentication_session;
 
+    /* TRUE if a the greeter can handle a reset; else we will just kill it instead */
+    gboolean resettable;
+
     /* TRUE if a user has been authenticated and the session requested to start */
     gboolean start_session;
 
@@ -92,6 +95,7 @@ typedef enum
     GREETER_MESSAGE_SET_LANGUAGE,
     GREETER_MESSAGE_AUTHENTICATE_REMOTE,
     GREETER_MESSAGE_ENSURE_SHARED_DIR,
+    GREETER_MESSAGE_SET_RESETTABLE,
 } GreeterMessage;
 
 /* Messages from the server to the greeter */
@@ -102,6 +106,8 @@ typedef enum
     SERVER_MESSAGE_END_AUTHENTICATION,
     SERVER_MESSAGE_SESSION_RESULT,
     SERVER_MESSAGE_SHARED_DIR_RESULT,
+    SERVER_MESSAGE_IDLE,
+    SERVER_MESSAGE_RESET,
 } ServerMessage;
 
 static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data);
@@ -127,6 +133,12 @@ greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest)
     greeter->priv->allow_guest = allow_guest;
 }
 
+void
+greeter_clear_hints (Greeter *greeter)
+{
+    g_hash_table_remove_all (greeter->priv->hints);
+}
+
 void
 greeter_set_hint (Greeter *greeter, const gchar *name, const gchar *value)
 {
@@ -315,6 +327,37 @@ send_end_authentication (Greeter *greeter, guint32 sequence_number, const gchar
     write_message (greeter, message, offset); 
 }
 
+void greeter_idle (Greeter *greeter)
+{
+    guint8 message[MAX_MESSAGE_LENGTH];
+    gsize offset = 0;
+
+    write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_IDLE, 0, &offset);
+    write_message (greeter, message, offset);
+}
+
+void greeter_reset (Greeter *greeter)
+{
+    guint8 message[MAX_MESSAGE_LENGTH];
+    gsize offset = 0;
+    guint32 length = 0;
+    GHashTableIter iter;
+    gpointer key, value;
+
+    g_hash_table_iter_init (&iter, greeter->priv->hints);
+    while (g_hash_table_iter_next (&iter, &key, &value))
+        length += string_length (key) + string_length (value);
+
+    write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_RESET, length, &offset);
+    g_hash_table_iter_init (&iter, greeter->priv->hints);
+    while (g_hash_table_iter_next (&iter, &key, &value))
+    {
+        write_string (message, MAX_MESSAGE_LENGTH, key, &offset);
+        write_string (message, MAX_MESSAGE_LENGTH, value, &offset);
+    }
+    write_message (greeter, message, offset);
+}
+
 static void
 authentication_complete_cb (Session *session, Greeter *greeter)
 {
@@ -837,6 +880,9 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
         handle_ensure_shared_dir (greeter, username);
         g_free (username);
         break;
+    case GREETER_MESSAGE_SET_RESETTABLE:
+        greeter->priv->resettable = read_int (greeter, &offset);
+        break;
     default:
         l_warning (greeter, "Unknown message from greeter: %d", id);
         break;
@@ -861,6 +907,13 @@ greeter_get_authentication_session (Greeter *greeter)
     return greeter->priv->authentication_session;
 }
 
+gboolean
+greeter_get_resettable (Greeter *greeter)
+{
+    g_return_val_if_fail (greeter != NULL, FALSE);
+    return greeter->priv->resettable;
+}
+
 gboolean
 greeter_get_start_session (Greeter *greeter)
 {
index 5fae00e4504974b8ae64164a770305500056e3b1..3aa126d63cf3910eb764d4379f2e725c3e62e5ce 100644 (file)
@@ -46,14 +46,22 @@ void greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const
 
 void greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest);
 
+void greeter_clear_hints (Greeter *greeter);
+
 void greeter_set_hint (Greeter *greeter, const gchar *name, const gchar *value);
 
+void greeter_idle (Greeter *greeter);
+
+void greeter_reset (Greeter *greeter);
+
 gboolean greeter_get_guest_authenticated (Greeter *greeter);
 
 Session *greeter_get_authentication_session (Greeter *greeter);
 
 gboolean greeter_get_start_session (Greeter *greeter);
 
+gboolean greeter_get_resettable (Greeter *greeter);
+
 const gchar *greeter_get_active_username (Greeter *greeter);
 
 G_END_DECLS
index cd8373c797fa33608dcc2250f90cea6ea025544a..10ec7a06aaad9d9fdf20d2e8ea60316823dfa97c 100644 (file)
@@ -220,8 +220,17 @@ seat_set_active_session (Seat *seat, Session *session)
 
         if (IS_GREETER (s))
         {
-            l_debug (seat, "Stopping greeter");
-            session_stop (s);
+            Greeter *greeter = GREETER (s);
+            if (greeter_get_resettable (greeter))
+            {
+                l_debug (seat, "Idling greeter");
+                greeter_idle (greeter);
+            }
+            else
+            {
+                l_debug (seat, "Stopping greeter");
+                session_stop (s);
+            }
         }
     }
 
@@ -430,36 +439,84 @@ can_share_display_server (Seat *seat, DisplayServer *display_server)
     return seat->priv->share_display_server && display_server_get_can_share (display_server);
 }
 
+static Greeter *
+find_greeter_session (Seat *seat)
+{
+    GList *link;
+
+    for (link = seat->priv->sessions; link; link = link->next)
+    {
+        Session *session = link->data;
+        if (!session_get_is_stopping (session) && IS_GREETER (session))
+            return GREETER (session);
+    }
+
+    return NULL;
+}
+
+static void
+reset_greeter_hints (Seat *seat, Greeter *greeter_session)
+{
+    greeter_clear_hints (greeter_session);    
+    greeter_set_hint (greeter_session, "default-session", seat_get_string_property (seat, "user-session"));
+    greeter_set_hint (greeter_session, "hide-users", seat_get_boolean_property (seat, "greeter-hide-users") ? "true" : "false");
+    greeter_set_hint (greeter_session, "show-manual-login", seat_get_boolean_property (seat, "greeter-show-manual-login") ? "true" : "false");
+    greeter_set_hint (greeter_session, "show-remote-login", seat_get_boolean_property (seat, "greeter-show-remote-login") ? "true" : "false");
+    greeter_set_hint (greeter_session, "has-guest-account", seat_get_allow_guest (seat) && seat_get_boolean_property (seat, "greeter-allow-guest") ? "true" : "false");
+}
+
 static void
 switch_to_greeter_from_failed_session (Seat *seat, Session *session)
 {
     Greeter *greeter_session;
+    gboolean existing = FALSE;
+
+    /* Switch to greeter if one open */
+    greeter_session = find_greeter_session (seat);
+    if (greeter_session)
+    {
+        l_debug (seat, "Switching to existing greeter");
+        reset_greeter_hints (seat, greeter_session);
+        existing = TRUE;
+    }
+    else
+    {
+        greeter_session = create_greeter_session (seat);
+    }
 
-    greeter_session = create_greeter_session (seat);
     if (session_get_is_guest (session))
         greeter_set_hint (greeter_session, "select-guest", "true");
     else
         greeter_set_hint (greeter_session, "select-user", session_get_username (session));
-    if (seat->priv->session_to_activate)
-        g_object_unref (seat->priv->session_to_activate);
-    seat->priv->session_to_activate = g_object_ref (greeter_session);
 
-    if (can_share_display_server (seat, session_get_display_server (session)))
-        session_set_display_server (SESSION (greeter_session), session_get_display_server (session));
+    if (existing)
+    {
+        greeter_reset (greeter_session);
+        seat_set_active_session (seat, SESSION (greeter_session));
+    }
     else
     {
-        DisplayServer *display_server;
+        if (seat->priv->session_to_activate)
+            g_object_unref (seat->priv->session_to_activate);
+        seat->priv->session_to_activate = g_object_ref (greeter_session);
 
-        display_server = create_display_server (seat, session_get_session_type (session));
-        session_set_display_server (session, display_server);
-        if (!display_server_start (display_server))
+        if (can_share_display_server (seat, session_get_display_server (session)))
+            session_set_display_server (SESSION (greeter_session), session_get_display_server (session));
+        else
         {
-            l_debug (seat, "Failed to start display server for greeter");
-            seat_stop (seat);
+            DisplayServer *display_server;
+
+            display_server = create_display_server (seat, session_get_session_type (session));
+            session_set_display_server (session, display_server);
+            if (!display_server_start (display_server))
+            {
+                l_debug (seat, "Failed to start display server for greeter");
+                seat_stop (seat);
+            }
         }
-    }
 
-    start_session (seat, SESSION (greeter_session));
+        start_session (seat, SESSION (greeter_session));
+    }
 
     /* Stop failed session */
     session_stop (session);
@@ -1160,12 +1217,8 @@ create_greeter_session (Seat *seat)
     g_signal_connect (greeter_session, "start-session", G_CALLBACK (greeter_start_session_cb), seat);
 
     /* Set hints to greeter */
-    greeter_set_hint (greeter_session, "default-session", seat_get_string_property (seat, "user-session"));
     greeter_set_allow_guest (greeter_session, seat_get_allow_guest (seat));
-    greeter_set_hint (greeter_session, "hide-users", seat_get_boolean_property (seat, "greeter-hide-users") ? "true" : "false");
-    greeter_set_hint (greeter_session, "show-manual-login", seat_get_boolean_property (seat, "greeter-show-manual-login") ? "true" : "false");
-    greeter_set_hint (greeter_session, "show-remote-login", seat_get_boolean_property (seat, "greeter-show-remote-login") ? "true" : "false");
-    greeter_set_hint (greeter_session, "has-guest-account", seat_get_allow_guest (seat) && seat_get_boolean_property (seat, "greeter-allow-guest") ? "true" : "false");
+    reset_greeter_hints (seat, greeter_session);
 
     g_object_unref (session_config);
 
@@ -1248,21 +1301,6 @@ create_display_server (Seat *seat, const gchar *session_type)
     return display_server;
 }
 
-static Greeter *
-find_greeter_session (Seat *seat)
-{
-    GList *link;
-
-    for (link = seat->priv->sessions; link; link = link->next)
-    {
-        Session *session = link->data;
-        if (!session_get_is_stopping (session) && IS_GREETER (session))
-            return GREETER (session);
-    }
-
-    return NULL;
-}
-
 gboolean
 seat_switch_to_greeter (Seat *seat)
 {
@@ -1274,7 +1312,7 @@ seat_switch_to_greeter (Seat *seat)
     if (!seat->priv->can_switch)
         return FALSE;
 
-    /* Switch to greeter if one open (shouldn't be though) */
+    /* Switch to greeter if one open */
     greeter_session = find_greeter_session (seat);
     if (greeter_session)
     {
@@ -1304,6 +1342,7 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
 {
     Greeter *greeter_session;
     DisplayServer *display_server;
+    gboolean existing = FALSE;
 
     /* If authenticated, then unlock existing session or start new one */
     if (session_get_is_authenticated (session))
@@ -1332,22 +1371,44 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
         return;
     }
 
-    l_debug (seat, "Switching to greeter to authenticate session");
-
     session_stop (session);
 
-    greeter_session = create_greeter_session (seat);
+    /* See if we already have a greeter up and reuse it if so.  Which will only
+       happen if the greeter marked itself as resettable and we thus didn't
+       kill it when a user session started */
+    greeter_session = find_greeter_session (seat);
+    if (greeter_session)
+    {
+        l_debug (seat, "Switching to existing greeter to authenticate session");
+        reset_greeter_hints (seat, greeter_session);
+        existing = TRUE;
+    }
+    else
+    {
+        l_debug (seat, "Starting greeter to authenticate session");
+        greeter_session = create_greeter_session (seat);
+    }
+
     if (session_get_is_guest (session))
         greeter_set_hint (greeter_session, "select-guest", "true");
     else
         greeter_set_hint (greeter_session, "select-user", session_get_username (session));
-    if (seat->priv->session_to_activate)
-        g_object_unref (seat->priv->session_to_activate);
-    seat->priv->session_to_activate = g_object_ref (greeter_session);
 
-    display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
-    session_set_display_server (SESSION (greeter_session), display_server);
-    display_server_start (display_server);
+    if (existing)
+    {
+        greeter_reset (greeter_session);
+        seat_set_active_session (seat, SESSION (greeter_session));
+    }
+    else
+    {
+        if (seat->priv->session_to_activate)
+            g_object_unref (seat->priv->session_to_activate);
+        seat->priv->session_to_activate = g_object_ref (greeter_session);
+
+        display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
+        session_set_display_server (SESSION (greeter_session), display_server);
+        display_server_start (display_server);
+    }
 }
 
 gboolean
@@ -1432,6 +1493,7 @@ seat_lock (Seat *seat, const gchar *username)
 {
     Greeter *greeter_session;
     DisplayServer *display_server;
+    gboolean existing = FALSE;
 
     g_return_val_if_fail (seat != NULL, FALSE);
 
@@ -1440,30 +1502,42 @@ seat_lock (Seat *seat, const gchar *username)
 
     l_debug (seat, "Locking");
 
-    /* Switch to greeter if one open (shouldn't be though) */
+    /* Switch to greeter if one open (only true if it's a resettable greeter) */
     greeter_session = find_greeter_session (seat);
     if (greeter_session)
     {
         l_debug (seat, "Switching to existing greeter");
-        seat_set_active_session (seat, SESSION (greeter_session));
-        return TRUE;
+        reset_greeter_hints (seat, greeter_session);
+        existing = TRUE;
+    }
+    else
+    {
+        greeter_session = create_greeter_session (seat);
+        if (!greeter_session)
+            return FALSE;
     }
 
-    greeter_session = create_greeter_session (seat);
-    if (!greeter_session)
-        return FALSE;
-
-    display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
-
-    if (seat->priv->session_to_activate)
-        g_object_unref (seat->priv->session_to_activate);
-    seat->priv->session_to_activate = g_object_ref (greeter_session);
     greeter_set_hint (greeter_session, "lock-screen", "true");
     if (username)
         greeter_set_hint (greeter_session, "select-user", username);
-    session_set_display_server (SESSION (greeter_session), display_server);
 
-    return display_server_start (display_server);
+    if (existing)
+    {
+        greeter_reset (greeter_session);
+        seat_set_active_session (seat, SESSION (greeter_session));
+        return TRUE;
+    }
+    else
+    {
+        display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
+
+        if (seat->priv->session_to_activate)
+            g_object_unref (seat->priv->session_to_activate);
+        seat->priv->session_to_activate = g_object_ref (greeter_session);
+        session_set_display_server (SESSION (greeter_session), display_server);
+
+        return display_server_start (display_server);
+    }
 }
 
 void
index 233df5c0fc7e56fc2faeb271ae9a6fcbdec57037..0be56c0b70f9ea2a610433f72e7076345f5c5b26 100644 (file)
@@ -64,6 +64,38 @@ sigterm_cb (gpointer user_data)
     return TRUE;
 }
 
+static void
+print_hints (LightDMGreeter *greeter)
+{
+    if (lightdm_greeter_get_select_user_hint (greeter))
+        status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, lightdm_greeter_get_select_user_hint (greeter));
+    if (lightdm_greeter_get_select_guest_hint (greeter))
+        status_notify ("%s SELECT-GUEST-HINT", greeter_id);
+    if (lightdm_greeter_get_lock_hint (greeter))
+        status_notify ("%s LOCK-HINT", greeter_id);
+    if (!lightdm_greeter_get_has_guest_account_hint (greeter))
+        status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
+    if (lightdm_greeter_get_hide_users_hint (greeter))
+        status_notify ("%s HIDE-USERS-HINT", greeter_id);
+    if (lightdm_greeter_get_show_manual_login_hint (greeter))
+        status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
+    if (!lightdm_greeter_get_show_remote_login_hint (greeter))
+        status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+}
+
+static void
+idle_cb (LightDMGreeter *greeter)
+{
+    status_notify ("%s IDLE", greeter_id);
+}
+
+static void
+reset_cb (LightDMGreeter *greeter)
+{
+    status_notify ("%s RESET", greeter_id);
+    print_hints (greeter);
+}
+
 static void
 user_changed_cb (LightDMUser *user)
 {
@@ -405,6 +437,13 @@ main (int argc, char **argv)
         g_signal_connect (lightdm_user_list_get_instance (), "user-removed", G_CALLBACK (user_removed_cb), NULL);
     }
 
+    if (g_key_file_get_boolean (config, "test-greeter-config", "resettable", NULL))
+    {
+        lightdm_greeter_set_resettable (greeter, TRUE);
+        g_signal_connect (greeter, "idle", G_CALLBACK (idle_cb), NULL);
+        g_signal_connect (greeter, "reset", G_CALLBACK (reset_cb), NULL);
+    }
+
     status_notify ("%s CONNECT-TO-DAEMON", greeter_id);
     if (!lightdm_greeter_connect_sync (greeter, NULL))
     {
@@ -414,20 +453,7 @@ main (int argc, char **argv)
 
     status_notify ("%s CONNECTED-TO-DAEMON", greeter_id);
 
-    if (lightdm_greeter_get_select_user_hint (greeter))
-        status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, lightdm_greeter_get_select_user_hint (greeter));
-    if (lightdm_greeter_get_select_guest_hint (greeter))
-        status_notify ("%s SELECT-GUEST-HINT", greeter_id);
-    if (lightdm_greeter_get_lock_hint (greeter))
-        status_notify ("%s LOCK-HINT", greeter_id);
-    if (!lightdm_greeter_get_has_guest_account_hint (greeter))
-        status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
-    if (lightdm_greeter_get_hide_users_hint (greeter))
-        status_notify ("%s HIDE-USERS-HINT", greeter_id);
-    if (lightdm_greeter_get_show_manual_login_hint (greeter))
-        status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
-    if (!lightdm_greeter_get_show_remote_login_hint (greeter))
-        status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+    print_hints (greeter);
 
     g_main_loop_run (loop);
 
index f8e5c3738836e5701ae6e70426387d15a4bcaaad..2bc80e3e6c130f74a4d1df65b6bebf9ac23ec016 100755 (executable)
@@ -185,6 +185,22 @@ def request_cb (channel, condition):
 
     return True
 
+def print_hints (greeter):
+    if greeter.get_select_user_hint () is not None:
+        status_notify ('%s SELECT-USER-HINT USERNAME=%s' % (greeter_id, greeter.get_select_user_hint ()))
+    if greeter.get_select_guest_hint ():
+        status_notify ('%s SELECT-GUEST-HINT' % greeter_id)
+    if greeter.get_lock_hint ():
+        status_notify ('%s LOCK-HINT' % greeter_id)
+    if not greeter.get_has_guest_account_hint ():
+        status_notify ('%s HAS-GUEST-ACCOUNT-HINT=FALSE' % greeter_id)
+    if greeter.get_hide_users_hint ():
+        status_notify ('%s HIDE-USERS-HINT' % greeter_id)
+    if greeter.get_show_manual_login_hint ():
+        status_notify ('%s SHOW-MANUAL-LOGIN-HINT' % greeter_id)
+    if not greeter.get_show_remote_login_hint ():
+        status_notify ('%s SHOW-REMOTE-LOGIN-HINT=FALSE' % greeter_id)
+
 path = os.getenv ('LIGHTDM_TEST_ROOT') + '/.s'
 status_socket = socket.socket (socket.AF_UNIX, socket.SOCK_STREAM)
 status_socket.connect (path)
@@ -254,6 +270,21 @@ if log_user_changes:
     LightDM.UserList.get_instance ().connect ('user-added', user_added_cb)
     LightDM.UserList.get_instance ().connect ('user-removed', user_removed_cb)
 
+def idle_cb (greeter):
+    status_notify ('%s IDLE' % (greeter_id))
+def reset_cb (greeter):
+    status_notify ('%s RESET' % (greeter_id))
+    print_hints (greeter)
+resettable = False
+try:
+    resettable = config.get_boolean ('test-greeter-config', 'resettable')
+except:
+    pass
+if resettable:
+    LightDM.Greeter.get_instance ().set_resettable (True)
+    LightDM.Greeter.get_instance ().connect ('idle', idle_cb)
+    LightDM.Greeter.get_instance ().connect ('reset', reset_cb)
+
 status_notify ('%s CONNECT-TO-DAEMON' % greeter_id)
 if not greeter.connect_sync ():
     status_notify ('%s FAIL-CONNECT-DAEMON' % greeter_id)
@@ -261,19 +292,6 @@ if not greeter.connect_sync ():
 
 status_notify ('%s CONNECTED-TO-DAEMON' % greeter_id)
 
-if greeter.get_select_user_hint () is not None:
-    status_notify ('%s SELECT-USER-HINT USERNAME=%s' % (greeter_id, greeter.get_select_user_hint ()))
-if greeter.get_select_guest_hint ():
-    status_notify ('%s SELECT-GUEST-HINT' % greeter_id)
-if greeter.get_lock_hint ():
-    status_notify ('%s LOCK-HINT' % greeter_id)
-if not greeter.get_has_guest_account_hint ():
-    status_notify ('%s HAS-GUEST-ACCOUNT-HINT=FALSE' % greeter_id)
-if greeter.get_hide_users_hint ():
-    status_notify ('%s HIDE-USERS-HINT' % greeter_id)
-if greeter.get_show_manual_login_hint ():
-    status_notify ('%s SHOW-MANUAL-LOGIN-HINT' % greeter_id)
-if not greeter.get_show_remote_login_hint ():
-    status_notify ('%s SHOW-REMOTE-LOGIN-HINT=FALSE' % greeter_id)
+print_hints (greeter)
 
 loop.run ()
index 29434c7b068f1dbabe4379d669860c2a56e26ec9..bac1fea8cadb96748ec803e11b5b50e168576767 100644 (file)
@@ -54,6 +54,36 @@ void TestGreeter::autologinTimerExpired ()
     status_notify ("%s AUTOLOGIN-TIMER-EXPIRED", greeter_id);
 }
 
+void TestGreeter::printHints ()
+{
+    if (selectUserHint() != "")
+        status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, greeter->selectUserHint ().toAscii ().constData ());
+    if (selectGuestHint())
+        status_notify ("%s SELECT-GUEST-HINT", greeter_id);
+    if (lockHint())
+        status_notify ("%s LOCK-HINT", greeter_id);
+    if (!hasGuestAccountHint ())
+        status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
+    if (hideUsersHint ())
+        status_notify ("%s HIDE-USERS-HINT", greeter_id);
+    if (showManualLoginHint ())
+        status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
+    if (!showRemoteLoginHint ())
+        status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+
+}
+
+void TestGreeter::idle ()
+{
+    status_notify ("%s IDLE", greeter_id);
+}
+
+void TestGreeter::reset ()
+{
+    status_notify ("%s RESET", greeter_id);
+    printHints ();
+}
+
 void TestGreeter::userRowsInserted (const QModelIndex & parent, int start, int end)
 {
     for (int i = start; i <= end; i++)
@@ -268,6 +298,13 @@ main(int argc, char *argv[])
         QObject::connect (users_model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), greeter, SLOT(userRowsRemoved(const QModelIndex&, int, int)));
     }
 
+    if (config->value ("test-greeter-config/resettable", "false") == "true")
+    {
+        greeter->setResettable (true);
+        QObject::connect (greeter, SIGNAL(idle()), greeter, SLOT(idle()));
+        QObject::connect (greeter, SIGNAL(reset()), greeter, SLOT(reset()));
+    }
+
     status_notify ("%s CONNECT-TO-DAEMON", greeter_id);
     if (!greeter->connectSync())
     {
@@ -277,20 +314,7 @@ main(int argc, char *argv[])
 
     status_notify ("%s CONNECTED-TO-DAEMON", greeter_id);
 
-    if (greeter->selectUserHint() != "")
-        status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, greeter->selectUserHint ().toAscii ().constData ());
-    if (greeter->selectGuestHint())
-        status_notify ("%s SELECT-GUEST-HINT", greeter_id);
-    if (greeter->lockHint())
-        status_notify ("%s LOCK-HINT", greeter_id);
-    if (!greeter->hasGuestAccountHint ())
-        status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
-    if (greeter->hideUsersHint ())
-        status_notify ("%s HIDE-USERS-HINT", greeter_id);
-    if (greeter->showManualLoginHint ())
-        status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
-    if (!greeter->showRemoteLoginHint ())
-        status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+    greeter->printHints();
 
     return app->exec();
 }
index 10a10db062189eef470bd01ff16af0d6d37f685b..b6ff127077624070897d40918717523c73710a71 100644 (file)
@@ -8,6 +8,8 @@ class TestGreeter : public QLightDM::Greeter
 public:
     TestGreeter ();
 
+    void printHints();
+
 private Q_SLOTS:
     void showMessage(QString text, QLightDM::Greeter::MessageType type);
     void showPrompt(QString text, QLightDM::Greeter::PromptType type);
@@ -15,4 +17,6 @@ private Q_SLOTS:
     void autologinTimerExpired();
     void userRowsInserted(const QModelIndex & parent, int start, int end);
     void userRowsRemoved(const QModelIndex & parent, int start, int end);
+    void idle();
+    void reset();
 };