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 +}