1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2010 Red Hat, Inc.
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* Author: Tomas Bzatek <tbzatek@redhat.com>
28
#include <glib/gi18n.h>
31
#include "gnome-settings-profile.h"
32
#include "gnome-settings-session.h"
33
#include "gsd-automount-manager.h"
34
#include "gsd-autorun.h"
36
#define GSD_AUTOMOUNT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_AUTOMOUNT_MANAGER, GsdAutomountManagerPrivate))
38
struct GsdAutomountManagerPrivate
42
GVolumeMonitor *volume_monitor;
43
unsigned int automount_idle_id;
46
gboolean session_is_active;
47
gboolean screensaver_active;
54
static void gsd_automount_manager_class_init (GsdAutomountManagerClass *klass);
55
static void gsd_automount_manager_init (GsdAutomountManager *gsd_automount_manager);
57
G_DEFINE_TYPE (GsdAutomountManager, gsd_automount_manager, G_TYPE_OBJECT)
60
show_error_dialog (const char *primary_text,
61
const char *secondary_text)
65
dialog = gtk_message_dialog_new (NULL,
73
"secondary-text", secondary_text,
76
gtk_widget_show (GTK_WIDGET (dialog));
78
g_signal_connect (dialog, "response",
79
G_CALLBACK (gtk_widget_destroy), NULL);
81
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
83
return GTK_DIALOG (dialog);
87
startup_volume_mount_cb (GObject *source_object,
91
g_volume_mount_finish (G_VOLUME (source_object), res, NULL);
95
automount_all_volumes (GsdAutomountManager *manager)
101
if (g_settings_get_boolean (manager->priv->settings, "automount")) {
102
/* automount all mountable volumes at start-up */
103
volumes = g_volume_monitor_get_volumes (manager->priv->volume_monitor);
104
for (l = volumes; l != NULL; l = l->next) {
107
if (!g_volume_should_automount (volume) ||
108
!g_volume_can_mount (volume)) {
112
mount = g_volume_get_mount (volume);
114
g_object_unref (mount);
118
/* pass NULL as GMountOperation to avoid user interaction */
119
g_volume_mount (volume, 0, NULL, NULL, startup_volume_mount_cb, NULL);
121
g_list_free_full (volumes, g_object_unref);
126
automount_all_volumes_idle_cb (gpointer data)
128
GsdAutomountManager *manager = GSD_AUTOMOUNT_MANAGER (data);
130
automount_all_volumes (manager);
132
manager->priv->automount_idle_id = 0;
137
volume_mount_cb (GObject *source_object,
141
GMountOperation *mount_op = user_data;
147
gsd_allow_autorun_for_volume_finish (G_VOLUME (source_object));
148
if (!g_volume_mount_finish (G_VOLUME (source_object), res, &error)) {
149
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
150
name = g_volume_get_name (G_VOLUME (source_object));
151
primary = g_strdup_printf (_("Unable to mount %s"), name);
153
show_error_dialog (primary,
157
g_error_free (error);
160
g_object_unref (mount_op);
164
do_mount_volume (GVolume *volume)
166
GMountOperation *mount_op;
168
mount_op = gtk_mount_operation_new (NULL);
169
g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
171
gsd_allow_autorun_for_volume (volume);
172
g_volume_mount (volume, 0, mount_op, NULL, volume_mount_cb, mount_op);
176
check_volume_queue (GsdAutomountManager *manager)
181
if (manager->priv->screensaver_active)
184
l = manager->priv->volume_queue;
189
do_mount_volume (volume);
190
manager->priv->volume_queue =
191
g_list_remove (manager->priv->volume_queue, volume);
193
g_object_unref (volume);
197
manager->priv->volume_queue = NULL;
201
check_screen_lock_and_mount (GsdAutomountManager *manager,
204
if (!manager->priv->session_is_active)
207
if (manager->priv->screensaver_active) {
208
/* queue the volume, to mount it after the screensaver state changed */
209
g_debug ("Queuing volume %p", volume);
210
manager->priv->volume_queue = g_list_prepend (manager->priv->volume_queue,
211
g_object_ref (volume));
213
/* mount it immediately */
214
do_mount_volume (volume);
219
volume_removed_callback (GVolumeMonitor *monitor,
221
GsdAutomountManager *manager)
223
g_debug ("Volume %p removed, removing from the queue", volume);
225
/* clear it from the queue, if present */
226
manager->priv->volume_queue =
227
g_list_remove (manager->priv->volume_queue, volume);
231
volume_added_callback (GVolumeMonitor *monitor,
233
GsdAutomountManager *manager)
235
if (g_settings_get_boolean (manager->priv->settings, "automount") &&
236
g_volume_should_automount (volume) &&
237
g_volume_can_mount (volume)) {
238
check_screen_lock_and_mount (manager, volume);
240
/* Allow gsd_autorun() to run. When the mount is later
241
* added programmatically (i.e. for a blank CD),
242
* gsd_autorun() will be called by mount_added_callback(). */
243
gsd_allow_autorun_for_volume (volume);
244
gsd_allow_autorun_for_volume_finish (volume);
249
autorun_show_window (GMount *mount, gpointer user_data)
257
location = g_mount_get_root (mount);
258
uri = g_file_get_uri (location);
261
/* use default folder handler */
262
if (! gtk_show_uri (NULL, uri, GDK_CURRENT_TIME, &error)) {
263
name = g_mount_get_name (mount);
264
primary = g_strdup_printf (_("Unable to open a folder for %s"), name);
266
show_error_dialog (primary,
269
g_error_free (error);
273
g_object_unref (location);
277
mount_added_callback (GVolumeMonitor *monitor,
279
GsdAutomountManager *manager)
281
/* don't autorun if the session is not active */
282
if (!manager->priv->session_is_active) {
286
gsd_autorun (mount, manager->priv->settings, autorun_show_window, manager);
291
session_state_changed (GDBusProxy *session,
294
GsdAutomountManager *manager)
296
GsdAutomountManagerPrivate *p = manager->priv;
300
v = g_variant_lookup_value (changed, "SessionIsActive", G_VARIANT_TYPE_BOOLEAN);
305
active = g_variant_get_boolean (v);
306
g_debug ("Received session is active change: now %s", active ? "active" : "inactive");
307
/* when doing the fast-user-switch into a new account,
308
* ensure the new account is undimmed and with the backlight on */
310
p->session_is_active = TRUE;
312
p->session_is_active = FALSE;
318
if (!p->session_is_active) {
319
if (p->volume_queue != NULL) {
320
g_list_free_full (p->volume_queue, g_object_unref);
321
p->volume_queue = NULL;
327
is_session_active (GsdAutomountManager *manager)
330
gboolean is_session_active = FALSE;
332
variant = g_dbus_proxy_get_cached_property (manager->priv->session,
335
is_session_active = g_variant_get_boolean (variant);
336
g_variant_unref (variant);
339
return is_session_active;
344
do_initialize_session (GsdAutomountManager *manager)
346
manager->priv->session = gnome_settings_session_get_session_proxy ();
347
g_signal_connect (manager->priv->session, "g-properties-changed",
348
G_CALLBACK (session_state_changed),
350
manager->priv->session_is_active = is_session_active (manager);
353
#define SCREENSAVER_NAME "org.gnome.ScreenSaver"
354
#define SCREENSAVER_PATH "/org/gnome/ScreenSaver"
355
#define SCREENSAVER_INTERFACE "org.gnome.ScreenSaver"
358
screensaver_signal_callback (GDBusProxy *proxy,
359
const gchar *sender_name,
360
const gchar *signal_name,
361
GVariant *parameters,
364
GsdAutomountManager *manager = user_data;
366
if (g_strcmp0 (signal_name, "ActiveChanged") == 0) {
367
g_variant_get (parameters, "(b)", &manager->priv->screensaver_active);
368
g_debug ("Screensaver active changed to %d", manager->priv->screensaver_active);
370
check_volume_queue (manager);
375
screensaver_get_active_ready_cb (GObject *source,
379
GsdAutomountManager *manager = user_data;
380
GDBusProxy *proxy = manager->priv->ss_proxy;
382
GError *error = NULL;
384
result = g_dbus_proxy_call_finish (proxy,
389
g_warning ("Can't call GetActive() on the ScreenSaver object: %s",
391
g_error_free (error);
396
g_variant_get (result, "(b)", &manager->priv->screensaver_active);
397
g_variant_unref (result);
399
g_debug ("Screensaver GetActive() returned %d", manager->priv->screensaver_active);
403
screensaver_proxy_ready_cb (GObject *source,
407
GsdAutomountManager *manager = user_data;
408
GError *error = NULL;
409
GDBusProxy *ss_proxy;
411
ss_proxy = g_dbus_proxy_new_finish (res, &error);
414
g_warning ("Can't get proxy for the ScreenSaver object: %s",
416
g_error_free (error);
421
g_debug ("ScreenSaver proxy ready");
423
manager->priv->ss_proxy = ss_proxy;
425
g_signal_connect (ss_proxy, "g-signal",
426
G_CALLBACK (screensaver_signal_callback), manager);
428
g_dbus_proxy_call (ss_proxy,
431
G_DBUS_CALL_FLAGS_NO_AUTO_START,
434
screensaver_get_active_ready_cb,
439
screensaver_appeared_callback (GDBusConnection *connection,
441
const gchar *name_owner,
444
GsdAutomountManager *manager = user_data;
446
g_debug ("ScreenSaver name appeared");
448
manager->priv->screensaver_active = FALSE;
450
g_dbus_proxy_new (connection,
451
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
455
SCREENSAVER_INTERFACE,
457
screensaver_proxy_ready_cb,
462
screensaver_vanished_callback (GDBusConnection *connection,
466
GsdAutomountManager *manager = user_data;
468
g_debug ("ScreenSaver name vanished");
470
manager->priv->screensaver_active = FALSE;
471
g_clear_object (&manager->priv->ss_proxy);
473
/* in this case force a clear of the volume queue, without
476
if (manager->priv->volume_queue != NULL) {
477
g_list_free_full (manager->priv->volume_queue, g_object_unref);
478
manager->priv->volume_queue = NULL;
483
do_initialize_screensaver (GsdAutomountManager *manager)
485
GsdAutomountManagerPrivate *p = manager->priv;
488
g_bus_watch_name (G_BUS_TYPE_SESSION,
490
G_BUS_NAME_WATCHER_FLAGS_NONE,
491
screensaver_appeared_callback,
492
screensaver_vanished_callback,
498
setup_automounter (GsdAutomountManager *manager)
500
do_initialize_session (manager);
501
do_initialize_screensaver (manager);
503
manager->priv->volume_monitor = g_volume_monitor_get ();
504
g_signal_connect_object (manager->priv->volume_monitor, "mount-added",
505
G_CALLBACK (mount_added_callback), manager, 0);
506
g_signal_connect_object (manager->priv->volume_monitor, "volume-added",
507
G_CALLBACK (volume_added_callback), manager, 0);
508
g_signal_connect_object (manager->priv->volume_monitor, "volume-removed",
509
G_CALLBACK (volume_removed_callback), manager, 0);
511
manager->priv->automount_idle_id =
512
g_idle_add_full (G_PRIORITY_LOW,
513
automount_all_volumes_idle_cb,
518
gsd_automount_manager_start (GsdAutomountManager *manager,
521
g_debug ("Starting automounting manager");
522
gnome_settings_profile_start (NULL);
524
manager->priv->settings = g_settings_new ("org.gnome.desktop.media-handling");
525
setup_automounter (manager);
527
gnome_settings_profile_end (NULL);
533
gsd_automount_manager_stop (GsdAutomountManager *manager)
535
GsdAutomountManagerPrivate *p = manager->priv;
537
g_debug ("Stopping automounting manager");
539
g_clear_object (&p->session);
540
g_clear_object (&p->volume_monitor);
541
g_clear_object (&p->settings);
542
g_clear_object (&p->ss_proxy);
544
g_bus_unwatch_name (p->ss_watch_id);
546
if (p->volume_queue != NULL) {
547
g_list_free_full (p->volume_queue, g_object_unref);
548
p->volume_queue = NULL;
551
if (p->automount_idle_id != 0) {
552
g_source_remove (p->automount_idle_id);
553
p->automount_idle_id = 0;
558
gsd_automount_manager_class_init (GsdAutomountManagerClass *klass)
560
g_type_class_add_private (klass, sizeof (GsdAutomountManagerPrivate));
564
gsd_automount_manager_init (GsdAutomountManager *manager)
566
manager->priv = GSD_AUTOMOUNT_MANAGER_GET_PRIVATE (manager);
569
GsdAutomountManager *
570
gsd_automount_manager_new (void)
572
return GSD_AUTOMOUNT_MANAGER (g_object_new (GSD_TYPE_AUTOMOUNT_MANAGER, NULL));