Consolidate systemd and consolekit in a common abstract class

Various code around had different paths for ConsoleKit and
logind. Consolidate it by making an abstract class that all
callers can use, which hides the implementation details of the
two daemons.

https://bugzilla.gnome.org/show_bug.cgi?id=682096
This commit is contained in:
Giovanni Campagna 2012-08-18 14:05:52 +02:00
parent 98c461dcd8
commit 9a7914eee9
7 changed files with 223 additions and 193 deletions

View File

@ -23,15 +23,14 @@ nobase_dist_js_DATA = \
gdm/util.js \
extensionPrefs/main.js \
misc/config.js \
misc/consoleKit.js \
misc/extensionUtils.js \
misc/fileUtils.js \
misc/gnomeSession.js \
misc/history.js \
misc/jsParse.js \
misc/loginManager.js \
misc/modemManager.js \
misc/params.js \
misc/systemd.js \
misc/util.js \
perf/core.js \
ui/altTab.js \

View File

@ -21,8 +21,7 @@
const Lang = imports.lang;
const UPowerGlib = imports.gi.UPowerGlib;
const ConsoleKit = imports.misc.consoleKit;
const Systemd = imports.misc.systemd;
const LoginManager = imports.misc.loginManager;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
@ -35,10 +34,7 @@ const PowerMenuButton = new Lang.Class({
this.parent('system-shutdown', null);
this._upClient = new UPowerGlib.Client();
if (Systemd.haveSystemd())
this._systemdLoginManager = new Systemd.SystemdLoginManager();
else
this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
this._loginManager = LoginManager.getLoginManager();
this._createSubMenu();
@ -65,57 +61,19 @@ const PowerMenuButton = new Lang.Class({
},
_updateHaveShutdown: function() {
if (Systemd.haveSystemd()) {
this._systemdLoginManager.CanPowerOffRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result[0] != 'no';
else
this._haveShutdown = false;
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
} else {
this._consoleKitManager.CanStopRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveShutdown = result[0];
else
this._haveShutdown = false;
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
}
this._loginManager.canPowerOff(Lang.bind(this, function(result) {
this._haveShutdown = result;
this._powerOffItem.actor.visible = this._haveShutdown;
this._updateVisibility();
}));
},
_updateHaveRestart: function() {
if (Systemd.haveSystemd()) {
this._systemdLoginManager.CanRebootRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result[0] != 'no';
else
this._haveRestart = false;
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
} else {
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
function(result, error) {
if (!error)
this._haveRestart = result[0];
else
this._haveRestart = false;
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
}
this._loginManager.canReboot(Lang.bind(this, function(result) {
this._haveRestart = result;
this._restartItem.actor.visible = this._haveRestart;
this._updateVisibility();
}));
},
_updateHaveSuspend: function() {
@ -152,19 +110,13 @@ const PowerMenuButton = new Lang.Class({
if (!this._haveRestart)
return;
if (Systemd.haveSystemd())
this._systemdLoginManager.RebootRemote(true);
else
this._consoleKitManager.RestartRemote();
this._loginManager.reboot();
},
_onActivatePowerOff: function() {
if (!this._haveShutdown)
return;
if (Systemd.haveSystemd())
this._systemdLoginManager.PowerOffRemote(true);
else
this._consoleKitManager.StopRemote();
this._loginManager.powerOff();
}
});

View File

@ -1,55 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
<method name='CanRestart'>
<arg type='b' direction='out'/>
</method>
<method name='CanStop'>
<arg type='b' direction='out'/>
</method>
<method name='Restart' />
<method name='Stop' />
<method name='GetCurrentSession'>
<arg type='o' direction='out' />
</method>
</interface>;
const ConsoleKitSessionIface = <interface name='org.freedesktop.ConsoleKit.Session'>
<method name='IsActive'>
<arg type='b' direction='out' />
</method>
<signal name='ActiveChanged'>
<arg type='b' direction='out' />
</signal>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const ConsoleKitSessionProxy = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
const ConsoleKitManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ConsoleKitManagerIface);
function ConsoleKitManager() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
g_interface_name: ConsoleKitManagerInfo.name,
g_interface_info: ConsoleKitManagerInfo,
g_name: 'org.freedesktop.ConsoleKit',
g_object_path: '/org/freedesktop/ConsoleKit/Manager',
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
self.init(null);
self.GetCurrentSessionRemote(function([session]) {
self.ckSession = new ConsoleKitSessionProxy(Gio.DBus.system, 'org.freedesktop.ConsoleKit', session);
self.ckSession.connectSignal('ActiveChanged', function(object, senderName, [isActive]) {
self.sessionActive = isActive;
});
self.ckSession.IsActiveRemote(function([isActive]) {
self.sessionActive = isActive;
});
});
return self;
}

197
js/misc/loginManager.js Normal file
View File

@ -0,0 +1,197 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager'>
<method name='PowerOff'>
<arg type='b' direction='in'/>
</method>
<method name='Reboot'>
<arg type='b' direction='in'/>
</method>
<method name='CanPowerOff'>
<arg type='s' direction='out'/>
</method>
<method name='CanReboot'>
<arg type='s' direction='out'/>
</method>
</interface>;
const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session'>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
<method name='CanRestart'>
<arg type='b' direction='out'/>
</method>
<method name='CanStop'>
<arg type='b' direction='out'/>
</method>
<method name='Restart' />
<method name='Stop' />
<method name='GetCurrentSession'>
<arg type='o' direction='out' />
</method>
</interface>;
const ConsoleKitSessionIface = <interface name='org.freedesktop.ConsoleKit.Session'>
<method name='IsActive'>
<arg type='b' direction='out' />
</method>
<signal name='ActiveChanged'>
<arg type='b' direction='out' />
</signal>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
}
let _loginManager = null;
/**
* LoginManager:
* An abstraction over systemd/logind and ConsoleKit.
*
*/
function getLoginManager() {
if (_loginManager == null) {
if (haveSystemd())
_loginManager = new LoginManagerSystemd();
else
_loginManager = new LoginManagerConsoleKit();
}
return _loginManager;
}
const LoginManagerSystemd = new Lang.Class({
Name: 'LoginManagerSystemd',
_init: function() {
this._proxy = new SystemdLoginManager(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() {
if (!this._currentSession) {
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1/session/' +
GLib.getenv('XDG_SESSION_ID'));
}
return this._currentSession;
},
get sessionActive() {
return Shell.session_is_active_for_systemd();
},
canPowerOff: function(asyncCallback) {
this._proxy.CanPowerOffRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0] != 'no');
});
},
canReboot: function(asyncCallback) {
this._proxy.CanRebootRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0] != 'no');
});
},
powerOff: function() {
this._proxy.PowerOffRemote(true);
},
reboot: function() {
this._proxy.RebootRemote(true);
}
});
const LoginManagerConsoleKit = new Lang.Class({
Name: 'LoginManagerConsoleKit',
_init: function() {
this._proxy = new ConsoleKitManager(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager');
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() {
if (!this._currentSession) {
let [currentSessionId] = this._proxy.GetCurrentSessionSync();
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
currentSessionId);
}
return this._currentSession;
},
get sessionActive() {
if (this._sessionActive !== undefined)
return this._sessionActive;
let session = this.getCurrentSessionProxy();
session.connectSignal('ActiveChanged', Lang.bind(this, function(object, senderName, [isActive]) {
this._sessionActive = isActive;
}));
[this._sessionActive] = session.IsActiveSync();
return this._sessionActive;
},
canPowerOff: function(asyncCallback) {
this._proxy.CanStopRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0]);
});
},
canReboot: function(asyncCallback) {
this._proxy.CanRestartRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0]);
});
},
powerOff: function() {
this._proxy.StopRemote();
},
reboot: function() {
this._proxy.RestartRemote();
}
});

View File

@ -1,44 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager'>
<method name='PowerOff'>
<arg type='b' direction='in'/>
</method>
<method name='Reboot'>
<arg type='b' direction='in'/>
</method>
<method name='CanPowerOff'>
<arg type='s' direction='out'/>
</method>
<method name='CanReboot'>
<arg type='s' direction='out'/>
</method>
</interface>;
const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session'>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const SystemdLoginManagerProxy = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
const SystemdLoginSessionProxy = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
function SystemdLoginManager() {
return new SystemdLoginManagerProxy(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
};
function SystemdLoginSession(id) {
return new SystemdLoginSessionProxy(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1/session/' + id);
}
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
}

View File

@ -7,11 +7,10 @@ const Gio = imports.gi.Gio;
const Params = imports.misc.params;
const Shell = imports.gi.Shell;
const ConsoleKit = imports.misc.consoleKit;
const GnomeSession = imports.misc.gnomeSession;
const LoginManager = imports.misc.loginManager;
const Main = imports.ui.main;
const ShellMountOperation = imports.ui.shellMountOperation;
const Systemd = imports.misc.systemd;
const GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
@ -34,8 +33,7 @@ const AutomountManager = new Lang.Class({
Lang.bind(this, this._InhibitorsChanged));
this._inhibited = false;
if (!Systemd.haveSystemd())
this.ckListener = new ConsoleKit.ConsoleKitManager();
this._loginManager = LoginManager.getLoginManager();
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._lockStatusChanged));
@ -92,21 +90,10 @@ const AutomountManager = new Lang.Class({
return false;
},
isSessionActive: function() {
// Return whether the current session is active, using the
// right mechanism: either systemd if available or ConsoleKit
// as fallback.
if (Systemd.haveSystemd())
return Shell.session_is_active_for_systemd();
return this.ckListener.sessionActive;
},
_onDriveConnected: function() {
// if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds
if (!this.isSessionActive())
if (!this._loginManager.sessionActive)
return;
if (Main.screenShield.locked)
@ -118,7 +105,7 @@ const AutomountManager = new Lang.Class({
_onDriveDisconnected: function() {
// if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds
if (!this.isSessionActive())
if (!this._loginManager.sessionActive)
return;
if (Main.screenShield.locked)
@ -130,7 +117,7 @@ const AutomountManager = new Lang.Class({
_onDriveEjectButton: function(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor
// doesn't emit this signal just yet.
if (!this.isSessionActive())
if (!this._loginManager.sessionActive)
return;
// we force stop/eject in this case, so we don't have to pass a
@ -170,7 +157,7 @@ const AutomountManager = new Lang.Class({
if (params.checkSession) {
// if we're not in the current ConsoleKit session,
// don't attempt automount
if (!this.isSessionActive())
if (!this._loginManager.sessionActive)
return;
if (Main.screenShield.locked) {

View File

@ -9,13 +9,12 @@ const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St;
const ConsoleKit = imports.misc.consoleKit;
const GnomeSession = imports.misc.gnomeSession;
const Layout = imports.ui.layout;
const LoginManager = imports.misc.loginManager;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Systemd = imports.misc.systemd;
const Tweener = imports.ui.tweener;
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
@ -341,15 +340,10 @@ const ScreenShield = new Lang.Class({
this._onStatusChanged(status);
}));
if (Systemd.haveSystemd()) {
this._systemdProxy = new Systemd.SystemdLoginSession(GLib.getenv('XDG_SESSION_ID'));
this._systemdProxy.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._systemdProxy.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
} else {
this._consoleKitProxy = new ConsoleKit.ConsoleKitManager();
this._consoleKitProxy.ckSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._consoleKitProxy.ckSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
}
this._loginManager = LoginManager.getLoginManager();
this._loginSession = this._loginManager.getCurrentSessionProxy();
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });