utilities/downloadmanager/src/downloadmanagerclient.cpp
changeset 16 3c88a81ff781
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utilities/downloadmanager/src/downloadmanagerclient.cpp	Fri Oct 15 17:30:59 2010 -0400
@@ -0,0 +1,714 @@
+/**
+   This file is part of CWRT package **
+
+   Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). **
+
+   This program 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, version 2.1 of the License.
+   This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "downloadmanagerclient.h"
+#include "backgrounddownloadmanager.h"
+#include "backgrounddownload.h"
+#include <serviceipc.h>
+#include <QTimer>
+#include <QtNetwork>
+
+class DownloadManagerClientPrivate
+{
+    DM_DECLARE_PUBLIC(DownloadManagerClient);
+public:
+    DownloadManagerClientPrivate();
+    ~DownloadManagerClientPrivate();
+    QString m_clientName;
+    bool m_isConnected;
+    int m_error;
+    WRT::ServiceFwIPC* m_session;
+    DownloadManager* m_downloadManager;
+    QTimer* m_timer;
+};
+
+DownloadManagerClientPrivate::DownloadManagerClientPrivate()
+{
+    m_clientName = "";
+    m_isConnected = false;
+    m_error = 0;
+    m_session = 0;
+    m_downloadManager = 0;
+    m_timer = 0;
+}
+
+DownloadManagerClientPrivate::~DownloadManagerClientPrivate()
+{
+    if (m_timer) {
+        if (m_timer->isActive())
+            m_timer->stop();
+        delete m_timer;
+        m_timer = 0;
+    }
+
+    if (m_session) {
+        m_session->disconnect();
+        delete m_session;
+        m_session = 0;
+    }
+}
+
+DownloadManagerClient::DownloadManagerClient(DownloadManager* downloadManager)
+{
+    DM_INITIALIZE(DownloadManagerClient);
+    priv->m_downloadManager = downloadManager;
+    priv->m_timer = new QTimer;
+    priv->m_clientName = downloadManager->getAttribute(DlMgrClientName).toString();
+    priv->m_session = new WRT::ServiceFwIPC(this);
+    connect(priv->m_session, SIGNAL(error(int aError)), this, SLOT(setServerError(int error)));
+    connect(priv->m_timer, SIGNAL(timeout()), this, SLOT(getEvents()));
+
+    // establish communication with server
+    initServer();
+}
+
+DownloadManagerClient::~DownloadManagerClient()
+{
+    DM_UNINITIALIZE(DownloadManagerClient);
+}
+
+bool DownloadManagerClient::initServer()
+{
+    DM_PRIVATE(DownloadManagerClient);
+
+    // start server (if required) and connect to it
+    connectToServer();
+
+    if (priv->m_isConnected) {
+        // set startup details - proxy, download path, progress mode
+        // and attach to downloads
+        setStartupInfo();
+
+        // start timer to get events from server
+        priv->m_timer->start(EVENTS_REQUEST_INTERVAL);
+        priv->m_downloadManager->postEvent(ConnectedToServer, NULL);
+    }
+
+    return priv->m_isConnected;
+}
+
+bool DownloadManagerClient::connectToServer()
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (priv->m_session) {
+        int retry(2);
+        for (;;)
+        {
+            priv->m_isConnected = priv->m_session->connect(DMSERVER);
+            if (priv->m_isConnected) {
+                break;
+            }
+            else {
+                if (!priv->m_session->startServer(DMSERVER, DMSERVEREXE)) {
+                    // start server failed.
+                    break;
+                }
+            }
+            if (0==--retry) {
+                break;
+            }
+        }
+    }
+    if (!priv->m_isConnected) {
+        delete priv->m_session;
+        priv->m_session = 0;
+    }
+
+    return priv->m_isConnected;
+}
+
+void DownloadManagerClient::setStartupInfo()
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (!priv->m_isConnected)
+        return;
+
+    if (priv->m_downloadManager) {
+        // get data from download manager
+        QNetworkProxy* proxy = priv->m_downloadManager->proxy();
+        QString dlPath = priv->m_downloadManager->getAttribute(DlMgrDestPath).toString();
+        int progressMode = priv->m_downloadManager->getAttribute(DlMgrProgressMode).toInt();
+        int persistantMode = priv->m_downloadManager->getAttribute(DlMgrPersistantMode).toInt();
+        QString data;
+
+        // client name
+        data.append(encodeString(priv->m_clientName));
+
+        // proxy info
+        if (proxy) {
+            data.append(DM_MSG_DELIMITER);
+            data.append(QString::number(SetProxy));
+            data.append(DM_FIELD_DELIMITER);
+            data.append(encodeString(proxy->hostName()));
+            data.append(DM_FIELD_DELIMITER);
+            data.append(QString::number(proxy->port()));
+        }
+
+        // download path
+        data.append(DM_MSG_DELIMITER);
+        data.append(QString::number(SetDownloadManagerAttribute));
+        data.append(DM_FIELD_DELIMITER);
+        data.append(QString::number(DlMgrDestPath));
+        data.append(DM_FIELD_DELIMITER);
+        data.append(encodeString(dlPath));
+
+        // progress mode (quiet/non-quiet)
+        data.append(DM_MSG_DELIMITER);
+        data.append(QString::number(SetDownloadManagerAttribute));
+        data.append(DM_FIELD_DELIMITER);
+        data.append(QString::number(DlMgrProgressMode));
+        data.append(DM_FIELD_DELIMITER);
+        data.append(encodeString(QString::number(progressMode)));
+
+        // persistant mode (active / inactive)
+        data.append(DM_MSG_DELIMITER);
+        data.append(QString::number(SetDownloadManagerAttribute));
+        data.append(DM_FIELD_DELIMITER);
+        data.append(QString::number(DlMgrPersistantMode));
+        data.append(DM_FIELD_DELIMITER);
+        data.append(encodeString(QString::number(persistantMode)));
+
+        // send to sever
+        if (priv->m_session->sendSync(QString::number(StartupInfo), data.toAscii()))
+            priv->m_session->readAll();
+    }
+}
+
+void DownloadManagerClient::setProxy(const QString& proxyServer, const int port)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(encodeString(proxyServer));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(port));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(SetProxy), data.toAscii()))
+        priv->m_session->readAll();
+    else
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+}
+
+int DownloadManagerClient::createDownload(const QString& url, DownloadType type)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    int downloadId(INVALID_DL_ID);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return downloadId;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(encodeString(url));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(type));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(CreateDownload), data.toAscii())) {
+        // expected response is
+        // list[0] -> downloadId
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 1)
+            downloadId = list[0].toInt();
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return downloadId;
+}
+
+bool DownloadManagerClient::attachToDownload(int dlId)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    bool status(false);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return status;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(dlId));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(AttachToDownload), data.toAscii())) {
+        // expected response is
+	// list[1] -> status
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 1) {
+            status = list[0].toInt();
+	}
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+	
+    return status;
+}
+
+void DownloadManagerClient::removeDownload(int downloadId)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(downloadId));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(RemoveDownload), data.toAscii()))
+        priv->m_session->readAll();
+    else
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+}
+
+void DownloadManagerClient::pauseAll()
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(PauseAll), data.toAscii()))
+        priv->m_session->readAll();
+    else
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+}
+
+void DownloadManagerClient::resumeAll()
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(ResumeAll), data.toAscii()))
+        priv->m_session->readAll();
+    else
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+}
+
+void DownloadManagerClient::removeAll()
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(RemoveAll), data.toAscii()))
+        priv->m_session->readAll();
+    else
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+}
+
+QVariant DownloadManagerClient::getDownloadManagerAttribute(DownloadManagerAttribute attr)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    QVariant returnValue;
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(attr));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(GetDownloadManagerAttribute), data.toAscii())) {
+        // expected response is
+        // list[0] -> attribute
+        // list[1] -> value
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 2) {
+            if (list[0] == QString::number(attr))
+                returnValue = QVariant(list[1]);
+        }
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+int DownloadManagerClient::setDownloadManagerAttribute(DownloadManagerAttribute attr, const QVariant& value)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    int returnValue(-1);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(attr));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(encodeString(value.toString()));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(SetDownloadManagerAttribute), data.toAscii())) {
+        // expected response is
+        // list[0] -> attribute
+        // list[1] -> returnValue
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 2) {
+            if (list[0] == QString::number(attr))
+                returnValue = list[1].toInt();
+        }
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+int DownloadManagerClient::startDownload(int dlId)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    int returnValue(-1);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(dlId));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(StartDownload), data.toAscii())) {
+        // expected response is
+        // list[0] -> downloadId
+        // list[1] -> returnValue
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 2) {
+            if (list[0] == QString::number(dlId))
+                returnValue = list[1].toInt();
+        }
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+int DownloadManagerClient::pauseDownload(int dlId)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    int returnValue(-1);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(dlId));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(PauseDownload), data.toAscii())) {
+        // expected response is
+        // list[0] -> downloadId
+        // list[1] -> returnValue
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 2) {
+            if (list[0] == QString::number(dlId))
+                returnValue = list[1].toInt();
+        }
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+int DownloadManagerClient::resumeDownload(int dlId)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    int returnValue(-1);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(dlId));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(ResumeDownload), data.toAscii())) {
+        // expected response is
+        // list[0] -> downloadId
+        // list[1] -> returnValue
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 2) {
+            if (list[0] == QString::number(dlId))
+                returnValue = list[1].toInt();
+        }
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+int DownloadManagerClient::cancelDownload(int dlId)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    int returnValue(-1);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(dlId));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(CancelDownload), data.toAscii())) {
+        // expected response is
+        // list[0] -> downloadId
+        // list[1] -> returnValue
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 2) {
+            if (list[0] == QString::number(dlId))
+                returnValue = list[1].toInt();
+        }
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+QVariant DownloadManagerClient::getDownloadAttribute(int dlId, DownloadAttribute attr)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    QVariant returnValue;
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(dlId));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(attr));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(GetDownloadAttribute), data.toAscii())) {
+        // expected response is
+        // list[0] -> downloadId
+        // list[1] -> attribute
+        // list[2] -> value
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 3) {
+            if ((list[0] == QString::number(dlId)) &&
+                (list[1] == QString::number(attr)))
+                returnValue = QVariant(list[2]);
+        }
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+int DownloadManagerClient::setDownloadAttribute(int dlId, DownloadAttribute attr, const QVariant& value)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    int returnValue(-1);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return returnValue;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(dlId));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(QString::number(attr));
+    data.append(DM_FIELD_DELIMITER);
+    data.append(encodeString(value.toString()));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(SetDownloadAttribute), data.toAscii())) {
+        // expected response is
+        // list[0] -> downloadId
+        // list[1] -> attribute
+        // list[2] -> returnValue
+        QByteArray bytes = priv->m_session->readAll();
+        QStringList list = QString(bytes).split(DM_FIELD_DELIMITER);
+        if (list.count() == 3) {
+            if ((list[0] == QString::number(dlId)) &&
+                (list[1] == QString::number(attr)))
+                returnValue = list[2].toInt();
+        }
+    }
+    else
+    {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+    return returnValue;
+}
+
+// poll server for events
+void DownloadManagerClient::getEvents()
+{
+    DM_PRIVATE(DownloadManagerClient);
+    if (!priv->m_isConnected) {
+        if (!initServer())
+            return;
+    }
+
+    // create string to send
+    QString data;
+    data.append(encodeString(priv->m_clientName));
+
+    // send to sever
+    if (priv->m_session->sendSync(QString::number(GetEvents), data.toAscii())) {
+        // expected response has a list of downloadmanager and download events
+        QString eventMsg = priv->m_session->readAll();
+        if (!eventMsg.isEmpty())
+            processEvents(eventMsg);
+
+        // start timer for getting next set of events
+        priv->m_timer->start(EVENTS_REQUEST_INTERVAL);
+    }
+    else {
+        setServerError(WRT::ServiceFwIPC::EIPCError);
+    }
+}
+
+// process Download and DownloadManager events
+void DownloadManagerClient::processEvents(QString eventMsg)
+{
+    DM_PRIVATE(DownloadManagerClient);
+
+    // Separate out the fields of an event
+    QStringList list = eventMsg.split(DM_FIELD_DELIMITER);
+    if (list.count() >= 2) {
+        QString eventName = list[0];
+        // // check type of event
+        if (list[0] == QString::number(EventDownloadManager)) {
+            // Download Manager event
+            DEventType type = (DEventType)list[1].toInt();
+            // post event
+            priv->m_downloadManager->postEvent(type, NULL);
+        }
+        else if (list[0] == QString::number(EventDownload)) {
+            // Download event
+            int dlId = list[1].toInt();
+            DEventType type = (DEventType)list[2].toInt();
+            BackgroundDownload* dl = dynamic_cast<BackgroundDownload*>(priv->m_downloadManager->findDownload(dlId));
+            // post event
+            if (dl)
+                dl->postEvent(type, NULL);
+        }
+    }
+}
+
+// encode string so that it does not contain any communication delimiter
+QString DownloadManagerClient::encodeString(const QString& inputString)
+{
+    QByteArray bytes = QUrl::toPercentEncoding(inputString);
+    return bytes.data();
+}
+
+// get server connection/communication error
+int DownloadManagerClient::serverError()
+{
+    DM_PRIVATE(DownloadManagerClient);
+    return priv->m_error;
+}
+
+// set server IPC error
+void DownloadManagerClient::setServerError(int error)
+{
+    DM_PRIVATE(DownloadManagerClient);
+    priv->m_error = error;
+    // client could have died
+    // mark client as disconnected so that it can reconnect again
+    priv->m_isConnected = false;
+    if (priv->m_timer->isActive())
+        priv->m_timer->stop();
+    priv->m_downloadManager->postEvent(DisconnectedFromServer, NULL);
+    priv->m_downloadManager->postEvent(ServerError, NULL);
+}