2 * This file is part of TpSession
4 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
5 * Contact Kate Alhola kate.alhola(a)nokia.com
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "tpsession.h"
30 * \headerfile <tpsession.h>
32 * Top level class, counterpart of Account Manager. TpSession connects to account manager and requests accounts from it. TpSession creates TpSessionAccount for all accounts .
33 * As top level class TpSession provides simålified interface to send and receive messages via any account. TpSession provides signal when it has accounts ready.
34 * If you require some specific account in constructor, you will receive signal only when this account is ready. If you use constructor without any parameters, you will get one
35 * signal for every account. If synchronous is true, constructor is executed as synchronous and it does return after transactions to set up accounts are done.
38 * \fn void TpSession::accountReady(TpSessionAccount *);
40 * Emitted when the account becomes ready
42 * \param TpSessionAccount pointer to account become ready
45 * \fn void TpSession::amReady(TpSession *);
47 * Emitted when the account Manager becomes ready
49 * \param TpSession pointer to TpSession class
52 * \fn void TpSession::messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
54 * Emitted when any of Account Managers recived message
56 * \param Tp::ReceivedMessage Message received
57 * \param TpSessionAccount pointer to account received message
62 * Construct a new TpSession object.
64 * \param cmname Name of the default connection manager. Can be empty or omnitted, then there is no default connection manager
65 * \param synchronous if false, asynchronous behavior, function returns immediately and accountReady signals are emitted when accounts are ready
66 * if True, synchronous behavior and function returns when accounts are ready
68 TpSession::TpSession(QString cmname,bool synchronous)
71 Tp::enableDebug(false);
72 Tp::enableWarnings(false);
74 mAM = Tp::AccountManager::create();
77 connect(mAM->becomeReady(),
78 SIGNAL(finished(Tp::PendingOperation *)),
79 SLOT(onAMReady(Tp::PendingOperation *)));
81 SIGNAL(accountCreated(const QString &)),
82 SLOT(onAccountCreated(const QString &)));
85 if(synchronous) loop.exec(); // Loop locally untill accounts are initialized
89 TpSession* TpSession::instancePtr=NULL;
91 * Returns pointer to TpSession singleton. If there is not yet TpSession Object, creates it with "Ring" connection manager as default
93 * \param synchronous if false, asynchronous behavior, function returns immediately and accountReady signals are emitted when accounts are ready
94 * if True, synchronous behavior and function returns when accounts are ready
96 TpSession* TpSession::instance(bool synchronous)
98 if(instancePtr==NULL) instancePtr=new TpSession("ring",synchronous);
102 void TpSession::onAMReady(Tp::PendingOperation *op)
105 // qDebug() << "TpSession::onAMReady";
106 TpSessionAccount *tpacc;
108 foreach (const QString &path, mAM->allAccountPaths()) {
109 accounts+=tpacc=new TpSessionAccount(mAM, path);
110 connect(tpacc,SIGNAL(accountReady(TpSessionAccount*)),
111 SLOT(onAccountReady(TpSessionAccount *)));
116 void TpSession::onReady(Tp::PendingOperation *)
120 void TpSession::onAccountCreated(const QString &path)
123 accounts+=new TpSessionAccount(mAM, path);
126 void TpSession::onAccountReady(TpSessionAccount *tpacc)
128 //qDebug() << "TpSession::onAccountReady:Account " << tpacc->acc->cmName() << "is Ready sync=" << sync << "waiting:" << reqCm;
129 connect(tpacc,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)),
130 SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)));
131 if(!reqCm.isEmpty() && tpacc->acc->cmName()==reqCm) {
135 qDebug() << "sync eventloop exit";
137 emit accountReady(tpacc);
138 if(!reqMsg.isEmpty()) tpacc->sendMessageToAddress(reqAddress,reqMsg);
142 void TpSession::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionAccount *acc)
144 // qDebug() << "TestProg::onMessageReceived " << msg.text() << "from " << msg.sender()->id();
145 emit messageReceived(msg,acc);
149 * Send message using specified connection manager to address
151 * \param connectionMgr Name of the connection manager
152 * \param address Valid address for this connection manager type. Asexample telephone number to Ring, GoogleTalk address for Gabble
153 * \param message Message body
155 void TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)
157 TpSessionAccount *tpsa=getAccount(connectionMgr);
158 if(tpsa) tpsa->sendMessageToAddress(address,message);
161 * Returns pointer to TpSessionAccout object with specified connection manager or protocol, returns NULL if no match found
163 * \param cm Name of the connection manager, or iniqueIdentifier (dbus path to cm) if left empty matches every entry
164 * \param protocol Name of the protocol manager, if left empty matches every entry
166 TpSessionAccount* TpSession::getAccount(const QString cm,QString protocol)
168 // qDebug() << "TpSession::getAccount" << cm << " " << protocol;
169 foreach (TpSessionAccount *tpacc, accounts) {
170 if((!cm.isEmpty() && ((tpacc->acc->cmName()==cm) || (tpacc->acc->uniqueIdentifier()==cm))) || (!protocol.isEmpty() && tpacc->acc->protocol()==protocol)) {
171 // qDebug() << "TpSession::getAccount found" << tpacc->acc->cmName() << " " << tpacc->acc->protocol() << " " << tpacc->acc->uniqueIdentifier();
178 void TpSession::createObserver()
181 qDebug() << __PRETTY_FUNCTION__ ;
183 registrar = Tp::ClientRegistrar::create();
185 Tp::ChannelClassList channelFilters;
186 QMap<QString, QDBusVariant> textFilter, mediaFilter;
187 // Registering Text channel observer
188 textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
189 QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT));
190 textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
191 QDBusVariant(Tp::HandleTypeContact));
192 channelFilters.append(textFilter);
194 // Registering Media channel observer
195 mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
196 QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA));
197 mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
198 QDBusVariant(Tp::HandleTypeContact));
199 channelFilters.append(mediaFilter);
201 TpSessionObserver* observer = new TpSessionObserver( channelFilters, this );
202 bool registered = registrar->registerClient(
203 Tp::AbstractClientPtr::dynamicCast(Tp::SharedPtr<TpSessionObserver>(observer)),
204 "TpSessionChannelObserver");
205 qDebug() << "TpSession::createObserver" << (registered ? "started" : "failed");
210 void TpSession::createChannelListener(const QString &channelType,
211 const Tp::MethodInvocationContextPtr<> &context,
212 const Tp::AccountPtr &account,
213 const Tp::ChannelPtr &channel)
217 qDebug() << "TpSession::createChannelListener";
219 QString channelObjectPath = channel->objectPath();
222 if ( channels.contains( channelObjectPath ) &&
223 !channelType.isEmpty() &&
224 !channelObjectPath.isEmpty() ) {
225 qDebug() << "TELEPATHY_ERROR_INVALID_ARGUMENT";
228 qDebug() << "creating listener for: " << channelObjectPath << " type " << channelType;
230 ChannelListener* listener = 0;
231 if( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT ) {
232 listener = new TextChannelListener(account, channel, context);
233 } else if ( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA ) {
234 listener = new StreamChannelListener(account, channel, context);
238 connect(listener, SIGNAL(channelClosed(ChannelListener *)),
239 this, SLOT(channelClosed(ChannelListener *)));
240 Channels.append( channelObjectPath );