Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /* gkd-dbus-session.c - daemon registering with the session
3 :
4 : Copyright (C) 2007, 2009, Stefan Walter
5 :
6 : The Gnome Keyring Library is free software; you can redistribute it and/or
7 : modify it under the terms of the GNU Library General Public License as
8 : published by the Free Software Foundation; either version 2 of the
9 : License, or (at your option) any later version.
10 :
11 : The Gnome Keyring Library is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Library General Public License for more details.
15 :
16 : You should have received a copy of the GNU Library General Public
17 : License along with the Gnome Library; see the file COPYING.LIB. If not,
18 : <http://www.gnu.org/licenses/>.
19 :
20 : Author: Stef Walter <stef@memberwebs.com>
21 : */
22 :
23 : #include "config.h"
24 :
25 : #include "gkd-dbus-private.h"
26 :
27 : #include "daemon/gkd-main.h"
28 :
29 : #include <string.h>
30 :
31 : #define SERVICE_SESSION_MANAGER "org.gnome.SessionManager"
32 : #define PATH_SESSION_MANAGER "/org/gnome/SessionManager"
33 : #define IFACE_SESSION_MANAGER "org.gnome.SessionManager"
34 : #define IFACE_SESSION_CLIENT "org.gnome.SessionManager.Client"
35 : #define IFACE_SESSION_PRIVATE "org.gnome.SessionManager.ClientPrivate"
36 :
37 : static gchar *client_session_path = NULL;
38 : static guint client_session_signal_id = 0;
39 :
40 : static void
41 0 : send_end_session_response (GDBusConnection *conn)
42 : {
43 0 : const gchar *reason = "";
44 0 : gboolean is_ok = TRUE;
45 0 : GError *error = NULL;
46 : GVariant *res;
47 :
48 0 : g_return_if_fail (client_session_path);
49 :
50 0 : res = g_dbus_connection_call_sync (conn,
51 : SERVICE_SESSION_MANAGER,
52 : client_session_path,
53 : IFACE_SESSION_PRIVATE,
54 : "EndSessionResponse",
55 : g_variant_new ("(bs)",
56 : is_ok,
57 : reason),
58 : NULL,
59 : G_DBUS_CALL_FLAGS_NONE, 1000,
60 : NULL, &error);
61 :
62 0 : if (error != NULL) {
63 0 : g_message ("dbus failure responding to ending session: %s", error->message);
64 0 : g_error_free (error);
65 0 : return;
66 : }
67 :
68 0 : g_variant_unref (res);
69 : }
70 :
71 : static void
72 0 : unregister_daemon_in_session (GDBusConnection *conn)
73 : {
74 : GVariant *res;
75 :
76 0 : if (client_session_signal_id) {
77 0 : g_dbus_connection_signal_unsubscribe (conn, client_session_signal_id);
78 0 : client_session_signal_id = 0;
79 : }
80 :
81 0 : if (!client_session_path)
82 0 : return;
83 :
84 0 : res = g_dbus_connection_call_sync (conn,
85 : SERVICE_SESSION_MANAGER,
86 : PATH_SESSION_MANAGER,
87 : IFACE_SESSION_MANAGER,
88 : "UnregisterClient",
89 : g_variant_new ("(o)", client_session_path),
90 : NULL, G_DBUS_CALL_FLAGS_NONE,
91 : -1, NULL, NULL);
92 :
93 0 : g_free (client_session_path);
94 0 : client_session_path = NULL;
95 :
96 0 : g_clear_pointer (&res, g_variant_unref);
97 : }
98 :
99 : static void
100 0 : signal_filter (GDBusConnection *conn,
101 : const gchar *sender_name,
102 : const gchar *object_path,
103 : const gchar *interface_name,
104 : const gchar *signal_name,
105 : GVariant *parameters,
106 : gpointer user_data)
107 : {
108 : /* Quit the daemon when the session is over */
109 0 : if (g_strcmp0 (signal_name, "Stop") == 0) {
110 0 : unregister_daemon_in_session (conn);
111 0 : gkd_main_quit ();
112 0 : } else if (g_strcmp0 (signal_name, "QueryEndSession") == 0) {
113 0 : send_end_session_response (conn);
114 0 : } else if (g_strcmp0 (signal_name, "EndSession") == 0) {
115 0 : send_end_session_response (conn);
116 0 : unregister_daemon_in_session (conn);
117 0 : gkd_main_quit ();
118 0 : } else if (g_strcmp0 (signal_name, "Disconnected") == 0) {
119 0 : gkd_main_quit ();
120 : }
121 0 : }
122 :
123 : void
124 27 : gkd_dbus_session_cleanup (GDBusConnection *conn)
125 : {
126 27 : g_free (client_session_path);
127 27 : client_session_path = NULL;
128 27 : }
129 :
130 : /*
131 : * Here we register our desktop autostart id gnome-session style
132 : * session manager via DBus.
133 : */
134 : void
135 27 : gkd_dbus_session_init (GDBusConnection *conn)
136 : {
137 27 : const gchar *app_id = "gnome-keyring-daemon";
138 : const gchar *client_id;
139 27 : GError *error = NULL;
140 : GVariant *object_path_variant;
141 :
142 27 : client_id = g_getenv ("DESKTOP_AUTOSTART_ID");
143 27 : if (!client_id)
144 27 : return;
145 :
146 0 : object_path_variant = g_dbus_connection_call_sync (conn,
147 : SERVICE_SESSION_MANAGER,
148 : PATH_SESSION_MANAGER,
149 : IFACE_SESSION_MANAGER,
150 : "RegisterClient",
151 : g_variant_new ("(ss)",
152 : app_id,
153 : client_id),
154 : G_VARIANT_TYPE ("(o)"),
155 : G_DBUS_CALL_FLAGS_NONE, 1000,
156 : NULL, &error);
157 :
158 0 : if (error != NULL) {
159 0 : g_message ("couldn't register in session: %s", error->message);
160 0 : g_error_free (error);
161 0 : return;
162 : }
163 :
164 0 : g_variant_get (object_path_variant, "(o)", &client_session_path);
165 0 : g_variant_unref (object_path_variant);
166 :
167 : /*
168 : * Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
169 : * use the same client id.
170 : */
171 0 : g_unsetenv ("DESKTOP_AUTOSTART_ID");
172 :
173 : /*
174 : * Now we register for DBus signals on that client session path
175 : * These are fired specifically for us.
176 : */
177 0 : client_session_signal_id = g_dbus_connection_signal_subscribe (conn,
178 : NULL,
179 : "org.gnome.SessionManager.ClientPrivate", NULL,
180 : client_session_path, NULL,
181 : G_DBUS_SIGNAL_FLAGS_NONE,
182 : signal_filter, NULL, NULL);
183 : }
|