1 /***************************************************************************
2 * Copyright (c) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
3 * Copyright (c) 2013 Abdurrahman AVCI <abdurrahmanavci@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ***************************************************************************/
20 
21 #include "GreeterProxy.h"
22 
23 #include "Configuration.h"
24 #include "Messages.h"
25 #include "SessionModel.h"
26 #include "SocketWriter.h"
27 
28 #include <QLocalSocket>
29 
30 namespace SDDM {
31     class GreeterProxyPrivate {
32     public:
33         SessionModel *sessionModel { nullptr };
34         QLocalSocket *socket { nullptr };
35         QString hostName;
36         bool canPowerOff { false };
37         bool canReboot { false };
38         bool canSuspend { false };
39         bool canHibernate { false };
40         bool canHybridSleep { false };
41     };
42 
GreeterProxy(const QString & socket,QObject * parent)43     GreeterProxy::GreeterProxy(const QString &socket, QObject *parent) : QObject(parent), d(new GreeterProxyPrivate()) {
44         d->socket = new QLocalSocket(this);
45         // connect signals
46         connect(d->socket, &QLocalSocket::connected, this, &GreeterProxy::connected);
47         connect(d->socket, &QLocalSocket::disconnected, this, &GreeterProxy::disconnected);
48         connect(d->socket, &QLocalSocket::readyRead, this, &GreeterProxy::readyRead);
49         connect(d->socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error), this, &GreeterProxy::error);
50 
51         // connect to server
52         d->socket->connectToServer(socket);
53     }
54 
~GreeterProxy()55     GreeterProxy::~GreeterProxy() {
56         delete d;
57     }
58 
hostName() const59     const QString &GreeterProxy::hostName() const {
60         return d->hostName;
61     }
62 
setSessionModel(SessionModel * model)63     void GreeterProxy::setSessionModel(SessionModel *model) {
64         d->sessionModel = model;
65     }
66 
canPowerOff() const67     bool GreeterProxy::canPowerOff() const {
68         return d->canPowerOff;
69     }
70 
canReboot() const71     bool GreeterProxy::canReboot() const {
72         return d->canReboot;
73     }
74 
canSuspend() const75     bool GreeterProxy::canSuspend() const {
76         return d->canSuspend;
77     }
78 
canHibernate() const79     bool GreeterProxy::canHibernate() const {
80         return d->canHibernate;
81     }
82 
canHybridSleep() const83     bool GreeterProxy::canHybridSleep() const {
84         return d->canHybridSleep;
85     }
86 
isConnected() const87     bool GreeterProxy::isConnected() const {
88         return d->socket->state() == QLocalSocket::ConnectedState;
89     }
90 
powerOff()91     void GreeterProxy::powerOff() {
92         SocketWriter(d->socket) << quint32(GreeterMessages::PowerOff);
93     }
94 
reboot()95     void GreeterProxy::reboot() {
96         SocketWriter(d->socket) << quint32(GreeterMessages::Reboot);
97     }
98 
suspend()99     void GreeterProxy::suspend() {
100         SocketWriter(d->socket) << quint32(GreeterMessages::Suspend);
101     }
102 
hibernate()103     void GreeterProxy::hibernate() {
104         SocketWriter(d->socket) << quint32(GreeterMessages::Hibernate);
105     }
106 
hybridSleep()107     void GreeterProxy::hybridSleep() {
108         SocketWriter(d->socket) << quint32(GreeterMessages::HybridSleep);
109     }
110 
login(const QString & user,const QString & password,const int sessionIndex) const111     void GreeterProxy::login(const QString &user, const QString &password, const int sessionIndex) const {
112         if (!d->sessionModel) {
113             // log error
114             qCritical() << "Session model is not set.";
115 
116             // return
117             return;
118         }
119 
120         // get model index
121         QModelIndex index = d->sessionModel->index(sessionIndex, 0);
122 
123         // send command to the daemon
124         Session::Type type = static_cast<Session::Type>(d->sessionModel->data(index, SessionModel::TypeRole).toInt());
125         QString name = d->sessionModel->data(index, SessionModel::FileRole).toString();
126         Session session(type, name);
127         SocketWriter(d->socket) << quint32(GreeterMessages::Login) << user << password << session;
128     }
129 
connected()130     void GreeterProxy::connected() {
131         // log connection
132         qDebug() << "Connected to the daemon.";
133 
134         // send connected message
135         SocketWriter(d->socket) << quint32(GreeterMessages::Connect);
136     }
137 
disconnected()138     void GreeterProxy::disconnected() {
139         // log disconnection
140         qDebug() << "Disconnected from the daemon.";
141     }
142 
error()143     void GreeterProxy::error() {
144         qCritical() << "Socket error: " << d->socket->errorString();
145     }
146 
readyRead()147     void GreeterProxy::readyRead() {
148         // input stream
149         QDataStream input(d->socket);
150 
151         while (input.device()->bytesAvailable()) {
152             // read message
153             quint32 message;
154             input >> message;
155 
156             switch (DaemonMessages(message)) {
157                 case DaemonMessages::Capabilities: {
158                     // log message
159                     qDebug() << "Message received from daemon: Capabilities";
160 
161                     // read capabilities
162                     quint32 capabilities;
163                     input >> capabilities;
164 
165                     // parse capabilities
166                     d->canPowerOff = capabilities & Capability::PowerOff;
167                     d->canReboot = capabilities & Capability::Reboot;
168                     d->canSuspend = capabilities & Capability::Suspend;
169                     d->canHibernate = capabilities & Capability::Hibernate;
170                     d->canHybridSleep = capabilities & Capability::HybridSleep;
171 
172                     // emit signals
173                     emit canPowerOffChanged(d->canPowerOff);
174                     emit canRebootChanged(d->canReboot);
175                     emit canSuspendChanged(d->canSuspend);
176                     emit canHibernateChanged(d->canHibernate);
177                     emit canHybridSleepChanged(d->canHybridSleep);
178                 }
179                 break;
180                 case DaemonMessages::HostName: {
181                     // log message
182                     qDebug() << "Message received from daemon: HostName";
183 
184                     // read host name
185                     input >> d->hostName;
186 
187                     // emit signal
188                     emit hostNameChanged(d->hostName);
189                 }
190                 break;
191                 case DaemonMessages::LoginSucceeded: {
192                     // log message
193                     qDebug() << "Message received from daemon: LoginSucceeded";
194 
195                     // emit signal
196                     emit loginSucceeded();
197                 }
198                 break;
199                 case DaemonMessages::LoginFailed: {
200                     // log message
201                     qDebug() << "Message received from daemon: LoginFailed";
202 
203                     // emit signal
204                     emit loginFailed();
205                 }
206                 break;
207                 default: {
208                     // log message
209                     qWarning() << "Unknown message received from daemon.";
210                 }
211             }
212         }
213     }
214 }
215