20a69cdc2b463883e91e576a6c17c580e15a68c5
[tpsession] / tpsession-0.1 / 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  Q_UNUSED(op);
105   // qDebug() << "TpSession::onAMReady";
106  TpSessionAccount *tpacc;
107
108    foreach (const QString &path, mAM->allAccountPaths()) {
109        accounts+=tpacc=new TpSessionAccount(mAM, path);
110        connect(tpacc,SIGNAL(accountReady(TpSessionAccount*)),
111                       SLOT(onAccountReady(TpSessionAccount *)));
112     }
113
114 }
115
116 void TpSession::onReady(Tp::PendingOperation *)
117 {
118 };
119
120 void TpSession::onAccountCreated(const QString &path)
121 {
122
123     accounts+=new TpSessionAccount(mAM, path);
124 }
125
126 void TpSession::onAccountReady(TpSessionAccount *tpacc)
127 {
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) {
132     if(sync) {
133         sync=false;
134         loop.quit();
135         qDebug() << "sync eventloop exit";
136     }
137      emit accountReady(tpacc);
138      if(!reqMsg.isEmpty()) tpacc->sendMessageToAddress(reqAddress,reqMsg);
139   }
140 }
141
142 void TpSession::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionAccount *acc)
143 {
144   //    qDebug() << "TestProg::onMessageReceived " << msg.text() << "from " << msg.sender()->id();
145     emit messageReceived(msg,acc);
146 }
147
148 /**
149  * Send message using specified connection manager to address
150  *
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
154  */
155 void TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)
156 {
157  TpSessionAccount *tpsa=getAccount(connectionMgr);
158  if(tpsa) tpsa->sendMessageToAddress(address,message);
159 }
160 /**
161  * Returns pointer to TpSessionAccout object with specified connection manager or protocol, returns NULL if no match found
162  *
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
165  */
166 TpSessionAccount* TpSession::getAccount(const  QString cm,QString protocol)
167 {
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();
172      return tpacc;
173      }
174  }
175  return NULL;
176 }
177
178 void TpSession::createObserver()
179 {
180
181       qDebug() << __PRETTY_FUNCTION__ ;
182
183     registrar = Tp::ClientRegistrar::create();
184
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);
193
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);
200
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");
206
207 }
208
209
210 void TpSession::createChannelListener(const QString &channelType,
211                                    const Tp::MethodInvocationContextPtr<> &context,
212                                    const Tp::AccountPtr &account,
213                                    const Tp::ChannelPtr &channel)
214 {
215     Q_UNUSED(context);
216     Q_UNUSED(account);
217     qDebug() << "TpSession::createChannelListener";
218
219     QString channelObjectPath = channel->objectPath();
220
221
222     if ( channels.contains( channelObjectPath ) &&
223          !channelType.isEmpty() &&
224          !channelObjectPath.isEmpty() ) {
225         qDebug() << "TELEPATHY_ERROR_INVALID_ARGUMENT";
226         return;
227     }
228     qDebug() << "creating listener for: " << channelObjectPath << " type " << channelType;
229 #if 0
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);
235     }
236
237     if(listener) {
238         connect(listener, SIGNAL(channelClosed(ChannelListener *)),
239                 this, SLOT(channelClosed(ChannelListener *)));
240         Channels.append( channelObjectPath );
241     }
242 #endif
243 }
244
245
246
247
248
249
250
251