~unity8-desktop-session-team/indicator-session/indicator-session-using-upstart

« back to all changes in this revision

Viewing changes to src/backend-dbus/guest.c

  • Committer: Charles Kerr
  • Date: 2012-07-06 20:11:40 UTC
  • Revision ID: charles.kerr@canonical.com-20120706201140-q0n8a8jo68dpsmwu
if tests aren't explicitly requested, don't fail the build if dbus-test-runner isn't installed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2013 Canonical Ltd.
3
 
 *
4
 
 * Authors:
5
 
 *   Charles Kerr <charles.kerr@canonical.com>
6
 
 *
7
 
 * This program is free software: you can redistribute it and/or modify it
8
 
 * under the terms of the GNU General Public License version 3, as published
9
 
 * by the Free Software Foundation.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful, but
12
 
 * WITHOUT ANY WARRANTY; without even the implied warranties of
13
 
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14
 
 * PURPOSE.  See the GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License along
17
 
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
#include <glib.h>
21
 
 
22
 
#include "guest.h"
23
 
 
24
 
struct _IndicatorSessionGuestDbusPriv
25
 
{
26
 
  GCancellable * cancellable;
27
 
 
28
 
  Login1Manager * login1_manager;
29
 
  Login1Seat * login1_seat;
30
 
  DisplayManagerSeat * dm_seat;
31
 
 
32
 
  gboolean guest_is_active;
33
 
  gboolean guest_is_logged_in;
34
 
  gboolean guest_is_allowed;
35
 
};
36
 
 
37
 
typedef IndicatorSessionGuestDbusPriv priv_t;
38
 
 
39
 
G_DEFINE_TYPE (IndicatorSessionGuestDbus,
40
 
               indicator_session_guest_dbus,
41
 
               INDICATOR_TYPE_SESSION_GUEST)
42
 
 
43
 
/***
44
 
****
45
 
***/
46
 
 
47
 
static void
48
 
set_guest_is_allowed_flag (IndicatorSessionGuestDbus * self, gboolean b)
49
 
{
50
 
  priv_t * p = self->priv;
51
 
 
52
 
  if (p->guest_is_allowed != b)
53
 
    {
54
 
      p->guest_is_allowed = b;
55
 
 
56
 
      indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self));
57
 
    }
58
 
}
59
 
 
60
 
static void
61
 
set_guest_is_logged_in_flag (IndicatorSessionGuestDbus * self, gboolean b)
62
 
{
63
 
  priv_t * p = self->priv;
64
 
 
65
 
  if (p->guest_is_logged_in != b)
66
 
    {
67
 
      p->guest_is_logged_in = b;
68
 
 
69
 
      indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST (self));
70
 
    }
71
 
}
72
 
 
73
 
static void
74
 
set_guest_is_active_flag (IndicatorSessionGuestDbus * self, gboolean b)
75
 
{
76
 
  priv_t * p = self->priv;
77
 
 
78
 
  if (p->guest_is_active != b)
79
 
    {
80
 
      p->guest_is_active = b;
81
 
 
82
 
      indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self));
83
 
    }
84
 
}
85
 
 
86
 
/***
87
 
****
88
 
***/
89
 
 
90
 
/* walk the sessions to see if guest is logged in or active */
91
 
static void
92
 
on_login1_manager_session_list_ready (GObject      * o,
93
 
                                      GAsyncResult * res,
94
 
                                      gpointer       gself)
95
 
{
96
 
  GVariant * sessions;
97
 
  GError * err;
98
 
 
99
 
  sessions = NULL;
100
 
  err = NULL;
101
 
  login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o),
102
 
                                            &sessions,
103
 
                                            res,
104
 
                                            &err);
105
 
  if (err != NULL)
106
 
    {
107
 
      if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
108
 
        g_warning ("%s: %s", G_STRFUNC, err->message);
109
 
 
110
 
      g_error_free (err);
111
 
    }
112
 
  else
113
 
    {
114
 
      const gchar * const current_seat_id = g_getenv ("XDG_SEAT");
115
 
      const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID");
116
 
      gboolean is_logged_in = FALSE;
117
 
      gboolean is_active = FALSE;
118
 
      const gchar * session_id = NULL;
119
 
      guint32 uid = 0;
120
 
      const gchar * user_name = NULL;
121
 
      const gchar * seat_id = NULL;
122
 
      GVariantIter iter;
123
 
 
124
 
      g_variant_iter_init (&iter, sessions);
125
 
      while (g_variant_iter_loop (&iter, "(&su&s&so)", &session_id,
126
 
                                                        &uid,
127
 
                                                        &user_name,
128
 
                                                        &seat_id,
129
 
                                                        NULL))
130
 
        {
131
 
          gboolean is_current_session;
132
 
          gboolean is_guest;
133
 
 
134
 
          is_current_session = !g_strcmp0 (current_seat_id, seat_id)
135
 
                            && !g_strcmp0 (current_session_id, session_id);
136
 
 
137
 
          is_guest = g_str_has_prefix (user_name, "guest-")
138
 
                  && (uid < 1000);
139
 
 
140
 
          if (is_guest)
141
 
            {
142
 
              is_logged_in = TRUE;
143
 
 
144
 
              is_active = is_current_session;
145
 
            }
146
 
        }
147
 
 
148
 
      set_guest_is_logged_in_flag (gself, is_logged_in);
149
 
      set_guest_is_active_flag (gself, is_active);
150
 
 
151
 
      g_variant_unref (sessions);
152
 
    }
153
 
}
154
 
 
155
 
static void
156
 
update_session_list (IndicatorSessionGuestDbus * self)
157
 
{
158
 
  priv_t * p = self->priv;
159
 
 
160
 
  if (p->login1_manager != NULL)
161
 
    {
162
 
      login1_manager_call_list_sessions (p->login1_manager,
163
 
                                         p->cancellable,
164
 
                                         on_login1_manager_session_list_ready,
165
 
                                         self);
166
 
    }
167
 
}
168
 
 
169
 
static void
170
 
set_login1_manager (IndicatorSessionGuestDbus * self,
171
 
                    Login1Manager             * login1_manager)
172
 
{
173
 
  priv_t * p = self->priv;
174
 
 
175
 
  if (p->login1_manager != NULL)
176
 
    {
177
 
      g_signal_handlers_disconnect_by_data (p->login1_manager, self);
178
 
 
179
 
      g_clear_object (&p->login1_manager);
180
 
    }
181
 
 
182
 
  if (login1_manager != NULL)
183
 
    {
184
 
      p->login1_manager = g_object_ref (login1_manager);
185
 
 
186
 
      g_signal_connect_swapped (login1_manager, "session-new",
187
 
                                G_CALLBACK(update_session_list), self);
188
 
      g_signal_connect_swapped (login1_manager, "session-removed",
189
 
                                G_CALLBACK(update_session_list), self);
190
 
      update_session_list (self);
191
 
    }
192
 
}
193
 
 
194
 
static void
195
 
set_login1_seat (IndicatorSessionGuestDbus * self,
196
 
                 Login1Seat                * login1_seat)
197
 
{
198
 
  priv_t * p = self->priv;
199
 
 
200
 
  if (p->login1_seat != NULL)
201
 
    {
202
 
      g_signal_handlers_disconnect_by_data (p->login1_seat, self);
203
 
      g_clear_object (&p->login1_seat);
204
 
    }
205
 
 
206
 
  if (login1_seat != NULL)
207
 
    {
208
 
      p->login1_seat = g_object_ref (login1_seat);
209
 
 
210
 
      g_signal_connect_swapped (login1_seat, "notify::active-session",
211
 
                                G_CALLBACK(update_session_list), self);
212
 
      update_session_list (self);
213
 
    }
214
 
}
215
 
 
216
 
/***
217
 
****
218
 
***/
219
 
 
220
 
static void
221
 
on_switch_to_guest_done (GObject      * o,
222
 
                         GAsyncResult * res,
223
 
                         gpointer       unused G_GNUC_UNUSED)
224
 
{
225
 
  GError * err;
226
 
 
227
 
  err = NULL;
228
 
  display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o),
229
 
                                                    res,
230
 
                                                    &err);
231
 
  if (err != NULL)
232
 
    {
233
 
      if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
234
 
        g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message);
235
 
 
236
 
      g_error_free (err);
237
 
    }
238
 
}
239
 
 
240
 
static void
241
 
my_switch_to_guest (IndicatorSessionGuest * guest)
242
 
{
243
 
  IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS(guest);
244
 
 
245
 
  g_return_if_fail (self != NULL);
246
 
  g_return_if_fail (self->priv->dm_seat != NULL);
247
 
 
248
 
  display_manager_seat_call_switch_to_guest (self->priv->dm_seat,
249
 
                                             "",
250
 
                                             self->priv->cancellable,
251
 
                                             on_switch_to_guest_done,
252
 
                                             self);
253
 
}
254
 
 
255
 
static void
256
 
on_notify_has_guest_account (DisplayManagerSeat        * dm_seat,
257
 
                             GParamSpec                * pspec G_GNUC_UNUSED,
258
 
                             IndicatorSessionGuestDbus * self)
259
 
{
260
 
  gboolean guest_exists = display_manager_seat_get_has_guest_account (dm_seat);
261
 
  set_guest_is_allowed_flag (self, guest_exists);
262
 
}
263
 
 
264
 
static void
265
 
set_display_manager_seat (IndicatorSessionGuestDbus * self,
266
 
                          DisplayManagerSeat        * dm_seat)
267
 
{
268
 
  priv_t * p = self->priv;
269
 
 
270
 
  if (p->dm_seat != NULL)
271
 
    {
272
 
      g_signal_handlers_disconnect_by_data (p->dm_seat, self);
273
 
 
274
 
      g_clear_object (&p->dm_seat);
275
 
    }
276
 
 
277
 
  if (dm_seat != NULL)
278
 
    {
279
 
      p->dm_seat = g_object_ref (dm_seat);
280
 
 
281
 
      g_signal_connect (dm_seat, "notify::has-guest-account",
282
 
                        G_CALLBACK(on_notify_has_guest_account), self);
283
 
      on_notify_has_guest_account (dm_seat, NULL, self);
284
 
    }
285
 
}
286
 
 
287
 
/***
288
 
****  IndiatorSessionGuest Virtual Functions
289
 
***/
290
 
 
291
 
static gboolean
292
 
my_is_allowed (IndicatorSessionGuest * self)
293
 
{
294
 
  g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE);
295
 
 
296
 
  return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_allowed;
297
 
}
298
 
 
299
 
static gboolean
300
 
my_is_logged_in (IndicatorSessionGuest * self)
301
 
{
302
 
  g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE);
303
 
 
304
 
  return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_logged_in;
305
 
}
306
 
 
307
 
static gboolean
308
 
my_is_active (IndicatorSessionGuest * self)
309
 
{
310
 
  g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE);
311
 
 
312
 
  return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_active;
313
 
}
314
 
 
315
 
/***
316
 
****  GObject Virtual Functions
317
 
***/
318
 
 
319
 
static void
320
 
my_dispose (GObject * o)
321
 
{
322
 
  IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o);
323
 
 
324
 
  if (self->priv->cancellable != NULL)
325
 
    {
326
 
      g_cancellable_cancel (self->priv->cancellable);
327
 
      g_clear_object (&self->priv->cancellable);
328
 
    }
329
 
 
330
 
  set_login1_seat (self, NULL);
331
 
  set_login1_manager (self, NULL);
332
 
  set_display_manager_seat (self, NULL);
333
 
 
334
 
  G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o);
335
 
}
336
 
 
337
 
/***
338
 
****  Instantiation
339
 
***/
340
 
 
341
 
static void
342
 
indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass)
343
 
{
344
 
  GObjectClass * object_class;
345
 
  IndicatorSessionGuestClass * guest_class;
346
 
 
347
 
  object_class = G_OBJECT_CLASS (klass);
348
 
  object_class->dispose = my_dispose;
349
 
 
350
 
  guest_class = INDICATOR_SESSION_GUEST_CLASS (klass);
351
 
  guest_class->is_allowed = my_is_allowed;
352
 
  guest_class->is_logged_in = my_is_logged_in;
353
 
  guest_class->is_active = my_is_active;
354
 
  guest_class->switch_to_guest = my_switch_to_guest;
355
 
 
356
 
  g_type_class_add_private (klass, sizeof (IndicatorSessionGuestDbusPriv));
357
 
}
358
 
 
359
 
static void
360
 
indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self)
361
 
{
362
 
  priv_t * p;
363
 
 
364
 
  p = G_TYPE_INSTANCE_GET_PRIVATE (self,
365
 
                                   INDICATOR_TYPE_SESSION_GUEST_DBUS,
366
 
                                   IndicatorSessionGuestDbusPriv);
367
 
  p->cancellable = g_cancellable_new ();
368
 
  self->priv = p;
369
 
}
370
 
 
371
 
/***
372
 
****  Public
373
 
***/
374
 
 
375
 
IndicatorSessionGuest *
376
 
indicator_session_guest_dbus_new (void)
377
 
{
378
 
  gpointer o = g_object_new (INDICATOR_TYPE_SESSION_GUEST_DBUS, NULL);
379
 
 
380
 
  return INDICATOR_SESSION_GUEST (o);
381
 
}
382
 
 
383
 
void
384
 
indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self,
385
 
                                          Login1Manager             * login1_manager,
386
 
                                          Login1Seat                * login1_seat,
387
 
                                          DisplayManagerSeat        * dm_seat)
388
 
{
389
 
  g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self));
390
 
 
391
 
  set_login1_manager (self, login1_manager);
392
 
  set_login1_seat (self, login1_seat);
393
 
  set_display_manager_seat (self, dm_seat);
394
 
}