~codygarver/+junk/ind-sess

« back to all changes in this revision

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

  • Committer: Cody Garver
  • Date: 2014-04-03 17:08:08 UTC
  • Revision ID: cody@elementaryos.org-20140403170808-z56s93rorb1dzvmk
Initial import, version 12.10.5+14.04.20140324-0ubuntu1

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 "dbus-user.h"
 
21
 
 
22
#include "users.h"
 
23
 
 
24
struct _IndicatorSessionUsersDbusPriv
 
25
{
 
26
  Login1Manager * login1_manager;
 
27
  Login1Seat * login1_seat;
 
28
  DisplayManagerSeat * dm_seat;
 
29
  Accounts * accounts;
 
30
 
 
31
  /* hash table of int uids to UserRecord* */
 
32
  GHashTable * uid_to_account;
 
33
 
 
34
  /* a hashset of int uids of users who are logged in */
 
35
  GHashTable * logins;
 
36
 
 
37
  /* the user-id of the owner of the active session */
 
38
  guint active_uid;
 
39
 
 
40
  /* true if this is a live session */
 
41
  gboolean is_live;
 
42
 
 
43
  GCancellable * cancellable;
 
44
 
 
45
  guint update_list_tag;
 
46
};
 
47
 
 
48
typedef IndicatorSessionUsersDbusPriv priv_t;
 
49
 
 
50
G_DEFINE_TYPE (IndicatorSessionUsersDbus,
 
51
               indicator_session_users_dbus,
 
52
               INDICATOR_TYPE_SESSION_USERS)
 
53
 
 
54
/***
 
55
****
 
56
***/
 
57
 
 
58
struct UserRecord
 
59
{
 
60
  AccountsUser * user;
 
61
 
 
62
  gulong signal_id;
 
63
};
 
64
 
 
65
struct UserRecord *
 
66
user_record_new (AccountsUser * user, gulong signal_id)
 
67
{
 
68
  struct UserRecord * rec;
 
69
  rec = g_new (struct UserRecord, 1);
 
70
  rec->user = g_object_ref (user);
 
71
  rec->signal_id = signal_id;
 
72
  return rec;
 
73
}
 
74
 
 
75
static void
 
76
user_record_free (struct UserRecord * rec)
 
77
{
 
78
  g_signal_handler_disconnect (rec->user, rec->signal_id);
 
79
  g_object_unref (G_OBJECT (rec->user));
 
80
  g_free (rec);
 
81
}
 
82
 
 
83
/***
 
84
****
 
85
***/
 
86
 
 
87
/* get our private org.freedesktop.Accounts.User proxy for the given uid */
 
88
static AccountsUser *
 
89
get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid)
 
90
{
 
91
  struct UserRecord * rec;
 
92
 
 
93
  if ((rec = g_hash_table_lookup (self->priv->uid_to_account,
 
94
                                  GUINT_TO_POINTER(uid))))
 
95
    return rec->user;
 
96
 
 
97
  return NULL;
 
98
}
 
99
 
 
100
static gboolean
 
101
is_tracked_uid (IndicatorSessionUsersDbus * self, guint uid)
 
102
{
 
103
  return get_user_for_uid (self, uid) != NULL;
 
104
}
 
105
 
 
106
static void
 
107
emit_user_added (IndicatorSessionUsersDbus * self, guint32 uid)
 
108
{
 
109
  if (is_tracked_uid (self, uid))
 
110
    indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid);
 
111
}
 
112
 
 
113
static void
 
114
emit_user_changed (IndicatorSessionUsersDbus * self, guint32 uid)
 
115
{
 
116
  if (is_tracked_uid (self, uid))
 
117
    indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid);
 
118
}
 
119
 
 
120
static void
 
121
emit_user_removed (IndicatorSessionUsersDbus * self, guint32 uid)
 
122
{
 
123
  indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid);
 
124
}
 
125
 
 
126
/***
 
127
****
 
128
***/
 
129
 
 
130
static void
 
131
set_is_live_session_flag (IndicatorSessionUsersDbus * self, gboolean b)
 
132
{
 
133
  priv_t * p = self->priv;
 
134
 
 
135
  if (p->is_live != b)
 
136
    {
 
137
      p->is_live = b;
 
138
 
 
139
      indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS (self));
 
140
    }
 
141
}
 
142
 
 
143
static void
 
144
set_active_uid (IndicatorSessionUsersDbus * self, guint uid)
 
145
{
 
146
  priv_t * p = self->priv;
 
147
 
 
148
  if (p->active_uid != uid)
 
149
    {
 
150
      const guint old_uid = p->active_uid;
 
151
 
 
152
      p->active_uid = uid;
 
153
 
 
154
      emit_user_changed (self, old_uid);
 
155
      emit_user_changed (self, uid);
 
156
    }
 
157
}
 
158
 
 
159
static void
 
160
set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins)
 
161
{
 
162
  GHashTable * old_logins = self->priv->logins;
 
163
  gpointer uid;
 
164
  GHashTableIter iter;
 
165
 
 
166
  self->priv->logins = g_hash_table_ref (logins);
 
167
 
 
168
  /* fire 'user changed' event for users who logged out */
 
169
  g_hash_table_iter_init (&iter, old_logins);
 
170
  while ((g_hash_table_iter_next (&iter, &uid, NULL)))
 
171
    if (!g_hash_table_contains (logins, uid))
 
172
      emit_user_changed (self, GPOINTER_TO_UINT(uid));
 
173
 
 
174
  /* fire 'user changed' event for users who logged in */
 
175
  g_hash_table_iter_init (&iter, logins);
 
176
  while ((g_hash_table_iter_next (&iter, &uid, NULL)))
 
177
    if (!g_hash_table_contains (old_logins, uid))
 
178
      emit_user_changed (self, GPOINTER_TO_UINT(uid));
 
179
 
 
180
  g_hash_table_destroy (old_logins);
 
181
}
 
182
 
 
183
/***
 
184
****  User Account Tracking
 
185
***/
 
186
 
 
187
static void create_user_proxy_for_path (IndicatorSessionUsersDbus *, const char *);
 
188
 
 
189
/* called when a user proxy gets the 'Changed' signal */
 
190
static void
 
191
on_user_changed (AccountsUser * user, gpointer gself)
 
192
{
 
193
  /* Accounts.User doesn't update properties in the standard way,
 
194
   * so create a new proxy to pull in the new properties.
 
195
   * The older proxy is freed when it's replaced in our accounts hash */
 
196
  const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user));
 
197
  create_user_proxy_for_path (gself, path);
 
198
}
 
199
 
 
200
static void
 
201
track_user (IndicatorSessionUsersDbus * self,
 
202
            AccountsUser              * user)
 
203
{
 
204
  const guint32 uid = accounts_user_get_uid (user);
 
205
  priv_t * p = self->priv;
 
206
  gulong id;
 
207
  const gboolean already_had_user = is_tracked_uid (self, uid);
 
208
 
 
209
  id  = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self);
 
210
  g_hash_table_insert (p->uid_to_account,
 
211
                       GUINT_TO_POINTER (uid),
 
212
                       user_record_new (user, id));
 
213
 
 
214
  if (already_had_user)
 
215
    emit_user_changed (self, uid);
 
216
  else
 
217
    emit_user_added (self, uid);
 
218
}
 
219
 
 
220
static void
 
221
untrack_user (IndicatorSessionUsersDbus * self,
 
222
              const gchar               * path)
 
223
{
 
224
  guint uid;
 
225
  gpointer key;
 
226
  gpointer val;
 
227
  GHashTableIter iter;
 
228
  priv_t * p = self->priv;
 
229
 
 
230
  /* find the uid matching this object path */
 
231
  uid = 0;
 
232
  g_hash_table_iter_init (&iter, p->uid_to_account);
 
233
  while (!uid && g_hash_table_iter_next (&iter, &key, &val))
 
234
    {
 
235
      struct UserRecord * rec = val;
 
236
      GDBusProxy * proxy = G_DBUS_PROXY (rec->user);
 
237
      if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (proxy)))
 
238
        uid = GPOINTER_TO_UINT (key);
 
239
    }
 
240
 
 
241
  if (uid)
 
242
    {
 
243
      g_hash_table_remove (p->uid_to_account, GUINT_TO_POINTER(uid)); 
 
244
 
 
245
      emit_user_removed (self, uid);
 
246
    }
 
247
}
 
248
 
 
249
/* We got a new org.freedesktop.Accounts.User proxy.
 
250
   If it's one we want to remember, pass it to track_user() */
 
251
static void
 
252
on_user_proxy_ready (GObject       * o G_GNUC_UNUSED,
 
253
                     GAsyncResult  * res,
 
254
                     gpointer        self)
 
255
{
 
256
  GError * err;
 
257
  AccountsUser * user;
 
258
 
 
259
  err = NULL;
 
260
  user = accounts_user_proxy_new_for_bus_finish (res, &err);
 
261
  if (err != NULL)
 
262
    {
 
263
      if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 
264
        g_warning ("%s: %s", G_STRFUNC, err->message);
 
265
 
 
266
      g_error_free (err);
 
267
    }
 
268
  else
 
269
    {
 
270
      if (!accounts_user_get_system_account (user))
 
271
        track_user (self, user);
 
272
 
 
273
      g_object_unref (user);
 
274
    }
 
275
}
 
276
 
 
277
static void
 
278
create_user_proxy_for_path (IndicatorSessionUsersDbus * self,
 
279
                            const char                * path)
 
280
{
 
281
  accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
 
282
                                   G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
 
283
                                   "org.freedesktop.Accounts",
 
284
                                   path,
 
285
                                   self->priv->cancellable,
 
286
                                   on_user_proxy_ready, self);
 
287
}
 
288
 
 
289
/* create proxy objects for everything in Account's user-list */
 
290
static void
 
291
on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself)
 
292
{
 
293
  GError * err;
 
294
  gchar ** paths;
 
295
 
 
296
  err = NULL;
 
297
  paths = NULL;
 
298
  accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err);
 
299
  if (err != NULL)
 
300
    {
 
301
      if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 
302
        g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message);
 
303
 
 
304
      g_error_free (err);
 
305
    }
 
306
  else
 
307
    {
 
308
      int i;
 
309
 
 
310
      for (i=0; paths && paths[i]; ++i)
 
311
        create_user_proxy_for_path (gself, paths[i]);
 
312
 
 
313
      g_strfreev (paths);
 
314
    }
 
315
}
 
316
 
 
317
static void
 
318
set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a)
 
319
{
 
320
  priv_t * p = self->priv;
 
321
 
 
322
  if (p->accounts != NULL)
 
323
    {
 
324
      g_signal_handlers_disconnect_by_data (p->accounts, self);
 
325
      g_clear_object (&p->accounts);
 
326
    }
 
327
 
 
328
  if (a != NULL)
 
329
    {
 
330
      p->accounts = g_object_ref (a);
 
331
 
 
332
      accounts_call_list_cached_users (a,
 
333
                                       self->priv->cancellable,
 
334
                                       on_user_list_ready,
 
335
                                       self);
 
336
 
 
337
      g_signal_connect_swapped (a, "user-added",
 
338
                                G_CALLBACK(create_user_proxy_for_path), self);
 
339
 
 
340
      g_signal_connect_swapped (a, "user-deleted",
 
341
                                G_CALLBACK(untrack_user), self);
 
342
    }
 
343
}
 
344
 
 
345
/***
 
346
****
 
347
***/
 
348
 
 
349
/* Based on the login1 manager's list of current sessions,
 
350
   update our 'logins', 'is_live', and 'active_uid' fields */
 
351
static void
 
352
on_login1_manager_session_list_ready (GObject      * o,
 
353
                                      GAsyncResult * res,
 
354
                                      gpointer       gself)
 
355
{
 
356
  GVariant * sessions;
 
357
  GError * err;
 
358
 
 
359
  sessions = NULL;
 
360
  err = NULL;
 
361
  login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o),
 
362
                                            &sessions,
 
363
                                            res,
 
364
                                            &err);
 
365
 
 
366
  if (err != NULL)
 
367
    {
 
368
      if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 
369
        g_warning ("%s: %s", G_STRFUNC, err->message);
 
370
 
 
371
      g_error_free (err);
 
372
    }
 
373
  else
 
374
    {
 
375
      const gchar * const current_seat_id = g_getenv ("XDG_SEAT");
 
376
      const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID");
 
377
      IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself);
 
378
      const gchar * session_id = NULL;
 
379
      guint32 uid = 0;
 
380
      const gchar * user_name = NULL;
 
381
      const gchar * seat_id = NULL;
 
382
      const gchar * path = NULL;
 
383
      gboolean is_live_session = FALSE;
 
384
      GHashTable * logins = g_hash_table_new (g_direct_hash, g_direct_equal);
 
385
      GVariantIter iter;
 
386
 
 
387
      g_variant_iter_init (&iter, sessions);
 
388
      while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id,
 
389
                                                        &uid,
 
390
                                                        &user_name,
 
391
                                                        &seat_id,
 
392
                                                        &path))
 
393
        {
 
394
          /* only track sessions on our seat */
 
395
          if (g_strcmp0 (seat_id, current_seat_id))
 
396
            continue;
 
397
 
 
398
          if (!g_strcmp0 (session_id, current_session_id))
 
399
            {
 
400
              set_active_uid (self, uid);
 
401
 
 
402
              if ((uid==999) && !g_strcmp0 (user_name, "ubuntu"))
 
403
                is_live_session = TRUE;
 
404
            }
 
405
 
 
406
          g_hash_table_add (logins, GINT_TO_POINTER(uid));
 
407
        }
 
408
 
 
409
      set_is_live_session_flag (self, is_live_session);
 
410
      set_logins (self, logins);
 
411
 
 
412
      g_hash_table_unref (logins);
 
413
      g_variant_unref (sessions);
 
414
    }
 
415
}
 
416
 
 
417
static void
 
418
update_session_list (IndicatorSessionUsersDbus * self)
 
419
{
 
420
  priv_t * p = self->priv;
 
421
 
 
422
  if (p->login1_manager != NULL)
 
423
    {
 
424
      login1_manager_call_list_sessions (p->login1_manager,
 
425
                                         p->cancellable,
 
426
                                         on_login1_manager_session_list_ready,
 
427
                                         self);
 
428
    }
 
429
}
 
430
 
 
431
static gboolean
 
432
on_update_session_list_timer (gpointer gself)
 
433
{
 
434
  IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself);
 
435
 
 
436
  update_session_list (self);
 
437
 
 
438
  self->priv->update_list_tag = 0;
 
439
  return G_SOURCE_REMOVE;
 
440
}
 
441
 
 
442
/* A dead session can still show up in list-sessions for a few seconds.
 
443
   So just to be safe, queue up a rebuild for a few seconds from now */
 
444
static void
 
445
update_session_list_twice (IndicatorSessionUsersDbus * self)
 
446
{
 
447
  priv_t * p = self->priv;
 
448
 
 
449
  update_session_list (self);
 
450
 
 
451
  if (p->update_list_tag == 0)
 
452
    p->update_list_tag = g_timeout_add_seconds (5,
 
453
                                                on_update_session_list_timer,
 
454
                                                self);
 
455
}
 
456
 
 
457
static void
 
458
set_login1_manager (IndicatorSessionUsersDbus * self,
 
459
                    Login1Manager             * login1_manager)
 
460
{
 
461
  priv_t * p = self->priv;
 
462
 
 
463
  if (p->login1_manager != NULL)
 
464
    {
 
465
      g_signal_handlers_disconnect_by_data (p->login1_manager, self);
 
466
 
 
467
      g_clear_object (&p->login1_manager);
 
468
    }
 
469
 
 
470
  if (login1_manager != NULL)
 
471
    {
 
472
      p->login1_manager = g_object_ref (login1_manager);
 
473
 
 
474
      g_signal_connect_swapped (login1_manager, "session-new",
 
475
                                G_CALLBACK(update_session_list), self);
 
476
      g_signal_connect_swapped (login1_manager, "session-removed",
 
477
                                G_CALLBACK(update_session_list_twice), self);
 
478
      g_signal_connect_swapped (login1_manager, "user-new",
 
479
                                G_CALLBACK(update_session_list), self);
 
480
      g_signal_connect_swapped (login1_manager, "user-removed",
 
481
                                G_CALLBACK(update_session_list_twice), self);
 
482
      update_session_list (self);
 
483
    }
 
484
}
 
485
 
 
486
static void
 
487
set_login1_seat (IndicatorSessionUsersDbus * self,
 
488
                 Login1Seat                * login1_seat)
 
489
{
 
490
  priv_t * p = self->priv;
 
491
 
 
492
  if (p->login1_seat != NULL)
 
493
    {
 
494
      g_signal_handlers_disconnect_by_data (p->login1_seat, self);
 
495
 
 
496
      g_clear_object (&p->login1_seat);
 
497
    }
 
498
 
 
499
  if (login1_seat != NULL)
 
500
    {
 
501
      p->login1_seat = g_object_ref (login1_seat);
 
502
 
 
503
      g_signal_connect_swapped (login1_seat, "notify::active-session",
 
504
                                G_CALLBACK(update_session_list), self);
 
505
      update_session_list (self);
 
506
    }
 
507
}
 
508
 
 
509
static void
 
510
set_display_manager_seat (IndicatorSessionUsersDbus * self,
 
511
                          DisplayManagerSeat        * dm_seat)
 
512
{
 
513
  priv_t * p = self->priv;
 
514
 
 
515
  g_clear_object (&p->dm_seat);
 
516
 
 
517
  if (dm_seat != NULL)
 
518
    p->dm_seat = g_object_ref (dm_seat);
 
519
}
 
520
 
 
521
/***
 
522
****  IndicatorSessionUsers virtual functions
 
523
***/
 
524
 
 
525
/* switch to (or create) a session for the specified user */
 
526
static void
 
527
my_activate_user (IndicatorSessionUsers * users, guint uid)
 
528
{
 
529
  IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users);
 
530
  priv_t * p = self->priv;
 
531
  AccountsUser * au;
 
532
  const char * username;
 
533
 
 
534
  au = get_user_for_uid (self, uid);
 
535
  username = au ? accounts_user_get_user_name (au) : NULL;
 
536
 
 
537
  if (!username)
 
538
    {
 
539
      g_warning ("%s %s can't find user '%u'", G_STRLOC, G_STRFUNC, uid);
 
540
    }
 
541
  else
 
542
    {
 
543
      g_return_if_fail (p->dm_seat != NULL);
 
544
 
 
545
      display_manager_seat_call_switch_to_user (p->dm_seat,
 
546
                                                username,
 
547
                                                "",
 
548
                                                p->cancellable,
 
549
                                                NULL,
 
550
                                                NULL);
 
551
    }
 
552
}
 
553
 
 
554
/* returns true if this is a live session */
 
555
static gboolean
 
556
my_is_live_session (IndicatorSessionUsers * users)
 
557
{
 
558
  g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), FALSE);
 
559
 
 
560
  return INDICATOR_SESSION_USERS_DBUS(users)->priv->is_live;
 
561
}
 
562
 
 
563
/* get a list of our user ids */
 
564
static GList *
 
565
my_get_uids (IndicatorSessionUsers * users)
 
566
{
 
567
  IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users);
 
568
  return g_hash_table_get_keys (self->priv->uid_to_account);
 
569
}
 
570
 
 
571
/* build a new struct populated with info on the specified user */
 
572
static IndicatorSessionUser *
 
573
my_get_user (IndicatorSessionUsers * users, guint uid)
 
574
{
 
575
  IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users);
 
576
  priv_t * p = self->priv;
 
577
  IndicatorSessionUser * ret;
 
578
  AccountsUser * au;
 
579
 
 
580
  ret = NULL;
 
581
  au = get_user_for_uid (self, uid);
 
582
  if (au && !accounts_user_get_system_account(au))
 
583
    {
 
584
      g_assert (uid == accounts_user_get_uid (au));
 
585
 
 
586
      ret = g_new0 (IndicatorSessionUser, 1);
 
587
      ret->uid = uid;
 
588
      ret->user_name = g_strdup (accounts_user_get_user_name (au));
 
589
      ret->real_name = g_strdup (accounts_user_get_real_name (au));
 
590
      ret->icon_file = g_strdup (accounts_user_get_icon_file (au));
 
591
      ret->login_frequency = accounts_user_get_login_frequency (au);
 
592
      ret->is_logged_in = g_hash_table_contains (p->logins, GINT_TO_POINTER(uid));
 
593
      ret->is_current_user = uid == p->active_uid;
 
594
    }
 
595
 
 
596
  return ret;
 
597
}
 
598
 
 
599
/***
 
600
****  GObject virtual functions
 
601
***/
 
602
 
 
603
static void
 
604
my_dispose (GObject * o)
 
605
{
 
606
  IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o);
 
607
  priv_t * p = self->priv;
 
608
 
 
609
  if (p->update_list_tag != 0)
 
610
    {
 
611
      g_source_remove (p->update_list_tag);
 
612
      p->update_list_tag = 0;
 
613
    }
 
614
 
 
615
  if (p->cancellable)
 
616
    {
 
617
      g_cancellable_cancel (p->cancellable);
 
618
      g_clear_object (&p->cancellable);
 
619
    }
 
620
 
 
621
  set_account_manager (self, NULL);
 
622
  set_display_manager_seat (self, NULL);
 
623
  set_login1_seat (self, NULL);
 
624
  set_login1_manager (self, NULL);
 
625
 
 
626
  g_hash_table_remove_all (p->uid_to_account);
 
627
 
 
628
  G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o);
 
629
}
 
630
 
 
631
static void
 
632
my_finalize (GObject * o)
 
633
{
 
634
  IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o);
 
635
  priv_t * p = self->priv;
 
636
 
 
637
  g_hash_table_destroy (p->logins);
 
638
  g_hash_table_destroy (p->uid_to_account);
 
639
 
 
640
  G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o);
 
641
}
 
642
 
 
643
static void
 
644
indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass)
 
645
{
 
646
  GObjectClass * object_class;
 
647
  IndicatorSessionUsersClass * users_class;
 
648
 
 
649
  object_class = G_OBJECT_CLASS (klass);
 
650
  object_class->dispose = my_dispose;
 
651
  object_class->finalize = my_finalize;
 
652
 
 
653
  users_class = INDICATOR_SESSION_USERS_CLASS (klass);
 
654
  users_class->is_live_session = my_is_live_session;
 
655
  users_class->get_uids = my_get_uids;
 
656
  users_class->get_user = my_get_user;
 
657
  users_class->activate_user = my_activate_user;
 
658
 
 
659
  g_type_class_add_private (klass, sizeof (IndicatorSessionUsersDbusPriv));
 
660
}
 
661
 
 
662
static void
 
663
indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self)
 
664
{
 
665
  priv_t * p;
 
666
 
 
667
  p = G_TYPE_INSTANCE_GET_PRIVATE (self,
 
668
                                   INDICATOR_TYPE_SESSION_USERS_DBUS,
 
669
                                   IndicatorSessionUsersDbusPriv);
 
670
  self->priv = p;
 
671
  p->cancellable = g_cancellable_new ();
 
672
 
 
673
  p->uid_to_account = g_hash_table_new_full (g_direct_hash,
 
674
                                             g_direct_equal,
 
675
                                             NULL,
 
676
                                             (GDestroyNotify)user_record_free);
 
677
 
 
678
  p->logins = g_hash_table_new (g_direct_hash, g_direct_equal);
 
679
}
 
680
 
 
681
/***
 
682
****  Public
 
683
***/
 
684
 
 
685
IndicatorSessionUsers *
 
686
indicator_session_users_dbus_new (void)
 
687
{
 
688
  gpointer o = g_object_new (INDICATOR_TYPE_SESSION_USERS_DBUS, NULL);
 
689
 
 
690
  return INDICATOR_SESSION_USERS (o);
 
691
}
 
692
 
 
693
void
 
694
indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus * self,
 
695
                                          Login1Manager             * login1_manager,
 
696
                                          Login1Seat                * login1_seat,
 
697
                                          DisplayManagerSeat        * dm_seat,
 
698
                                          Accounts                  * accounts)
 
699
{
 
700
  g_return_if_fail (INDICATOR_IS_SESSION_USERS_DBUS (self));
 
701
 
 
702
  set_login1_manager (self, login1_manager);
 
703
  set_login1_seat (self, login1_seat);
 
704
  set_display_manager_seat (self, dm_seat);
 
705
  set_account_manager (self, accounts);
 
706
}