23#include "connection-manager.h"
25#include "libsignoncommon.h"
26#include "signond/signoncommon.h"
28#include <QDBusConnectionInterface>
30#include <QDBusPendingCallWatcher>
32#include <QProcessEnvironment>
33#include <QStandardPaths>
37static QPointer<ConnectionManager> connectionInstance = 0;
39ConnectionManager::ConnectionManager(QObject *parent):
41 m_connection(QLatin1String(
"libsignon-qt-invalid")),
42 m_serviceStatus(ServiceStatusUnknown),
45 if (connectionInstance == 0) {
47 connectionInstance =
this;
49 BLAME() <<
"SignOn::ConnectionManager instantiated more than once!";
53ConnectionManager::~ConnectionManager()
59 if (connectionInstance == 0) {
62 return connectionInstance;
65void ConnectionManager::connect()
67 if (m_connection.isConnected()) {
68 Q_EMIT connected(m_connection);
74bool ConnectionManager::hasConnection()
const
76 return m_connection.isConnected();
79ConnectionManager::SocketConnectionStatus
80ConnectionManager::setupSocketConnection()
82 QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
83 QLatin1String one(
"1");
84 if (environment.value(QLatin1String(
"SSO_USE_PEER_BUS"), one) != one) {
85 return SocketConnectionUnavailable;
89 QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
90 if (runtimeDir.isEmpty())
return SocketConnectionUnavailable;
92 QString socketFileName =
93 QString::fromLatin1(
"unix:path=%1/" SIGNOND_SOCKET_FILENAME).arg(runtimeDir);
96 QDBusConnection connection =
97 QDBusConnection::connectToPeer(socketFileName,
98 QString(QLatin1String(
"libsignon-qt%1")).arg(count++));
99 if (!connection.isConnected()) {
100 QDBusError error = connection.lastError();
101 QString name = error.name();
102 TRACE() <<
"p2p error:" << error << error.type();
103 if (name == QLatin1String(
"org.freedesktop.DBus.Error.FileNotFound") &&
104 m_serviceStatus != ServiceActivated) {
105 return SocketConnectionNoService;
107 return SocketConnectionUnavailable;
111 m_connection = connection;
112 m_connection.connect(QString(),
113 QLatin1String(
"/org/freedesktop/DBus/Local"),
114 QLatin1String(
"org.freedesktop.DBus.Local"),
115 QLatin1String(
"Disconnected"),
116 this, SLOT(onDisconnected()));
118 return SocketConnectionOk;
121void ConnectionManager::init()
123 if (m_serviceStatus == ServiceActivating)
return;
125 SocketConnectionStatus status = setupSocketConnection();
127 if (status == SocketConnectionUnavailable) {
129 if (m_retryCount >= 15) {
130 BLAME() <<
"Unable to activate p2p signond service!";
133 TRACE() <<
"Unable to activate p2p signond service, trying again";
134 status = SocketConnectionNoService;
137 TRACE() <<
"Unable to activate p2p signond service, falling back to session bus";
138 m_connection = SIGNOND_BUS;
142 if (status == SocketConnectionNoService) {
143 TRACE() <<
"Peer connection unavailable, activating service";
144 QDBusConnectionInterface *
interface =
145 QDBusConnection::sessionBus().interface();
146 QDBusPendingCall call =
147 interface->asyncCall(QLatin1String(
"StartServiceByName"),
148 SIGNOND_SERVICE, uint(0));
149 m_serviceStatus = ServiceActivating;
150 QDBusPendingCallWatcher *watcher =
151 new QDBusPendingCallWatcher(call,
this);
152 QObject::connect(watcher,
153 SIGNAL(finished(QDBusPendingCallWatcher*)),
155 SLOT(onActivationDone(QDBusPendingCallWatcher*)));
158 if (m_connection.isConnected()) {
160 TRACE() <<
"Connected to" << m_connection.name();
161 Q_EMIT connected(m_connection);
165void ConnectionManager::onActivationDone(QDBusPendingCallWatcher *watcher)
167 QDBusPendingReply<> reply(*watcher);
168 watcher->deleteLater();
170 if (!reply.isError()) {
171 m_serviceStatus = ServiceActivated;
175 BLAME() << reply.error();
179void ConnectionManager::onDisconnected()
181 TRACE() <<
"Disconnected from daemon";
182 m_serviceStatus = ServiceStatusUnknown;
183 Q_EMIT disconnected();