on d8fd129 help sign in
unity8/plugins/Unity/Session/dbusunitysessionservice.cpp
243 lines 6.7 kB history raw
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17// local
18#include "dbusunitysessionservice.h"
20// system
21#include <sys/types.h>
22#include <unistd.h>
23#include <pwd.h>
25// Qt
26#include <QDebug>
27#include <QDBusPendingCall>
28#include <QDBusReply>
30#define LOGIN1_SERVICE QStringLiteral("org.freedesktop.login1")
31#define LOGIN1_PATH QStringLiteral("/org/freedesktop/login1")
32#define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
33#define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
35bool checkLogin1Call(const QString &method)
37 QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
38 QDBusReply<QString> reply = QDBusConnection::systemBus().asyncCall(msg);
39 const QString retval = reply.value();
40 return (retval == QStringLiteral("yes") || retval == QStringLiteral("challenge"));
43void makeLogin1Call(const QString &method, const QVariantList &args)
45 QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
46 LOGIN1_PATH,
47 LOGIN1_IFACE,
48 method);
49 msg.setArguments(args);
50 QDBusConnection::systemBus().asyncCall(msg);
53DBusUnitySessionService::DBusUnitySessionService()
54 : UnityDBusObject("/com/canonical/Unity/Session", "com.canonical.Unity")
58void DBusUnitySessionService::Logout()
60 // TODO ask the apps to quit and then emit the signal
61 Q_EMIT LogoutReady();
64void DBusUnitySessionService::EndSession()
66 const QDBusMessage msg = QDBusMessage::createMethodCall("com.ubuntu.Upstart",
67 "/com/ubuntu/Upstart",
68 "com.ubuntu.Upstart0_6",
69 "EndSession");
70 QDBusConnection::sessionBus().asyncCall(msg);
73bool DBusUnitySessionService::CanHibernate() const
75 return checkLogin1Call("CanHibernate");
78bool DBusUnitySessionService::CanSuspend() const
80 return checkLogin1Call("CanSuspend");
83bool DBusUnitySessionService::CanHybridSleep() const
85 return checkLogin1Call("CanHybridSleep");
88bool DBusUnitySessionService::CanReboot() const
90 return checkLogin1Call("CanReboot");
93bool DBusUnitySessionService::CanShutdown() const
95 return checkLogin1Call("CanPowerOff");
98bool DBusUnitySessionService::CanLock() const
100 return true; // FIXME
103QString DBusUnitySessionService::UserName() const
105 struct passwd *p = getpwuid(getuid());
106 if (p) {
107 return QString::fromUtf8(p->pw_name);
108 }
110 return QString();
113QString DBusUnitySessionService::RealName() const
115 struct passwd *p = getpwuid(getuid());
116 if (p) {
117 const QString gecos = QString::fromLocal8Bit(p->pw_gecos);
118 if (!gecos.isEmpty()) {
119 return gecos.split(QLatin1Char(',')).first();
120 }
121 }
123 return QString();
126QString DBusUnitySessionService::HostName() const
128 char hostName[512];
129 if (gethostname(hostName, sizeof(hostName)) == -1) {
130 qWarning() << "Could not determine local hostname";
131 return QString();
132 }
133 hostName[sizeof(hostName) - 1] = '\0';
134 return QString::fromLocal8Bit(hostName);
137void DBusUnitySessionService::PromptLock()
139 Q_EMIT LockRequested();
142void DBusUnitySessionService::Lock()
144 const QString sessionId = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
145 QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DisplayManager",
146 sessionId,
147 "org.freedesktop.DisplayManager.Session",
148 "Lock");
149 qDebug() << "Locking session" << msg.path();
150 QDBusReply<void> reply = QDBusConnection::systemBus().asyncCall(msg);
151 if (!reply.isValid()) {
152 qWarning() << "Lock call failed" << reply.error().message();
153 }
156void DBusUnitySessionService::RequestLogout()
158 Q_EMIT LogoutRequested(false);
161void DBusUnitySessionService::Reboot()
163 makeLogin1Call("Reboot", {false});
166void DBusUnitySessionService::RequestReboot()
168 Q_EMIT RebootRequested(false);
171void DBusUnitySessionService::Shutdown()
173 makeLogin1Call("PowerOff", {false});
176void DBusUnitySessionService::Suspend()
178 makeLogin1Call("Suspend", {false});
181void DBusUnitySessionService::Hibernate()
183 makeLogin1Call("Hibernate", {false});
186void DBusUnitySessionService::HybridSleep()
188 makeLogin1Call("HybridSleep", {false});
191void DBusUnitySessionService::RequestShutdown()
193 Q_EMIT ShutdownRequested(false);
196enum class Action : unsigned
198 LOGOUT = 0,
199 SHUTDOWN,
200 REBOOT,
201 NONE
202};
204DBusGnomeSessionManagerWrapper::DBusGnomeSessionManagerWrapper()
205 : UnityDBusObject("/org/gnome/SessionManager/EndSessionDialog", "com.canonical.Unity")
209void DBusGnomeSessionManagerWrapper::performAsyncCall(const QString &method)
211 const QDBusMessage msg = QDBusMessage::createMethodCall("com.canonical.Unity",
212 "/com/canonical/Unity/Session",
213 "com.canonical.Unity.Session",
214 method);
215 QDBusConnection::sessionBus().asyncCall(msg);
218void DBusGnomeSessionManagerWrapper::Open(const unsigned type, const unsigned arg_1, const unsigned max_wait, const QList<QDBusObjectPath> &inhibitors)
220 Q_UNUSED(arg_1);
221 Q_UNUSED(max_wait);
222 Q_UNUSED(inhibitors);
224 const Action action = (Action)type;
226 switch (action)
227 {
228 case Action::LOGOUT:
229 performAsyncCall("RequestLogout");
230 break;
232 case Action::REBOOT:
233 performAsyncCall("RequestReboot");
234 break;
236 case Action::SHUTDOWN:
237 performAsyncCall("RequestShutdown");
238 break;
240 default:
241 break;
242 }