23 #include "connection-manager.h"
24 #include "libsignoncommon.h"
25 #include "signond/signoncommon.h"
27 #include <QDBusConnectionInterface>
29 #include <QDBusPendingCallWatcher>
31 #include <QProcessEnvironment>
32 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
33 #include <QStandardPaths>
36 using namespace SignOn;
38 static QPointer<ConnectionManager> connectionInstance = 0;
40 ConnectionManager::ConnectionManager(QObject *parent):
42 m_connection(QLatin1String(
"libsignon-qt-invalid")),
43 m_serviceStatus(ServiceStatusUnknown)
45 if (connectionInstance == 0) {
47 connectionInstance =
this;
49 BLAME() <<
"SignOn::ConnectionManager instantiated more than once!";
53 ConnectionManager::~ConnectionManager()
59 if (connectionInstance == 0) {
62 return connectionInstance;
65 void ConnectionManager::connect()
67 if (m_connection.isConnected()) {
68 Q_EMIT connected(m_connection);
74 bool ConnectionManager::hasConnection()
const
76 return m_connection.isConnected();
79 ConnectionManager::SocketConnectionStatus
80 ConnectionManager::setupSocketConnection()
82 QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
83 QLatin1String one(
"1");
84 if (environment.value(QLatin1String(
"SSO_USE_PEER_BUS"), one) != one) {
85 return SocketConnectionUnavailable;
88 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
90 QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
92 QString runtimeDir = environment.value(QLatin1String(
"XDG_RUNTIME_DIR"));
94 if (runtimeDir.isEmpty())
return SocketConnectionUnavailable;
96 QString socketFileName =
97 QString::fromLatin1(
"unix:path=%1/" SIGNOND_SOCKET_FILENAME).arg(runtimeDir);
100 QDBusConnection connection =
101 QDBusConnection::connectToPeer(socketFileName,
102 QString(QLatin1String(
"libsignon-qt%1")).arg(count++));
103 if (!connection.isConnected()) {
104 QDBusError error = connection.lastError();
105 QString name = error.name();
106 TRACE() <<
"p2p error:" << error << error.type();
107 if (name == QLatin1String(
"org.freedesktop.DBus.Error.FileNotFound") &&
108 m_serviceStatus != ServiceActivated) {
109 return SocketConnectionNoService;
111 return SocketConnectionUnavailable;
115 m_connection = connection;
116 m_connection.connect(QString(),
117 QLatin1String(
"/org/freedesktop/DBus/Local"),
118 QLatin1String(
"org.freedesktop.DBus.Local"),
119 QLatin1String(
"Disconnected"),
120 this, SLOT(onDisconnected()));
122 return SocketConnectionOk;
125 void ConnectionManager::init()
127 if (m_serviceStatus == ServiceActivating)
return;
129 SocketConnectionStatus status = setupSocketConnection();
131 if (status == SocketConnectionNoService) {
132 TRACE() <<
"Peer connection unavailable, activating service";
133 QDBusConnectionInterface *
interface =
134 QDBusConnection::sessionBus().interface();
135 QDBusPendingCall call =
136 interface->asyncCall(QLatin1String(
"StartServiceByName"),
137 SIGNOND_SERVICE, uint(0));
138 m_serviceStatus = ServiceActivating;
139 QDBusPendingCallWatcher *watcher =
140 new QDBusPendingCallWatcher(call,
this);
141 QObject::connect(watcher,
142 SIGNAL(finished(QDBusPendingCallWatcher*)),
144 SLOT(onActivationDone(QDBusPendingCallWatcher*)));
145 }
else if (status == SocketConnectionUnavailable) {
146 m_connection = SIGNOND_BUS;
149 if (m_connection.isConnected()) {
150 TRACE() <<
"Connected to" << m_connection.name();
151 Q_EMIT connected(m_connection);
155 void ConnectionManager::onActivationDone(QDBusPendingCallWatcher *watcher)
157 QDBusPendingReply<> reply(*watcher);
158 watcher->deleteLater();
160 if (!reply.isError()) {
161 m_serviceStatus = ServiceActivated;
165 BLAME() << reply.error();
169 void ConnectionManager::onDisconnected()
171 TRACE() <<
"Disconnected from daemon";
172 m_serviceStatus = ServiceStatusUnknown;
173 Q_EMIT disconnected();