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
This commit is contained in:
Cosimo Cecchi 2011-06-20 15:16:40 -04:00
parent 534b371d42
commit acc053302d
4 changed files with 185 additions and 0 deletions

View File

@ -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 \

176
js/ui/automountManager.js Normal file
View File

@ -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);
});
}
}

View File

@ -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);

View File

@ -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();