first release
[groupsms] / sms / tpsession / tpsession.cpp
1 /*
2  * This file is part of TpSession
3  *
4  * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
5  * Contact Kate Alhola  kate.alhola(a)nokia.com
6  *
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.
11  *
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.
16  *
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
20  */
21 #include "tpsession.h"
22 #include <QDebug>
23
24
25
26
27
28 /**
29  * \class TpSession
30  * \headerfile <tpsession.h>
31  *
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.
36  */
37 /**
38  * \fn void TpSession::accountReady(TpSessionAccount *);
39  *
40  * Emitted when the account becomes ready
41  *
42  * \param  TpSessionAccount  pointer to account become ready
43  */
44 /**
45  * \fn void TpSession::amReady(TpSession *);
46  *
47  * Emitted when the account Manager becomes ready
48  *
49  * \param  TpSession  pointer to TpSession class
50  */
51 /**
52  * \fn void TpSession::messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
53  *
54  * Emitted when any of Account Managers recived message
55  *
56  * \param  Tp::ReceivedMessage  Message received
57  * \param  TpSessionAccount  pointer to account received message
58  */
59
60
61 /**
62  * Construct a new TpSession object.
63  *
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
67  */
68 TpSession::TpSession(QString cmname,bool synchronous)
69 {
70     Tp::registerTypes();
71     Tp::enableDebug(false);
72     Tp::enableWarnings(false);
73
74     mAM = Tp::AccountManager::create();
75     reqCm=cmname;
76     sync=synchronous;
77     connect(mAM->becomeReady(),
78             SIGNAL(finished(Tp::PendingOperation *)),
79             SLOT(onAMReady(Tp::PendingOperation *)));
80     connect(mAM.data(),
81             SIGNAL(accountCreated(const QString &)),
82             SLOT(onAccountCreated(const QString &)));
83
84     // createObserver();
85     if(synchronous) loop.exec(); // Loop locally untill accounts are initialized
86     reqCm=cmname;
87
88 }
89 TpSession* TpSession::instancePtr=NULL;
90 /**
91  * Returns pointer to TpSession singleton. If there is not yet TpSession Object, creates it with "Ring" connection manager as default
92  *
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
95  */
96 TpSession* TpSession::instance(bool synchronous)
97 {
98     if(instancePtr==NULL) instancePtr=new TpSession("ring",synchronous);
99     return instancePtr;
100 };
101
102 void TpSession::onAMReady(Tp::PendingOperation *op)
103 {
104     // qDebug() << "TpSession::onAMReady";
105     TpSessionAccount *tpacc;
106
107     Q_FOREACH (const QString &path, mAM->allAccountPaths()) {
108         accounts+=tpacc=new TpSessionAccount(mAM, path);
109         connect(tpacc,SIGNAL(accountReady(TpSessionAccount*)),
110                 SLOT(onAccountReady(TpSessionAccount *)));
111     }
112
113 }
114
115 void TpSession::onReady(Tp::PendingOperation *)
116 {
117 };
118
119 void TpSession::onAccountCreated(const QString &path)
120 {
121
122     accounts+=new TpSessionAccount(mAM, path);
123 }
124
125 void TpSession::onAccountReady(TpSessionAccount *tpacc)
126 {
127     qDebug() << "TpSession::onAccountReady:Account " << tpacc->acc->cmName() << "is Ready sync=" << sync << "waiting:" << reqCm;
128     connect(tpacc,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)),
129             SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)));
130     // Tom add
131     connect(tpacc,SIGNAL(messageSent(const Tp::Message &,TpSessionAccount *)),
132             SLOT(onMessageSent(const Tp::Message &,TpSessionAccount *)));
133     // Tom end
134     if(!reqCm.isEmpty() && tpacc->acc->cmName()==reqCm) {
135         if(sync) {
136             sync=false;
137             loop.quit();
138             qDebug() << "sync eventloop exit";
139         }
140         Q_EMIT accountReady(tpacc);
141         if(!reqMsg.isEmpty()) tpacc->sendMessageToAddress(reqAddress,reqMsg);
142     }
143 }
144
145 void TpSession::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionAccount *acc)
146 {
147     //    qDebug() << "TestProg::onMessageReceived " << msg.text() << "from " << msg.sender()->id();
148     Q_EMIT messageReceived(msg,acc);
149 }
150
151 // Tom add
152 void TpSession::onMessageSent(const Tp::Message &msg,TpSessionAccount *acc)
153 {
154     //    qDebug() << "TpSession::onMessageSent " << msg.text() << "from " << msg.sender()->id();
155     Q_EMIT messageSent(msg,acc);
156 }
157 // Tom end
158
159 /**
160  * Send message using specified connection manager to address
161  *
162  * \param connectionMgr  Name of the connection manager
163  * \param address Valid address for this connection manager type. Asexample telephone number to Ring, GoogleTalk address for Gabble
164  * \param message Message body
165  */
166 void TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)
167 {
168     qDebug() << "TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)";
169     TpSessionAccount *tpsa=getAccount(connectionMgr);
170     if(tpsa)
171     {
172         tpsa->sendMessageToAddress(address,message);
173     }
174 }
175 /**
176  * Returns pointer to TpSessionAccout object with specified connection manager or protocol, returns NULL if no match found
177  *
178  * \param cm  Name of the connection manager, or iniqueIdentifier (dbus path  to cm) if left empty matches every entry
179  * \param protocol Name of the protocol manager, if left empty matches every entry
180  */
181 TpSessionAccount* TpSession::getAccount(const  QString cm,QString protocol)
182 {
183     // qDebug() << "TpSession::getAccount" << cm << " " << protocol;
184     Q_FOREACH (TpSessionAccount *tpacc, accounts) {
185         if((!cm.isEmpty()  && ((tpacc->acc->cmName()==cm) || (tpacc->acc->uniqueIdentifier()==cm))) || (!protocol.isEmpty() && tpacc->acc->protocol()==protocol)) {
186             //     qDebug() << "TpSession::getAccount found" << tpacc->acc->cmName() << " " << tpacc->acc->protocol() << " " << tpacc->acc->uniqueIdentifier();
187             return tpacc;
188         }
189     }
190     return NULL;
191 }
192
193 void TpSession::createObserver()
194 {
195
196     qDebug() << __PRETTY_FUNCTION__ ;
197
198     registrar = Tp::ClientRegistrar::create();
199
200     Tp::ChannelClassList channelFilters;
201     QMap<QString, QDBusVariant> textFilter, mediaFilter;
202     // Registering Text channel observer
203     textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
204                       QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT));
205     textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
206                       QDBusVariant(Tp::HandleTypeContact));
207     channelFilters.append(textFilter);
208
209     // Registering Media channel observer
210     mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
211                        QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA));
212     mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
213                        QDBusVariant(Tp::HandleTypeContact));
214     channelFilters.append(mediaFilter);
215
216     TpSessionObserver* observer = new TpSessionObserver( channelFilters, this );
217     bool registered = registrar->registerClient(
218             Tp::AbstractClientPtr::dynamicCast(Tp::SharedPtr<TpSessionObserver>(observer)),
219             "TpSessionChannelObserver");
220
221     //        qDebug() << "TpSession::createObserver" << (registered ? "started" : "failed");
222
223 }
224
225
226 void TpSession::createChannelListener(const QString &channelType,
227                                       const Tp::MethodInvocationContextPtr<> &context,
228                                       const Tp::AccountPtr &account,
229                                       const Tp::ChannelPtr &channel)
230 {
231     qDebug() << "TpSession::createChannelListener";
232
233     QString channelObjectPath = channel->objectPath();
234
235
236     if ( channels.contains( channelObjectPath ) &&
237          !channelType.isEmpty() &&
238          !channelObjectPath.isEmpty() ) {
239         qDebug() << "TELEPATHY_ERROR_INVALID_ARGUMENT";
240         return;
241     }
242     qDebug() << "creating listener for: " << channelObjectPath << " type " << channelType;
243 #if 0
244     ChannelListener* listener = 0;
245     if( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT ) {
246         listener = new TextChannelListener(account, channel, context);
247     } else if ( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA ) {
248         listener = new StreamChannelListener(account, channel, context);
249     }
250
251     if(listener) {
252         connect(listener, SIGNAL(channelClosed(ChannelListener *)),
253                 this, SLOT(channelClosed(ChannelListener *)));
254         Channels.append( channelObjectPath );
255     }
256 #endif
257 }
258
259
260
261
262
263
264
265