diff -r 6aeb7a756187 -r 3c88a81ff781 utilities/downloadmanager/src/oma2downloadbackend.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utilities/downloadmanager/src/oma2downloadbackend.cpp Fri Oct 15 17:30:59 2010 -0400
@@ -0,0 +1,723 @@
+/**
+ 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 "oma2downloadbackend.h"
+#include "omaddparser.h"
+#include "downloadmanager.h"
+#include "download.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 {
+ qint64 blockSize = fiData.f_bsize/1024;
+ qint64 freeSize = (fiData.f_bavail)*blockSize;
+ freeSize = freeSize/1024;
+ return freeSize;
+ }
+#endif
+ return 0;
+}
+
+// Constants
+const char* const SuppressUserConfirmation_Never = "Never";
+
+// private implementation
+class OMA2DownloadBackendPrivate {
+ DM_DECLARE_PUBLIC(OMA2DownloadBackend);
+public:
+ OMA2DownloadBackendPrivate();
+ ~OMA2DownloadBackendPrivate();
+ 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
+ MediaDownloadList m_mediaDownloadList; // media downloads
+ int m_currDownloadIndex;
+ int m_currProductIndex;
+ qint64 m_dlCompletedSize;
+ QMap m_mediaObjIdStateMap; // map to have the list of Media Objects' id and it's state.
+ QList m_childIds;
+ OMA2DownloadProduct *m_currProduct;
+ OMA2DownloadMediaObj *m_currMediaObj;
+};
+
+OMA2DownloadBackendPrivate::OMA2DownloadBackendPrivate():m_downloadCore(0)
+ ,m_download(0)
+ ,m_parser(0)
+ ,m_downloadDesc(0)
+ ,m_isMediaDownload(false)
+ ,m_currDownloadIndex(-1)
+ ,m_currProductIndex(0)
+ ,m_dlCompletedSize(0)
+{ }
+
+OMA2DownloadBackendPrivate::~OMA2DownloadBackendPrivate()
+{
+ if (m_parser) {
+ delete m_parser;
+ m_parser = 0;
+ m_downloadDesc = 0;
+ }
+ // In case of persistent storage
+ if (m_downloadDesc) {
+ delete m_downloadDesc;
+ m_downloadDesc = 0;
+ }
+
+ int count = m_mediaDownloadList.count();
+ for (int i = 0; i < count; i++)
+ delete m_mediaDownloadList[i];
+}
+
+OMA2DownloadBackend::OMA2DownloadBackend(DownloadCore *dlCore, ClientDownload *dl)
+ :DownloadBackend(dlCore, dl)
+{
+ DM_INITIALIZE(OMA2DownloadBackend);
+ priv->m_downloadCore = dlCore;
+ priv->m_download = dl;
+}
+
+OMA2DownloadBackend::~OMA2DownloadBackend()
+{
+ DM_UNINITIALIZE(OMA2DownloadBackend);
+}
+
+int OMA2DownloadBackend::pause()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ if (priv->m_isMediaDownload) {
+ priv->m_mediaDownloadList[priv->m_currDownloadIndex]->pause();
+ setDownloadState(DlPaused);
+ }
+ return 0;
+}
+
+int OMA2DownloadBackend::resume()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ if (priv->m_isMediaDownload)
+ return (priv->m_mediaDownloadList[priv->m_currDownloadIndex]->resume());
+
+ // Ready to download after the descriptor is parsed
+ // capability check on the descriptor information
+ if (checkDownloadDescriptor()) {
+ ProductList product = priv->m_downloadDesc->productList();
+ int count = product[priv->m_currProductIndex]->mediaCount();
+
+ for (int i=0; i < count; i++) {
+ QUrl baseUrl = priv->m_downloadCore->url();
+ QUrl relativeUrl = product[priv->m_currProductIndex]->mediaObjList()[i]->getAttribute(OMA2DownloadDescMediaObjServer).toString();
+ QString url = baseUrl.resolved(relativeUrl).toString();
+ // create download for media object
+ // id's of media downloads are unique under its parent oma download
+ ClientDownload *dl = new ClientDownload(priv->m_download->downloadManager(), url, (i+1), Parallel
+ , priv->m_download->id() );
+ if (NULL == dl)
+ return -1;
+ // functions for persistent storage
+ serializeData(dl, i);
+ setValueForChild(DownloadInfo::EUrl, url, dl->id());
+ setValueForChild(DownloadInfo::EDlState, DlCreated, dl->id());
+ long state;
+ getValue(DownloadInfo::EDlState, state);
+ priv->m_mediaObjIdStateMap[dl->id()] = state;
+ addtoDownloadList(dl);
+ }
+ setValue(DownloadInfo::EChildIdList, priv->m_childIds);
+ qint64 tSize = product[priv->m_currProductIndex]->albumSize();
+ setTotalSize(tSize);
+ priv->m_currDownloadIndex = 0;
+ priv->m_mediaDownloadList[priv->m_currDownloadIndex]->start();
+ priv->m_isMediaDownload = true;
+ return 0;
+ }
+ return -1;
+}
+
+int OMA2DownloadBackend::cancel()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ if (priv->m_isMediaDownload)
+ priv->m_mediaDownloadList[priv->m_currDownloadIndex]->cancel();
+ else
+ DownloadBackend::cancel();
+ return 0;
+}
+
+QVariant OMA2DownloadBackend::getAttribute(DownloadAttribute attr)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ // moIndex is zero because when product name is empty the name of 0th Mediaobject should be shown in dd and also the type is of the 0th Mediaobject
+ const int moIndex = 0;
+ QString text = "";
+ ProductList product;
+ if (priv->m_downloadDesc)
+ product = priv->m_downloadDesc->productList();
+ switch(attr) {
+ case OMADownloadDescriptorName:
+ {
+ if (product[priv->m_currProductIndex]) {
+ QString name = product[priv->m_currProductIndex]->getAttribute(OMA2DownloadDescProductName).toString();
+ if (!name.isEmpty())
+ return name;
+ if (product[priv->m_currProductIndex]->mediaCount() > 0)
+ return product[priv->m_currProductIndex]->mediaObjList()[moIndex]->getAttribute(OMA2DownloadDescMediaObjName);
+ return text;
+ }
+ return text;
+ }
+
+ case OMADownloadDescriptorType:
+ {
+ if (product[priv->m_currProductIndex]) {
+ if (product[priv->m_currProductIndex]->mediaCount() > 0)
+ return product[priv->m_currProductIndex]->mediaObjList()[moIndex]->getAttribute(OMA2DownloadDescMediaObjType);
+ return text;
+ }
+ return text;
+ }
+
+ case OMADownloadDescriptorSize:
+ {
+ qint64 size = 0;
+ if (product[priv->m_currProductIndex])
+ return product[priv->m_currProductIndex]->albumSize();
+ return size;
+ }
+
+ case OMADownloadDescriptorNextURL:
+ {
+ return priv->m_downloadDesc->getAttribute(OMADownloadDescNextURL);
+ }
+
+ case DlFileName:
+ {
+ if (!priv->m_isMediaDownload) {
+ QString url = priv->m_downloadCore->url();
+ QFileInfo fileUrl(url);
+ return QVariant(fileUrl.fileName());
+ }
+ // If the product tag doesn't have a name then display the media object's name in the download list.
+ // This is helpful for single OMA2 download and is done for better user readability
+ if (product[priv->m_currProductIndex]) {
+ QString name = product[priv->m_currProductIndex]->getAttribute(OMA2DownloadDescProductName).toString();
+ if (!name.isEmpty())
+ return name;
+ if (product[priv->m_currProductIndex]->mediaCount() > 0)
+ return product[priv->m_currProductIndex]->mediaObjList()[priv->m_currDownloadIndex]->getAttribute(OMA2DownloadDescMediaObjName);
+ return text;
+ }
+ return text;
+ }
+
+ case DlContentType:
+ {
+ if (!priv->m_isMediaDownload)
+ return DownloadBackend::getAttribute(DlContentType);
+ QString contentType = priv->m_mediaDownloadList[priv->m_currDownloadIndex]->getAttribute(DlContentType).toString();
+ if (contentType != "")
+ return contentType;
+ QString mediaObjContentType;
+ getValueForChild(DownloadInfo::EContentType, mediaObjContentType, priv->m_childIds[priv->m_currDownloadIndex].toInt());
+ return mediaObjContentType;
+ }
+
+ default:
+ return DownloadBackend::getAttribute(attr);
+ }
+ return QVariant();
+}
+
+int OMA2DownloadBackend::setAttribute(DownloadAttribute attr, const QVariant& value)
+{
+ return DownloadBackend::setAttribute(attr, value);
+}
+
+// stores the data in storage
+void OMA2DownloadBackend::store(QByteArray /*data*/, bool /*lastChunk=false*/)
+{
+ return;
+}
+
+// deletes the storage
+void OMA2DownloadBackend::deleteStore()
+{
+ return;
+}
+
+// returns the size of stored data
+qint64 OMA2DownloadBackend::storedDataSize()
+{
+ return 0;
+}
+
+void OMA2DownloadBackend::bytesRecieved(qint64 /*bytesRecieved*/, qint64 /*bytesTotal*/)
+{
+ //Do nothing. This is here to avoid this signal to reach to base class' slot.
+ return;
+}
+
+void OMA2DownloadBackend::bytesUploaded(qint64 bytesUploaded, qint64 bytesTotal)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ // once data is uploaded, cancel the transaction
+ if (bytesUploaded == bytesTotal)
+ priv->m_downloadCore->abort() ;
+
+}
+
+void OMA2DownloadBackend::handleFinished()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ QString contentType = priv->m_downloadCore->contentType();
+ if (contentType == OMA2_CONTENT_TYPE) {
+ bool bSucceeded = parseDownloadDescriptor();
+ priv->m_downloadDesc = priv->m_parser->downloadDescriptor();
+ if (bSucceeded) {
+ ProductList product = priv->m_downloadDesc->productList();
+ int count = product[priv->m_currProductIndex]->mediaCount();
+ if (count == 0) {
+ 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);
+ return;
+ }
+ for (int i=0; i < count; i++) {
+ QString server = product[priv->m_currProductIndex]->mediaObjList()[i]->getAttribute(OMA2DownloadDescMediaObjServer).toString();
+ QString size = product[priv->m_currProductIndex]->mediaObjList()[i]->getAttribute(OMA2DownloadDescMediaObjSize).toString();
+ QString type = product[priv->m_currProductIndex]->mediaObjList()[i]->getAttribute(OMA2DownloadDescMediaObjType).toString();
+ if (server.isEmpty() || size.isEmpty() || type.isEmpty()) {
+ QString string;
+ string = product[priv->m_currProductIndex]->mediaObjList()[i]->getAttribute(OMA2DownloadDescMediaObjInstallNotifyURI).toString();
+ priv->m_downloadCore->post(string, QByteArray("905 Attribute Mismatch"));
+ priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
+ priv->m_downloadCore->setLastErrorString(tr("Invalid Descriptor"));
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ return;
+ }
+ }
+ // if download is restarted OR suppressUserConfirmation is true, do not show descriptor
+ if (suppressUserConfirmation() || (DlDescriptorUpdated == downloadState())) {
+ resume();
+ } else {
+ setDownloadState(DlPaused);
+ postEvent(OMADownloadDescriptorReady, NULL);
+ }
+ } else {
+ 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 OMA2DownloadBackend::parseDownloadDescriptor()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ 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 OMA2DownloadBackend::checkDownloadDescriptor()
+{
+#ifdef Q_OS_LINUX
+ DM_PRIVATE(OMA2DownloadBackend);
+ ProductList product = priv->m_downloadDesc->productList();
+ double fileSize = product[priv->m_currProductIndex]->albumSize();
+ 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 OMA2DownloadBackend::event(QEvent *event)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ ProductList product = priv->m_downloadDesc->productList();
+ DownloadEvent* downloadEvent = dynamic_cast(event);
+ DEventType type = (DEventType)event->type();
+ switch(type) {
+ case Started:
+ break;
+ case HeaderReceived:
+ {
+ int dlId = ((DownloadEvent*)event)->getId();
+ if (downloadEvent) {
+ int statusCode = downloadEvent->getAttribute(HeaderReceivedStatusCode).toInt();
+ handleStatusCode(statusCode);
+ }
+ ClientDownload *dl = findDownload(dlId);
+ // 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
+ /*qint64 totalSize = dl->getAttribute(DlTotalSize).toInt();
+ if(product[priv->m_currProductIndex]->mediaObjList()[priv->m_currDownloadIndex]->getAttribute(OMA2DownloadDescMediaObjSize).toInt() != totalSize) {
+ postInstallNotifyEvent("905 Attribut Mismatch");
+ priv->m_mediaObjIdStateMap[downloadEvent->getId()] = DlFailed;
+ } */
+ // Check the mismatch in content type returned by server with the content type given in the descriptor.
+ QString contentType = dl->getAttribute(DlContentType).toString();
+ if(product[priv->m_currProductIndex]->mediaObjList()[priv->m_currDownloadIndex]->getAttribute(OMA2DownloadDescMediaObjType).toString() != contentType) {
+ postInstallNotifyEvent("905 Attribute Mismatch");
+ priv->m_mediaObjIdStateMap[downloadEvent->getId()] = DlFailed;
+ if (priv->m_currDownloadIndex < product[priv->m_currProductIndex]->mediaCount()-1) {
+ priv->m_currDownloadIndex++;
+ priv->m_mediaDownloadList[priv->m_currDownloadIndex]->start();
+ }
+ }
+ break;
+ }
+
+ case Progress:
+ {
+ QVariant curDlsize = priv->m_mediaDownloadList[priv->m_currDownloadIndex]->getAttribute(DlDownloadedSize);
+ qint64 currentDlSize = priv->m_dlCompletedSize + (curDlsize.toInt());
+ setDownloadedDataSize(currentDlSize);
+ setDownloadState(DlInprogress);
+ priv->m_mediaObjIdStateMap[downloadEvent->getId()] = DlInprogress;
+ setValueForChild(DownloadInfo::EDlState, DlInprogress, downloadEvent->getId());
+ postEvent(Progress, NULL);
+ break;
+ }
+ case Paused:
+ {
+ setDownloadState(DlPaused);
+ priv->m_mediaObjIdStateMap[downloadEvent->getId()] = DlPaused;
+ setValueForChild(DownloadInfo::EDlState, DlPaused, downloadEvent->getId());
+ postEvent(Paused, NULL);
+ break;
+ }
+ case NetworkLoss:
+ {
+ postEvent(NetworkLoss, NULL);
+ break;
+ }
+ case Cancelled:
+ {
+ postInstallNotifyEvent("902 User Cancelled");
+ priv->m_mediaObjIdStateMap[downloadEvent->getId()] = DlCancelled;
+ setValueForChild(DownloadInfo::EDlState, DlCancelled, downloadEvent->getId());
+ setDownloadState(DlCancelled);
+ postEvent(Cancelled, NULL);
+ break;
+ }
+ case Completed:
+ {
+ postInstallNotifyEvent("900 Success");
+ priv->m_mediaObjIdStateMap[downloadEvent->getId()] = DlCompleted;
+ setValueForChild(DownloadInfo::EDlState, DlCompleted, downloadEvent->getId());
+ QVariant curDlsize = priv->m_mediaDownloadList[priv->m_currDownloadIndex]->getAttribute(DlDownloadedSize);
+ priv->m_dlCompletedSize = priv->m_dlCompletedSize + (curDlsize.toInt());
+ if (priv->m_currDownloadIndex < product[priv->m_currProductIndex]->mediaCount()-1) {
+ priv->m_currDownloadIndex++;
+ priv->m_mediaDownloadList[priv->m_currDownloadIndex]->start();
+ } else if (priv->m_currDownloadIndex == product[priv->m_currProductIndex]->mediaCount()-1)
+ verifyDownloads();
+ break;
+ }
+ case Error:
+ {
+ priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
+ priv->m_downloadCore->setLastErrorString(tr("905 Attribute Mismatch"));
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ priv->m_mediaObjIdStateMap[downloadEvent->getId()] = DlFailed;
+ setValueForChild(DownloadInfo::EDlState, DlFailed, downloadEvent->getId());
+ break;
+ }
+ default:
+ break;
+ }
+ return true;
+}
+
+void OMA2DownloadBackend::getChildren(QList& list)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ for (int i = 0; i < priv->m_mediaDownloadList.count(); i++)
+ list.append(priv->m_mediaDownloadList[i]);
+
+}
+
+bool OMA2DownloadBackend::suppressUserConfirmation()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+
+ ProductList productList = priv->m_downloadDesc->productList();
+ QString suppressValue = productList[priv->m_currProductIndex]->getAttribute(OMA2DownloadDescProductSuppressConfirmation).toString();
+ QString suppressUserConfirmNever(SuppressUserConfirmation_Never);
+
+ // If suppressUserConfirmation attribute is present for Product tag, use it and don't check media objects
+ // for this attribute
+ if (!suppressValue.isEmpty()) {
+ if (suppressValue == suppressUserConfirmNever)
+ return false;
+ return true;
+ }
+
+ int mediaCount = productList[priv->m_currProductIndex]->mediaCount();
+ // If suppressUserConfirmation is present and it is NOT "Never" for even a single media object,
+ // then treat this as true and do not display user confirmation.
+ QString suppressConfirmMediaObj = "";
+
+ for (int i=0; im_currProductIndex]->mediaObjList()[i]->getAttribute(OMA2DownloadDescMediaObjSuppressConfirmation).toString();
+ if (!suppressValue.isEmpty()) {
+ // Check if two or more mediObjects have different values for this attribute.
+ // If so, then this is an invalid case. Hence we ignore this attribute.
+ if (suppressConfirmMediaObj.isEmpty())
+ suppressConfirmMediaObj = suppressValue;
+ else if (suppressConfirmMediaObj != suppressValue) {
+ // Two mediaObjects have different values of suppressUserConfirmation attribute.
+ // Ignore this attribute.
+ return false;
+ }
+ }
+ }
+
+ // If string is empty OR its value is "Never", return false.
+ if (suppressConfirmMediaObj.isEmpty() || (suppressConfirmMediaObj == suppressUserConfirmNever))
+ return false;
+
+ return true;
+}
+
+void OMA2DownloadBackend::handleStatusCode(const int& statusCode)
+{
+ HttpStatusCode status = (HttpStatusCode)statusCode;
+ switch(status) {
+ case HttpPreconditionFailed: // Precondition Failed
+ {
+ handlePreconditionFailed();
+ postEvent(DescriptorUpdated, NULL);
+ return;
+ }
+
+ default:
+ return;
+ }
+}
+
+void OMA2DownloadBackend::handlePreconditionFailed()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ QString updatedDDUri = priv->m_downloadDesc->getAttribute(OMA2DownloadDescUpdatedDDURI).toString();
+ if (updatedDDUri.isEmpty())
+ return;
+
+ DownloadManager* dlMgr = priv->m_download->downloadManager();
+ if (!dlMgr)
+ return;
+
+ // Delete all media objects
+ priv->m_isMediaDownload = false;
+ ProductList productList = priv->m_downloadDesc->productList();
+ int count = productList[priv->m_currProductIndex]->mediaCount();
+
+ // Remove all media objects
+ for(int i=0; im_mediaDownloadList[i];
+ QCoreApplication::removePostedEvents(this);
+ dl->unregisterEventReceiver(this);
+ priv->m_mediaDownloadList.removeOne(dl);
+ dlMgr->removeOne(dl);
+ }
+
+ // start download of updated DD
+ priv->m_downloadCore->changeUrl(updatedDDUri);
+ priv->m_downloadCore->doDownload();
+ setDownloadState(DlDescriptorUpdated);
+}
+
+void OMA2DownloadBackend::addtoDownloadList(ClientDownload* dl)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ dl->registerEventReceiver(this);
+ priv->m_childIds.append(dl->id());
+ priv->m_mediaDownloadList.append(dl);
+}
+
+ClientDownload* OMA2DownloadBackend::findDownload(int id)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ for (int i = 0; i < priv->m_mediaDownloadList.size(); ++i) {
+ if (priv->m_mediaDownloadList[i]->id() == id)
+ return priv->m_mediaDownloadList[i];
+ }
+ return 0;
+}
+
+void OMA2DownloadBackend::postInstallNotifyEvent(const char* statusMessage)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ ProductList product = priv->m_downloadDesc->productList();
+ QString string;
+ string = product[priv->m_currProductIndex]->mediaObjList()[priv->m_currDownloadIndex]->getAttribute(OMA2DownloadDescMediaObjInstallNotifyURI).toString();
+ priv->m_downloadCore->post(string, QByteArray(statusMessage));
+}
+
+void OMA2DownloadBackend::verifyDownloads()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ // go throught the mediaObjmap of id, state value pair and if any dl is failed then set the state of parent as paused.
+ ProductList product = priv->m_downloadDesc->productList();
+ int counter = 0;
+ for (int i=0; i < priv->m_childIds.count(); i++) {
+ if (priv->m_mediaObjIdStateMap[priv->m_childIds[i].toInt()] == DlCompleted)
+ counter++;
+ else if (priv->m_mediaObjIdStateMap[priv->m_childIds[i].toInt()] == DlFailed) {
+ setDownloadState(DlFailed);
+ postEvent(Error, NULL);
+ break;
+ }
+ }
+ if (counter == priv->m_childIds.count()) {
+ setDownloadState(DlCompleted);
+ postEvent(Completed, NULL);
+ }
+}
+
+int OMA2DownloadBackend::currentIndex()
+{
+ // If a download is in progress and closed, a track in an album is either paused or created.
+ // This function as part of persistant storage,returns the index of the download which is either in paused or created state
+ DM_PRIVATE(OMA2DownloadBackend);
+ ProductList product = priv->m_downloadDesc->productList();
+ for (int i=0; i < priv->m_childIds.count(); i++) {
+ if (priv->m_mediaObjIdStateMap[priv->m_childIds[i].toInt()] == DlPaused
+ || priv->m_mediaObjIdStateMap[priv->m_childIds[i].toInt()] == DlCreated) {
+ priv->m_currDownloadIndex = i;
+ break;
+ }
+ }
+ return priv->m_currDownloadIndex;
+}
+
+void OMA2DownloadBackend::init()
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ priv->m_isMediaDownload = true; // since init() is called during restoring the persistent info, the flag should be set to true.
+
+ priv->m_downloadDesc = new OMADownloadDescriptor();
+ priv->m_currProduct = new OMA2DownloadProduct();
+ priv->m_downloadDesc->addProduct(priv->m_currProduct);
+ // populating the product map
+ QString productName;
+ getValue(DownloadInfo::EFileName, productName);
+ priv->m_currProduct->setAttribute("name", QVariant(productName));
+
+ QList id;
+ getValue(DownloadInfo::EChildIdList, id);
+ QString oma2ContentType,mediaObjName,mediaObjUrl,mediaObjContentType;
+ long mediaObjSize;
+ long state;
+ priv->m_currProductIndex = 0;
+ for(int i=0; im_currMediaObj = new OMA2DownloadMediaObj();
+ priv->m_currProduct->addMediaObject(priv->m_currMediaObj);
+
+ // getting all the values related to media object for populating descriptor's mediaobj map
+ getValueForChild(DownloadInfo::EFileName, mediaObjName, id[i].toInt());
+ getValueForChild(DownloadInfo::ETotalSize, mediaObjSize, id[i].toInt());
+ getValueForChild(DownloadInfo::EUrl, mediaObjUrl, id[i].toInt());
+ getValueForChild(DownloadInfo::EContentType, mediaObjContentType, id[i].toInt());
+ getValueForChild(DownloadInfo::EDlState, state, id[i].toInt());
+ priv->m_mediaObjIdStateMap[id[i].toInt()] = state;
+
+ // creaating downloads for the media objects
+ ClientDownload *dl = NULL;
+ if (state == DlCreated) {
+ dl = new ClientDownload(priv->m_download->downloadManager(), mediaObjUrl, id[i].toInt(), Parallel
+ , priv->m_download->id() );
+ }
+ else
+ dl = new ClientDownload(priv->m_download->downloadManager(), id[i].toInt(), priv->m_download->id());
+
+ setValueForChild(DownloadInfo::EDlState, priv->m_mediaObjIdStateMap[id[i].toInt()], id[i].toInt());
+ addtoDownloadList(dl);
+ // re-constructing descriptor's mediaobj map
+ priv->m_currMediaObj->setAttribute("name", QVariant(mediaObjName));
+ int size = mediaObjSize;
+ priv->m_currMediaObj->setAttribute("size", QVariant(size));
+ priv->m_currMediaObj->setAttribute("type", QVariant(mediaObjContentType));
+ priv->m_currMediaObj->setAttribute("server",QVariant(mediaObjUrl));
+ }
+ ProductList product = priv->m_downloadDesc->productList();
+ getValue(DownloadInfo::EDlState,state);
+ if(state == DlCompleted)
+ priv->m_currDownloadIndex = product[priv->m_currProductIndex]->mediaCount()-1;
+ else
+ priv->m_currDownloadIndex = currentIndex();
+}
+
+void OMA2DownloadBackend::serializeData(ClientDownload* dl, int index)
+{
+ DM_PRIVATE(OMA2DownloadBackend);
+ ProductList product = priv->m_downloadDesc->productList();
+ // set OMA2 parent values in QSettings.
+ QString productName = product[priv->m_currProductIndex]->getAttribute(OMA2DownloadDescProductName).toString(); // contenttype,url being written in dlbackend's constructor
+ setValue(DownloadInfo::EFileName, productName);
+
+ // set minimal MediaObject attributes in QSettings like name, size, url and contentType as these are the ones required for persistent storage.
+ QString mediaObjName = product[priv->m_currProductIndex]->mediaObjList()[index]->getAttribute(OMA2DownloadDescMediaObjName).toString();
+ setValueForChild(DownloadInfo::EFileName, mediaObjName, dl->id());
+ long mediaObjSize = product[priv->m_currProductIndex]->mediaObjList()[index]->getAttribute(OMA2DownloadDescMediaObjSize).toInt();
+ setValueForChild(DownloadInfo::ETotalSize, mediaObjSize, dl->id());
+ QString mediaObjContentType = product[priv->m_currProductIndex]->mediaObjList()[index]->getAttribute(OMA2DownloadDescMediaObjType).toString();
+ setValueForChild(DownloadInfo::EContentType, mediaObjContentType, dl->id());
+ QString destPath = (download()->attributes().value(DlDestPath)).toString();
+ setValueForChild(DownloadInfo::EFinalPath, destPath, dl->id());
+ setValueForChild(DownloadInfo::EETag, priv->m_downloadCore->entityTag(), dl->id()); //not getting set check later
+}