first release
[groupsms] / sms / tpsession / tpsession.cpp
diff --git a/sms/tpsession/tpsession.cpp b/sms/tpsession/tpsession.cpp
new file mode 100755 (executable)
index 0000000..1b230cd
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * This file is part of TpSession
+ *
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * Contact Kate Alhola  kate.alhola(a)nokia.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "tpsession.h"
+#include <QDebug>
+
+
+
+
+
+/**
+ * \class TpSession
+ * \headerfile <tpsession.h>
+ *
+ * Top level class, counterpart of Account Manager. TpSession connects to account manager and requests accounts from it. TpSession creates TpSessionAccount for all accounts .
+ * 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.
+ * 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
+ * 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.
+ */
+/**
+ * \fn void TpSession::accountReady(TpSessionAccount *);
+ *
+ * Emitted when the account becomes ready
+ *
+ * \param  TpSessionAccount  pointer to account become ready
+ */
+/**
+ * \fn void TpSession::amReady(TpSession *);
+ *
+ * Emitted when the account Manager becomes ready
+ *
+ * \param  TpSession  pointer to TpSession class
+ */
+/**
+ * \fn void TpSession::messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
+ *
+ * Emitted when any of Account Managers recived message
+ *
+ * \param  Tp::ReceivedMessage  Message received
+ * \param  TpSessionAccount  pointer to account received message
+ */
+
+
+/**
+ * Construct a new TpSession object.
+ *
+ * \param cmname      Name of the default connection manager. Can be empty or omnitted, then there is no default connection manager
+ * \param synchronous if false, asynchronous behavior, function returns immediately and accountReady signals are emitted when accounts are ready
+ *                    if True, synchronous behavior and function returns when accounts are ready
+ */
+TpSession::TpSession(QString cmname,bool synchronous)
+{
+    Tp::registerTypes();
+    Tp::enableDebug(false);
+    Tp::enableWarnings(false);
+
+    mAM = Tp::AccountManager::create();
+    reqCm=cmname;
+    sync=synchronous;
+    connect(mAM->becomeReady(),
+            SIGNAL(finished(Tp::PendingOperation *)),
+            SLOT(onAMReady(Tp::PendingOperation *)));
+    connect(mAM.data(),
+            SIGNAL(accountCreated(const QString &)),
+            SLOT(onAccountCreated(const QString &)));
+
+    // createObserver();
+    if(synchronous) loop.exec(); // Loop locally untill accounts are initialized
+    reqCm=cmname;
+
+}
+TpSession* TpSession::instancePtr=NULL;
+/**
+ * Returns pointer to TpSession singleton. If there is not yet TpSession Object, creates it with "Ring" connection manager as default
+ *
+ * \param synchronous if false, asynchronous behavior, function returns immediately and accountReady signals are emitted when accounts are ready
+ *                    if True, synchronous behavior and function returns when accounts are ready
+ */
+TpSession* TpSession::instance(bool synchronous)
+{
+    if(instancePtr==NULL) instancePtr=new TpSession("ring",synchronous);
+    return instancePtr;
+};
+
+void TpSession::onAMReady(Tp::PendingOperation *op)
+{
+    // qDebug() << "TpSession::onAMReady";
+    TpSessionAccount *tpacc;
+
+    Q_FOREACH (const QString &path, mAM->allAccountPaths()) {
+        accounts+=tpacc=new TpSessionAccount(mAM, path);
+        connect(tpacc,SIGNAL(accountReady(TpSessionAccount*)),
+                SLOT(onAccountReady(TpSessionAccount *)));
+    }
+
+}
+
+void TpSession::onReady(Tp::PendingOperation *)
+{
+};
+
+void TpSession::onAccountCreated(const QString &path)
+{
+
+    accounts+=new TpSessionAccount(mAM, path);
+}
+
+void TpSession::onAccountReady(TpSessionAccount *tpacc)
+{
+    qDebug() << "TpSession::onAccountReady:Account " << tpacc->acc->cmName() << "is Ready sync=" << sync << "waiting:" << reqCm;
+    connect(tpacc,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)),
+            SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)));
+    // Tom add
+    connect(tpacc,SIGNAL(messageSent(const Tp::Message &,TpSessionAccount *)),
+            SLOT(onMessageSent(const Tp::Message &,TpSessionAccount *)));
+    // Tom end
+    if(!reqCm.isEmpty() && tpacc->acc->cmName()==reqCm) {
+        if(sync) {
+            sync=false;
+            loop.quit();
+            qDebug() << "sync eventloop exit";
+        }
+        Q_EMIT accountReady(tpacc);
+        if(!reqMsg.isEmpty()) tpacc->sendMessageToAddress(reqAddress,reqMsg);
+    }
+}
+
+void TpSession::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionAccount *acc)
+{
+    //    qDebug() << "TestProg::onMessageReceived " << msg.text() << "from " << msg.sender()->id();
+    Q_EMIT messageReceived(msg,acc);
+}
+
+// Tom add
+void TpSession::onMessageSent(const Tp::Message &msg,TpSessionAccount *acc)
+{
+    //    qDebug() << "TpSession::onMessageSent " << msg.text() << "from " << msg.sender()->id();
+    Q_EMIT messageSent(msg,acc);
+}
+// Tom end
+
+/**
+ * Send message using specified connection manager to address
+ *
+ * \param connectionMgr  Name of the connection manager
+ * \param address Valid address for this connection manager type. Asexample telephone number to Ring, GoogleTalk address for Gabble
+ * \param message Message body
+ */
+void TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)
+{
+    qDebug() << "TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)";
+    TpSessionAccount *tpsa=getAccount(connectionMgr);
+    if(tpsa)
+    {
+        tpsa->sendMessageToAddress(address,message);
+    }
+}
+/**
+ * Returns pointer to TpSessionAccout object with specified connection manager or protocol, returns NULL if no match found
+ *
+ * \param cm  Name of the connection manager, or iniqueIdentifier (dbus path  to cm) if left empty matches every entry
+ * \param protocol Name of the protocol manager, if left empty matches every entry
+ */
+TpSessionAccount* TpSession::getAccount(const  QString cm,QString protocol)
+{
+    // qDebug() << "TpSession::getAccount" << cm << " " << protocol;
+    Q_FOREACH (TpSessionAccount *tpacc, accounts) {
+        if((!cm.isEmpty()  && ((tpacc->acc->cmName()==cm) || (tpacc->acc->uniqueIdentifier()==cm))) || (!protocol.isEmpty() && tpacc->acc->protocol()==protocol)) {
+            //     qDebug() << "TpSession::getAccount found" << tpacc->acc->cmName() << " " << tpacc->acc->protocol() << " " << tpacc->acc->uniqueIdentifier();
+            return tpacc;
+        }
+    }
+    return NULL;
+}
+
+void TpSession::createObserver()
+{
+
+    qDebug() << __PRETTY_FUNCTION__ ;
+
+    registrar = Tp::ClientRegistrar::create();
+
+    Tp::ChannelClassList channelFilters;
+    QMap<QString, QDBusVariant> textFilter, mediaFilter;
+    // Registering Text channel observer
+    textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
+                      QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT));
+    textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
+                      QDBusVariant(Tp::HandleTypeContact));
+    channelFilters.append(textFilter);
+
+    // Registering Media channel observer
+    mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
+                       QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA));
+    mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
+                       QDBusVariant(Tp::HandleTypeContact));
+    channelFilters.append(mediaFilter);
+
+    TpSessionObserver* observer = new TpSessionObserver( channelFilters, this );
+    bool registered = registrar->registerClient(
+            Tp::AbstractClientPtr::dynamicCast(Tp::SharedPtr<TpSessionObserver>(observer)),
+            "TpSessionChannelObserver");
+
+    //        qDebug() << "TpSession::createObserver" << (registered ? "started" : "failed");
+
+}
+
+
+void TpSession::createChannelListener(const QString &channelType,
+                                      const Tp::MethodInvocationContextPtr<> &context,
+                                      const Tp::AccountPtr &account,
+                                      const Tp::ChannelPtr &channel)
+{
+    qDebug() << "TpSession::createChannelListener";
+
+    QString channelObjectPath = channel->objectPath();
+
+
+    if ( channels.contains( channelObjectPath ) &&
+         !channelType.isEmpty() &&
+         !channelObjectPath.isEmpty() ) {
+        qDebug() << "TELEPATHY_ERROR_INVALID_ARGUMENT";
+        return;
+    }
+    qDebug() << "creating listener for: " << channelObjectPath << " type " << channelType;
+#if 0
+    ChannelListener* listener = 0;
+    if( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT ) {
+        listener = new TextChannelListener(account, channel, context);
+    } else if ( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA ) {
+        listener = new StreamChannelListener(account, channel, context);
+    }
+
+    if(listener) {
+        connect(listener, SIGNAL(channelClosed(ChannelListener *)),
+                this, SLOT(channelClosed(ChannelListener *)));
+        Channels.append( channelObjectPath );
+    }
+#endif
+}
+
+
+
+
+
+
+
+