2
* Copyright (C) 2013 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU General Public License version 3, as published by
6
* the Free Software Foundation.
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
* General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Tiago Salem Herrmann <tiago.herrmann@canonical.com>
18
* Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
21
#include "telepathyhelper.h"
22
#include <TelepathyQt/AbstractClient>
23
#include <TelepathyQt/AccountSet>
24
#include <TelepathyQt/ClientRegistrar>
25
#include <TelepathyQt/PendingReady>
26
#include <TelepathyQt/PendingAccount>
28
TelepathyHelper::TelepathyHelper(QObject *parent)
30
//mChannelObserver(0),
37
mAccountFeatures << Tp::Account::FeatureCore;
38
mContactFeatures << Tp::Contact::FeatureAlias
39
<< Tp::Contact::FeatureAvatarData
40
<< Tp::Contact::FeatureAvatarToken
41
<< Tp::Contact::FeatureCapabilities
42
<< Tp::Contact::FeatureSimplePresence;
43
mConnectionFeatures << Tp::Connection::FeatureCore
44
<< Tp::Connection::FeatureSelfContact
45
<< Tp::Connection::FeatureSimplePresence;
47
Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus());
48
channelFactory->addCommonFeatures(Tp::Channel::FeatureCore);
50
mAccountManager = Tp::AccountManager::create(
51
Tp::AccountFactory::create(QDBusConnection::sessionBus(), mAccountFeatures),
52
Tp::ConnectionFactory::create(QDBusConnection::sessionBus(), mConnectionFeatures),
54
Tp::ContactFactory::create(mContactFeatures));
56
connect(mAccountManager->becomeReady(Tp::AccountManager::FeatureCore),
57
SIGNAL(finished(Tp::PendingOperation*)),
58
SLOT(onAccountManagerReady(Tp::PendingOperation*)));
60
mClientRegistrar = Tp::ClientRegistrar::create(mAccountManager);
63
TelepathyHelper::~TelepathyHelper()
67
TelepathyHelper *TelepathyHelper::instance()
69
static TelepathyHelper* helper = new TelepathyHelper();
73
QString TelepathyHelper::accountId() const
76
return mAccount->uniqueIdentifier();
81
Tp::AccountPtr TelepathyHelper::account() const
87
ChannelObserver *TelepathyHelper::channelObserver() const
89
return mChannelObserver;
93
bool TelepathyHelper::connected() const
99
void TelepathyHelper::registerChannelObserver(const QString &observerName)
101
QString name = observerName;
103
if (name.isEmpty()) {
104
name = "TelephonyPluginObserver";
107
if (mChannelObserver) {
108
mChannelObserver->deleteLater();
111
mChannelObserver = new ChannelObserver(this);
112
registerClient(mChannelObserver, name);
115
connect(mChannelObserver, SIGNAL(textChannelAvailable(Tp::TextChannelPtr)),
116
ChatManager::instance(), SLOT(onTextChannelAvailable(Tp::TextChannelPtr)));
119
connect(mChannelObserver, SIGNAL(callChannelAvailable(Tp::CallChannelPtr)),
120
CallManager::instance(), SLOT(onCallChannelAvailable(Tp::CallChannelPtr)));
122
Q_EMIT channelObserverCreated(mChannelObserver);
125
void TelepathyHelper::unregisterChannelObserver()
127
Tp::AbstractClientPtr clientPtr(mChannelObserver);
129
mClientRegistrar->unregisterClient(clientPtr);
131
mChannelObserver->deleteLater();
132
mChannelObserver = NULL;
133
Q_EMIT channelObserverUnregistered();
137
QStringList TelepathyHelper::supportedProtocols() const
139
QStringList protocols;
144
void TelepathyHelper::initializeAccount()
146
// watch for account state and connection changes
147
connect(mAccount.data(),
148
SIGNAL(stateChanged(bool)),
149
SLOT(onAccountStateChanged(bool)));
150
connect(mAccount.data(),
151
SIGNAL(connectionChanged(const Tp::ConnectionPtr&)),
152
SLOT(onAccountConnectionChanged(const Tp::ConnectionPtr&)));
154
// and make sure it is enabled and connected
155
if (!mAccount->isEnabled()) {
156
ensureAccountEnabled();
158
ensureAccountConnected();
162
void TelepathyHelper::ensureAccountEnabled()
164
mAccount->setConnectsAutomatically(true);
165
connect(mAccount->setEnabled(true),
166
SIGNAL(finished(Tp::PendingOperation*)),
167
SLOT(onAccountEnabled(Tp::PendingOperation*)));
170
void TelepathyHelper::ensureAccountConnected()
172
// if the account is not connected, request it to connect
173
if (!mAccount->connection() || mAccount->connectionStatus() != Tp::ConnectionStatusConnected) {
174
Tp::Presence presence(Tp::ConnectionPresenceTypeAvailable, "available", "online");
175
mAccount->setRequestedPresence(presence);
177
watchSelfContactPresence();
181
Q_EMIT accountReady();
186
void TelepathyHelper::watchSelfContactPresence()
188
if (mAccount.isNull() || mAccount->connection().isNull()) {
192
connect(mAccount->connection()->selfContact().data(),
193
SIGNAL(presenceChanged(Tp::Presence)),
194
SLOT(onPresenceChanged(Tp::Presence)));
195
onPresenceChanged(mAccount->connection()->selfContact()->presence());
198
void TelepathyHelper::registerClient(Tp::AbstractClient *client, QString name)
200
Tp::AbstractClientPtr clientPtr(client);
201
bool succeeded = mClientRegistrar->registerClient(clientPtr, name);
205
// limit the number of registered clients to 20, that should be a safe margin
206
while (!succeeded && count < 20) {
207
succeeded = mClientRegistrar->registerClient(clientPtr, name.arg(++count));
209
name = name.arg(count);
215
QObject *object = dynamic_cast<QObject*>(client);
217
object->setProperty("clientName", TP_QT_IFACE_CLIENT + "." + name );
222
void TelepathyHelper::onAccountManagerReady(Tp::PendingOperation *op)
226
Tp::AccountSetPtr accountSet;
227
// try to find an account of the one of supported protocols
228
Q_FOREACH(const QString &protocol, supportedProtocols()) {
229
accountSet = mAccountManager->accountsByProtocol(protocol);
230
if (accountSet->accounts().count() > 0) {
235
if (accountSet->accounts().count() == 0) {
236
qCritical() << "No compatible telepathy account found!";
240
mAccount = accountSet->accounts()[0];
242
// in case we have more than one account, the first one to show on the list is going to be used
243
if (accountSet->accounts().count() > 1) {
244
qWarning() << "There are more than just one account of type" << mAccount->protocolName();
247
Q_EMIT accountIdChanged();
252
void TelepathyHelper::onAccountEnabled(Tp::PendingOperation *op)
254
// we might need to do more stuff once the account is enabled, but making sure it is connected is a good start
255
ensureAccountConnected();
258
void TelepathyHelper::onAccountStateChanged(bool enabled)
261
ensureAccountEnabled();
265
void TelepathyHelper::onAccountConnectionChanged(const Tp::ConnectionPtr &connection)
267
if (connection.isNull()) {
268
ensureAccountConnected();
270
watchSelfContactPresence();
272
Q_EMIT connectionChanged();
275
void TelepathyHelper::onPresenceChanged(const Tp::Presence &presence)
277
mConnected = (presence.type() == Tp::ConnectionPresenceTypeAvailable);
278
Q_EMIT connectedChanged();