diff -r 6aeb7a756187 -r 3c88a81ff781 utilities/downloadmanager/src/omadownloadbackend.cpp --- /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 . +*/ + +#include "omadownloadbackend.h" +#include "omaddparser.h" +#include "downloadmanager.h" +#include "clientdownload.h" +#include "downloadcore.h" +#include "downloadevent.h" +#include +#include + +#ifdef Q_OS_LINUX + #include +#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; +} + +