// -*- 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 Mainloop = imports.mainloop; const Shell = imports.gi.Shell; const Signals = imports.signals; const SystemdLoginManagerIface = ; const SystemdLoginSessionIface = ; const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface); const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface); const ConsoleKitManagerIface = ; const ConsoleKitSessionIface = ; 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'); this._proxy.connectSignal('PrepareForSleep', Lang.bind(this, this._prepareForSleep)); }, // 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; }, 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'); }); }, canSuspend: function(asyncCallback) { this._proxy.CanSuspendRemote(function(result, error) { if (error) asyncCallback(false); else asyncCallback(result[0] != 'no'); }); }, listSessions: function(asyncCallback) { this._proxy.ListSessionsRemote(function(result, error) { if (error) asyncCallback([]); else asyncCallback(result[0]); }); }, powerOff: function() { this._proxy.PowerOffRemote(true); }, reboot: function() { this._proxy.RebootRemote(true); }, suspend: function() { this._proxy.SuspendRemote(true); }, inhibit: function(reason, callback) { let inVariant = GLib.Variant.new('(ssss)', ['sleep', 'GNOME Shell', reason, 'delay']); this._proxy.call_with_unix_fd_list('Inhibit', inVariant, 0, -1, null, null, Lang.bind(this, function(proxy, result) { let fd = -1; try { let [outVariant, fdList] = proxy.call_with_unix_fd_list_finish(result); fd = fdList.steal_fds(outVariant.deep_unpack())[0]; callback(new Gio.UnixInputStream({ fd: fd })); } catch(e) { logError(e, "Error getting systemd inhibitor"); callback(null); } })); }, _prepareForSleep: function(proxy, sender, [aboutToSuspend]) { this.emit('prepare-for-sleep', aboutToSuspend); } }); Signals.addSignalMethods(LoginManagerSystemd.prototype); 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; }, 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]); }); }, canSuspend: function(asyncCallback) { asyncCallback(false); }, listSessions: function(asyncCallback) { asyncCallback([]); }, powerOff: function() { this._proxy.StopRemote(); }, reboot: function() { this._proxy.RestartRemote(); }, suspend: function() { this.emit('prepare-for-sleep', true); this.emit('prepare-for-sleep', false); }, inhibit: function(reason, callback) { callback(null); } }); Signals.addSignalMethods(LoginManagerConsoleKit.prototype);