diff --git a/js/Makefile.am b/js/Makefile.am index 5d2d06f1a..2964879b8 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 000000000..ab50582ed --- /dev/null +++ b/js/ui/automountManager.js @@ -0,0 +1,176 @@ +/* -*- 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 Params = imports.misc.params; + +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); + + 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('active-changed', + 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) { + if (!isActive) { + this._volumeQueue.forEach(Lang.bind(this, function(volume) { + this._checkAndMountVolume(volume); + })); + } + + // clear the queue anyway + this._volumeQueue = []; + }, + + _startupMountAll: function() { + let volumes = this._volumeMonitor.get_volumes(); + volumes.forEach(Lang.bind(this, function(volume) { + this._checkAndMountVolume(volume, { checkSession: false, + useMountOp: false }); + })); + + return false; + }, + + _onVolumeAdded: function(monitor, volume) { + this._checkAndMountVolume(volume); + }, + + _checkAndMountVolume: function(volume, params) { + params = Params.parse(params, { checkSession: true, + useMountOp: true }); + + if (!this._settings.get_boolean(SETTING_ENABLE_AUTOMOUNT)) + return; + + if (!volume.should_automount() || + !volume.can_mount()) + return; + + if (params.checkSession) { + // if we're not in the current ConsoleKit session, + // don't attempt automount + if (!this.ckListener.sessionActive) + return; + + if (this._ssProxy.getActive()) { + 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 4d52a9b5d..fd301e88d 100644 --- a/js/ui/autorunManager.js +++ b/js/ui/autorunManager.js @@ -118,6 +118,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 0fed731ee..6cb58fd41 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();