[gnome-shell/hotplug: 3/13] automount: add an AutomountManager class



commit 2b5f9c783e0f531edea0d3048aade87a967495bb
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Mon Jun 20 15:16:40 2011 -0400

    automount: add an AutomountManager class
    
    The AutomountManager class is the low-level counterpart of the
    previously introduced AutorunManager, and takes care of extracting the
    list of valid mounts from a GVolume or a GDrive and mounting them,
    provided a number of conditions and requirements are met.
    
    AutomountManager also keeps track of the current session availability
    (using the ConsoleKit and gnome-screensaver DBus interfaces) and
    inhibits mounting if the current session is locked, or another session
    is in use instead.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=653520

 js/Makefile.am            |    1 +
 js/ui/automountManager.js |  174 +++++++++++++++++++++++++++++++++++++++++++++
 js/ui/autorunManager.js   |    5 ++
 js/ui/main.js             |    3 +
 4 files changed, 183 insertions(+), 0 deletions(-)
---
diff --git a/js/Makefile.am b/js/Makefile.am
index 5d2d06f..2964879 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -16,6 +16,7 @@ nobase_dist_js_DATA = 	\
 	ui/altTab.js		\
 	ui/appDisplay.js	\
 	ui/appFavorites.js	\
+	ui/automountManager.js  \
 	ui/autorunManager.js    \
 	ui/boxpointer.js	\
 	ui/calendar.js		\
diff --git a/js/ui/automountManager.js b/js/ui/automountManager.js
new file mode 100644
index 0000000..c6678d1
--- /dev/null
+++ b/js/ui/automountManager.js
@@ -0,0 +1,174 @@
+/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+const Lang = imports.lang;
+const DBus = imports.dbus;
+const Mainloop = imports.mainloop;
+const Gio = imports.gi.Gio;
+
+const Main = imports.ui.main;
+const ScreenSaver = imports.misc.screenSaver;
+
+// GSettings keys
+const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
+const SETTING_ENABLE_AUTOMOUNT = 'automount';
+
+const ConsoleKitSessionIface = {
+    name: 'org.freedesktop.ConsoleKit.Session',
+    methods: [{ name: 'IsActive',
+                inSignature: '',
+                outSignature: 'b' }],
+    signals: [{ name: 'ActiveChanged',
+                inSignature: 'b' }]
+};
+
+const ConsoleKitSessionProxy = DBus.makeProxyClass(ConsoleKitSessionIface);
+
+const ConsoleKitManagerIface = {
+    name: 'org.freedesktop.ConsoleKit.Manager',
+    methods: [{ name: 'GetCurrentSession',
+                inSignature: '',
+                outSignature: 'o' }]
+};
+
+function ConsoleKitManager() {
+    this._init();
+};
+
+ConsoleKitManager.prototype = {
+    _init: function() {
+        this.sessionActive = true;
+
+        DBus.system.proxifyObject(this,
+                                  'org.freedesktop.ConsoleKit',
+                                  '/org/freedesktop/ConsoleKit/Manager');
+
+        DBus.system.watch_name('org.freedesktop.ConsoleKit',
+                               false, // do not launch a name-owner if none exists
+                               Lang.bind(this, this._onManagerAppeared),
+                               Lang.bind(this, this._onManagerVanished));
+    },
+
+    _onManagerAppeared: function(owner) {
+        this.GetCurrentSessionRemote(Lang.bind(this, this._onCurrentSession));
+    },
+
+    _onManagerVanished: function(oldOwner) {
+        this.sessionActive = true;
+    },
+
+    _onCurrentSession: function(session) {
+        this._ckSession = new ConsoleKitSessionProxy(DBus.system, 'org.freedesktop.ConsoleKit', session);
+        log(this._ckSession);
+
+        this._ckSession.connect
+            ('ActiveChanged', Lang.bind(this, function(object, isActive) {
+                this.sessionActive = isActive;            
+            }));
+        this._ckSession.IsActiveRemote(Lang.bind(this, function(isActive) {
+            this.sessionActive = isActive;            
+        }));
+    }
+};
+DBus.proxifyPrototype(ConsoleKitManager.prototype, ConsoleKitManagerIface);
+
+function AutomountManager() {
+    this._init();
+}
+
+AutomountManager.prototype = {
+    _init: function() {
+        this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
+        this._volumeQueue = [];
+
+        this.ckListener = new ConsoleKitManager();
+
+        this._ssProxy = new ScreenSaver.ScreenSaverProxy();
+        this._ssProxy.connect('ActiveChanged',
+                              Lang.bind(this,
+                                        this._screenSaverActiveChanged));
+
+        this._volumeMonitor = Gio.VolumeMonitor.get();
+
+        this._volumeMonitor.connect('volume-added',
+                                    Lang.bind(this,
+                                              this._onVolumeAdded));
+        this._volumeMonitor.connect('volume-removed',
+                                    Lang.bind(this,
+                                              this._onVolumeRemoved));
+
+        Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
+    },
+
+    _screenSaverActiveChanged: function(object, isActive) {
+        this._ssProxy.screenSaverActive = isActive;
+
+        if (!isActive) {
+            this._volumeQueue.forEach(Lang.bind(this, function(volume) {
+                this._checkAndMountVolume(volume, true, true);
+            }));
+        }
+
+        // clear the queue anyway
+        this._volumeQueue = [];
+    },
+
+    _startupMountAll: function() {
+        let volumes = this._volumeMonitor.get_volumes();
+        volumes.forEach(Lang.bind(this, function(volume) {
+            this._checkAndMountVolume(volume, false, false);
+        }));
+
+        return false;
+    },
+
+    _onVolumeAdded: function(monitor, volume) {
+        this._checkAndMountVolume(volume, true, true);
+    },
+
+    _checkAndMountVolume: function(volume, checkSession, useMountOp) {
+        if (!this._settings.get_boolean(SETTING_ENABLE_AUTOMOUNT))
+            return;
+
+        if (!volume.should_automount() ||
+            !volume.can_mount())
+            return;
+
+        if (checkSession) {
+            // if we're not in the current ConsoleKit session,
+            // don't attempt automount
+            if (!this.ckListener.sessionActive)
+                return;
+
+            if (this._ssProxy.screenSaverActive) {
+                if (this._volumeQueue.indexOf(volume) == -1)
+                    this._volumeQueue.push(volume);
+
+                return;
+            }
+        }
+
+        // TODO: mount op
+        this._mountVolume(volume, null);
+    },
+
+    _mountVolume: function(volume, operation) {
+        volume.mount(0, operation, null,
+                     Lang.bind(this, this._onVolumeMounted));
+    },
+
+    _onVolumeMounted: function(volume, res) {
+        try {
+            volume.mount_finish(res);
+        } catch (e) {
+            log('Unable to mount volume ' + volume.get_name() + ': ' +
+                e.toString());
+        }
+    },
+
+    _onVolumeRemoved: function(monitor, volume) {
+        this._volumeQueue = 
+            this._volumeQueue.filter(function(element) {
+                return (element != volume);
+            });
+    }
+}
diff --git a/js/ui/autorunManager.js b/js/ui/autorunManager.js
index 6a8a6f3..d0c54ff 100644
--- a/js/ui/autorunManager.js
+++ b/js/ui/autorunManager.js
@@ -114,6 +114,11 @@ AutorunManager.prototype = {
     },
 
     _onMountAdded: function(monitor, mount) {
+        // don't do anything if our session is not the currently
+        // active one
+        if (!Main.automountManager.ckListener.sessionActive)
+            return;
+
         let discoverer = new ContentTypeDiscoverer
             (Lang.bind (this, function (mount, contentTypes) {
                 this._transDispatcher.addMount(mount, contentTypes);
diff --git a/js/ui/main.js b/js/ui/main.js
index 0fed731..6cb58fd 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -12,6 +12,7 @@ const Meta = imports.gi.Meta;
 const Shell = imports.gi.Shell;
 const St = imports.gi.St;
 
+const AutomountManager = imports.ui.automountManager;
 const AutorunManager = imports.ui.autorunManager;
 const Chrome = imports.ui.chrome;
 const CtrlAltTab = imports.ui.ctrlAltTab;
@@ -40,6 +41,7 @@ const Util = imports.misc.util;
 const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
 DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
 
+let automountManager = null;
 let autorunManager = null;
 let chrome = null;
 let panel = null;
@@ -144,6 +146,7 @@ function start() {
     notificationDaemon = new NotificationDaemon.NotificationDaemon();
     windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
     telepathyClient = new TelepathyClient.Client();
+    automountManager = new AutomountManager.AutomountManager();
     autorunManager = new AutorunManager.AutorunManager();
 
     layoutManager.init();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]