--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utilities/downloadmanager/src/omadownloadbackend.cpp Fri Oct 15 17:30:59 2010 -0400
@@ -0,0 +1,389 @@
+/**
+ 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 "omadownloadbackend.h"
+#include "omaddparser.h"
+#include "downloadmanager.h"
+#include "clientdownload.h"
+#include "downloadcore.h"
+#include "downloadevent.h"
+#include <QCoreApplication>
+#include <QFileInfo>
+
+#ifdef Q_OS_LINUX
+ #include <sys/statvfs.h>
+#endif
+
+#ifdef Q_OS_LINUX
+static double freeSpace(const char *path)
+#else
+static double freeSpace(const char* /*path*/)
+#endif
+{
+#ifdef Q_OS_LINUX
+ struct statvfs fiData;
+ if ((statvfs(path,&fiData)) < 0 )
+ return 0;
+ else {
+ int blockSize = fiData.f_bsize/1024;
+ double freeSize = (fiData.f_bavail)*blockSize;
+ freeSize = freeSize/1024;
+ return freeSize;
+ }
+#endif
+ return 0;
+}
+
+// private implementation
+class OMADownloadBackendPrivate {
+ DM_DECLARE_PUBLIC(OMADownloadBackend);
+public:
+ OMADownloadBackendPrivate();
+ ~OMADownloadBackendPrivate();
+
+ DownloadCore *m_downloadCore;
+ ClientDownload *m_download;
+ OMADownloadDescParser *m_parser; // for parsing oma descriptor
+ OMADownloadDescriptor *m_downloadDesc;
+ bool m_isMediaDownload; // flag to indicate if media download is happening
+ ClientDownload *m_mediaDownload; // not owned
+ bool m_isUserCancelled;
+};
+
+OMADownloadBackendPrivate::OMADownloadBackendPrivate()
+{
+ m_downloadCore = 0;
+ m_download = 0;
+ m_parser = 0;
+ m_downloadDesc = 0;
+ m_isMediaDownload = false;
+ m_mediaDownload = 0;
+ m_isUserCancelled = false;
+}
+
+OMADownloadBackendPrivate::~OMADownloadBackendPrivate()
+{
+ if (m_parser) {
+ delete m_parser;
+ m_parser = 0;
+ m_downloadDesc = 0;
+ }
+ if (m_mediaDownload) {
+ delete m_mediaDownload;
+ m_mediaDownload = NULL;
+ }
+}
+
+OMADownloadBackend::OMADownloadBackend(DownloadCore *dlCore, ClientDownload *dl)
+ :DownloadBackend(dlCore, dl)
+{
+ DM_INITIALIZE(OMADownloadBackend);
+ priv->m_downloadCore = dlCore;
+ priv->m_download = dl;
+}
+
+OMADownloadBackend::~OMADownloadBackend()
+{
+ DM_UNINITIALIZE(OMADownloadBackend);
+}
+
+int OMADownloadBackend::pause()
+{
+ DM_PRIVATE(OMADownloadBackend);
+ if (priv->m_isMediaDownload) {
+ priv->m_mediaDownload->pause();
+ setDownloadState(DlPaused);
+ }
+ return 0;
+}
+
+int OMADownloadBackend::resume()
+{
+ DM_PRIVATE(OMADownloadBackend);
+ priv->m_isUserCancelled = false;
+ if (priv->m_isMediaDownload)
+ return (priv->m_mediaDownload->resume());
+
+ // Ready to download after the descriptor is parsed
+ // capability check on the descriptor information
+ if (checkDownloadDescriptor()) {
+ // create download for media object
+ priv->m_mediaDownload = new ClientDownload(priv->m_download->downloadManager(),
+ priv->m_downloadDesc->getAttribute(OMADownloadDescObjectURI).toString(), priv->m_download->id());
+
+ if (!priv->m_mediaDownload) {
+ deleteInfo();
+ return -1;
+ }
+ priv->m_mediaDownload->setAttribute(DlFileName, priv->m_downloadDesc->getAttribute(OMADownloadDescName));
+ priv->m_mediaDownload->registerEventReceiver(this);
+ priv->m_mediaDownload->start();
+ priv->m_isMediaDownload = true;
+ deleteInfo();
+ return 0;
+ }
+ return -1;
+}
+
+int OMADownloadBackend::cancel()
+{
+ DM_PRIVATE(OMADownloadBackend);
+ priv->m_isUserCancelled = true;
+ if (priv->m_isMediaDownload)
+ priv->m_mediaDownload->cancel();
+ else
+ DownloadBackend::cancel();
+ return 0;
+}
+
+QVariant OMADownloadBackend::getAttribute(DownloadAttribute attr)
+{
+ DM_PRIVATE(OMADownloadBackend);
+ switch(attr) {
+ case OMADownloadDescriptorName:
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescName);
+ case OMADownloadDescriptorVersion:
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescVersion);
+ case OMADownloadDescriptorType:
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescType);
+ case OMADownloadDescriptorSize:
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescSize);
+ case OMADownloadDescriptorVendor:
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescVendor);
+ case OMADownloadDescriptorDescription:
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescDescription);
+
+ case DlFileName:
+ {
+ if (!priv->m_isMediaDownload) {
+ QString url = priv->m_downloadCore->url();
+ QFileInfo fileUrl(url);
+ return QVariant(fileUrl.fileName());
+ } else
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescName);
+ }
+ case DlContentType:
+ {
+ if (!priv->m_isMediaDownload)
+ return DownloadBackend::getAttribute(DlContentType);
+
+ else
+ return priv->m_mediaDownload->getAttribute(DlContentType);
+ }
+ default:
+ return DownloadBackend::getAttribute(attr);
+ }
+ return QVariant();
+}
+
+int OMADownloadBackend::setAttribute(DownloadAttribute attr, const QVariant& value)
+{
+ return DownloadBackend::setAttribute(attr, value);
+}
+
+// stores the data in storage
+void OMADownloadBackend::store(QByteArray /*data*/, bool /*lastChunk=false*/)
+{
+ return;
+}
+
+// deletes the storage
+void OMADownloadBackend::deleteStore()
+{
+ return;
+}
+
+// returns the size of stored data
+qint64 OMADownloadBackend::storedDataSize()
+{
+ return 0;
+}
+
+void OMADownloadBackend::bytesRecieved(qint64 /*bytesRecieved*/, qint64 /*bytesTotal*/)
+{
+ //Do nothing. This is here to avoid this signal to reach to base class' slot.
+ return;
+}
+
+void OMADownloadBackend::bytesUploaded(qint64 bytesUploaded, qint64 bytesTotal)
+{
+ DM_PRIVATE(OMADownloadBackend);
+ // once data is uploaded, cancel the transaction
+ if (bytesUploaded == bytesTotal)
+ priv->m_downloadCore->abort() ;
+}
+
+void OMADownloadBackend::handleFinished()
+{
+ DM_PRIVATE(OMADownloadBackend);
+ QString contentType = priv->m_downloadCore->contentType();
+ if (contentType == OMA_CONTENT_TYPE) {
+ bool bSucceeded = parseDownloadDescriptor();
+ if (bSucceeded) {
+ priv->m_downloadDesc = priv->m_parser->downloadDescriptor();
+
+ QString objectURI = priv->m_downloadDesc->getAttribute(OMADownloadDescObjectURI).toString();
+ if (objectURI.isEmpty()) {
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("905 Attribute Mismatch"));
+ priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
+ priv->m_downloadCore->setLastErrorString(tr("No ObjectURI"));
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ return;
+ }
+ setDownloadState(DlPaused);
+ postEvent(OMADownloadDescriptorReady, NULL);
+ } else {
+ priv->m_downloadDesc = priv->m_parser->downloadDescriptor();
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("906 Invalid descriptor"));
+ priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
+ priv->m_downloadCore->setLastErrorString(tr("Invalid Descriptor"));
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ }
+ }
+}
+
+bool OMADownloadBackend::parseDownloadDescriptor()
+{
+ DM_PRIVATE(OMADownloadBackend);
+ priv->m_parser = new OMADownloadDescParser();
+ QXmlInputSource source(priv->m_downloadCore->reply());
+ QXmlSimpleReader reader;
+ reader.setContentHandler(priv->m_parser);
+ reader.setErrorHandler(priv->m_parser);
+ return reader.parse(source);
+}
+
+// capability check on the descriptor
+bool OMADownloadBackend::checkDownloadDescriptor()
+{
+ DM_PRIVATE(OMADownloadBackend);
+
+ QString version = priv->m_downloadDesc->getAttribute(OMADownloadDescVersion).toString();
+ if (! version.isEmpty() && (version != OMA_VERSION_1)) {
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("951 Invalid DDVersion"));
+ priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
+ priv->m_downloadCore->setLastErrorString(tr("951 Invalid DDVersion"));
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ return false;
+ }
+
+#ifdef Q_OS_LINUX
+ // "Size" check needs to be done
+ double fileSize = priv->m_downloadDesc->getAttribute(OMADownloadDescSize).toDouble();
+ double mbFactor = 1024*1024;
+ fileSize = fileSize/mbFactor; //fileSize in MB
+ double spaceLeft = freeSpace(ROOT_PATH); //spaze left in MB
+
+ if (fileSize > spaceLeft) {
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("901 Insufficient memory"));
+ priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
+ priv->m_downloadCore->setLastErrorString(tr("901 Insufficient Memory"));
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ return false;
+ }
+#endif
+ return true;
+}
+
+bool OMADownloadBackend::event(QEvent *event)
+{
+ DM_PRIVATE(OMADownloadBackend);
+ DEventType type = (DEventType)event->type();
+ switch(type) {
+ case Started:
+ break;
+ case HeaderReceived:
+ {
+ // handling the events from media object downloads
+ // Check the mismatch in total size returned by server with the size given in the descriptor.
+ //This piece of code is commented as-of-now. when needed in future , will be uncommented
+ /*int totalSize = dl->getAttribute(DlTotalSize).toInt();
+ if (priv->m_downloadDesc->getAttribute(OMADownloadDescSize).toInt() != totalSize)
+ {
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("905 Attribute Mismatch"));
+
+ if (dl)
+ {
+ dl->setError("905 Attribute Mismatch");
+ dl->cancel();
+ dl->setDownloadState(DlFailed);
+ dl->postEvent(Error, NULL);
+ }
+ return true;
+ }*/
+ // Check the mismatch in content type returned by server with the content type given in the descriptor.
+ QString contentType = priv->m_mediaDownload->getAttribute(DlContentType).toString();
+ if (priv->m_downloadDesc->getAttribute(OMADownloadDescType).toString() != contentType) {
+ // media object download cannot be proceeded
+ if (priv->m_mediaDownload) {
+ priv->m_mediaDownload->setError("905 Attribute Mismatch");
+ priv->m_mediaDownload->cancel();
+ priv->m_mediaDownload->setDownloadState(DlFailed);
+ priv->m_mediaDownload->postEvent(Error, NULL);
+ }
+ break;
+ }
+ }
+ case Progress:
+ {
+ QVariant tSize = priv->m_mediaDownload->getAttribute(DlTotalSize);
+ setTotalSize(tSize.toInt());
+ QVariant curDlsize = priv->m_mediaDownload->getAttribute(DlDownloadedSize);
+ setDownloadedDataSize(curDlsize.toInt());
+ setDownloadState(DlInprogress);
+ postEvent(Progress, NULL);
+ break;
+ }
+ case NetworkLoss:
+ {
+ postEvent(NetworkLoss, NULL);
+ break;
+ }
+ case Cancelled:
+ {
+ if (priv->m_isUserCancelled)
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("902 User Cancelled"));
+ setDownloadState(DlCancelled);
+ postEvent(Cancelled, NULL);
+ break;
+ }
+ case Completed:
+ {
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("900 Success "));
+ setDownloadState(DlCompleted);
+ postEvent(Completed, NULL);
+ break;
+ }
+ case Error:
+ {
+ priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("905 Attribute Mismatch"));
+ priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
+ priv->m_downloadCore->setLastErrorString(tr("905 Attribute Mismatch"));
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ break;
+ }
+ default:
+ break;
+ }
+ return true;
+}
+
+