utilities/downloadmanager/src/omadownloadbackend.cpp
changeset 16 3c88a81ff781
equal deleted inserted replaced
14:6aeb7a756187 16:3c88a81ff781
       
     1 /**
       
     2    This file is part of CWRT package **
       
     3 
       
     4    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). **
       
     5 
       
     6    This program is free software: you can redistribute it and/or modify
       
     7    it under the terms of the GNU (Lesser) General Public License as 
       
     8    published by the Free Software Foundation, version 2.1 of the License. 
       
     9    This program is distributed in the hope that it will be useful, but
       
    10    WITHOUT ANY WARRANTY; without even the implied warranty of 
       
    11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
       
    12    (Lesser) General Public License for more details. You should have 
       
    13    received a copy of the GNU (Lesser) General Public License along 
       
    14    with this program. If not, see <http://www.gnu.org/licenses/>.
       
    15 */
       
    16 
       
    17 #include "omadownloadbackend.h"
       
    18 #include "omaddparser.h"
       
    19 #include "downloadmanager.h"
       
    20 #include "clientdownload.h"
       
    21 #include "downloadcore.h"
       
    22 #include "downloadevent.h"
       
    23 #include <QCoreApplication>
       
    24 #include <QFileInfo>
       
    25 
       
    26 #ifdef Q_OS_LINUX
       
    27   #include <sys/statvfs.h>
       
    28 #endif
       
    29 
       
    30 #ifdef Q_OS_LINUX 
       
    31 static double freeSpace(const char *path)
       
    32 #else
       
    33 static double freeSpace(const char* /*path*/)
       
    34 #endif
       
    35 {
       
    36 #ifdef Q_OS_LINUX   
       
    37     struct statvfs fiData;
       
    38     if ((statvfs(path,&fiData)) < 0 ) 
       
    39         return 0;
       
    40     else {
       
    41         int blockSize = fiData.f_bsize/1024;
       
    42         double freeSize = (fiData.f_bavail)*blockSize;
       
    43         freeSize = freeSize/1024;
       
    44         return freeSize;
       
    45     }
       
    46 #endif
       
    47     return 0;
       
    48 }
       
    49 
       
    50 // private implementation
       
    51 class OMADownloadBackendPrivate {
       
    52     DM_DECLARE_PUBLIC(OMADownloadBackend);
       
    53 public:
       
    54     OMADownloadBackendPrivate();
       
    55     ~OMADownloadBackendPrivate();
       
    56 
       
    57     DownloadCore *m_downloadCore;
       
    58     ClientDownload *m_download;
       
    59     OMADownloadDescParser *m_parser; // for parsing oma descriptor
       
    60     OMADownloadDescriptor *m_downloadDesc;
       
    61     bool m_isMediaDownload; // flag to indicate if media download is happening
       
    62     ClientDownload *m_mediaDownload; // not owned
       
    63     bool m_isUserCancelled;
       
    64 };
       
    65 
       
    66 OMADownloadBackendPrivate::OMADownloadBackendPrivate()
       
    67 {
       
    68     m_downloadCore = 0;
       
    69     m_download = 0;
       
    70     m_parser = 0;
       
    71     m_downloadDesc = 0;
       
    72     m_isMediaDownload = false;
       
    73     m_mediaDownload = 0;
       
    74     m_isUserCancelled = false;
       
    75 }
       
    76 
       
    77 OMADownloadBackendPrivate::~OMADownloadBackendPrivate()
       
    78 {
       
    79     if (m_parser) {
       
    80         delete m_parser;
       
    81         m_parser = 0;
       
    82         m_downloadDesc = 0;
       
    83     }
       
    84     if (m_mediaDownload) {
       
    85         delete m_mediaDownload;
       
    86         m_mediaDownload = NULL;
       
    87     }
       
    88 }
       
    89 
       
    90 OMADownloadBackend::OMADownloadBackend(DownloadCore *dlCore, ClientDownload *dl)
       
    91     :DownloadBackend(dlCore, dl)
       
    92 {
       
    93     DM_INITIALIZE(OMADownloadBackend);
       
    94     priv->m_downloadCore = dlCore;
       
    95     priv->m_download = dl;
       
    96 }
       
    97 
       
    98 OMADownloadBackend::~OMADownloadBackend()
       
    99 {
       
   100      DM_UNINITIALIZE(OMADownloadBackend);
       
   101 }
       
   102 
       
   103 int OMADownloadBackend::pause()
       
   104 {
       
   105     DM_PRIVATE(OMADownloadBackend);
       
   106     if (priv->m_isMediaDownload) {
       
   107         priv->m_mediaDownload->pause();
       
   108         setDownloadState(DlPaused);
       
   109     }
       
   110     return 0;
       
   111 }
       
   112 
       
   113 int OMADownloadBackend::resume()
       
   114 {
       
   115     DM_PRIVATE(OMADownloadBackend);
       
   116     priv->m_isUserCancelled = false;
       
   117     if (priv->m_isMediaDownload)
       
   118         return (priv->m_mediaDownload->resume());
       
   119 
       
   120     // Ready to download after the descriptor is parsed
       
   121     // capability check on the descriptor information
       
   122     if (checkDownloadDescriptor()) {
       
   123          // create download for media object
       
   124         priv->m_mediaDownload = new ClientDownload(priv->m_download->downloadManager(), 
       
   125                 priv->m_downloadDesc->getAttribute(OMADownloadDescObjectURI).toString(), priv->m_download->id()); 
       
   126 
       
   127         if (!priv->m_mediaDownload) {
       
   128             deleteInfo(); 
       
   129             return -1;               
       
   130         }
       
   131         priv->m_mediaDownload->setAttribute(DlFileName, priv->m_downloadDesc->getAttribute(OMADownloadDescName));
       
   132         priv->m_mediaDownload->registerEventReceiver(this);
       
   133         priv->m_mediaDownload->start();
       
   134         priv->m_isMediaDownload = true; 
       
   135         deleteInfo(); 
       
   136         return 0;         
       
   137     }
       
   138     return -1;
       
   139 }
       
   140 
       
   141 int OMADownloadBackend::cancel()
       
   142 {
       
   143     DM_PRIVATE(OMADownloadBackend);
       
   144     priv->m_isUserCancelled = true;
       
   145     if (priv->m_isMediaDownload)
       
   146         priv->m_mediaDownload->cancel();
       
   147     else
       
   148         DownloadBackend::cancel();
       
   149     return 0;
       
   150 }
       
   151 
       
   152 QVariant OMADownloadBackend::getAttribute(DownloadAttribute attr)
       
   153 {
       
   154     DM_PRIVATE(OMADownloadBackend);
       
   155     switch(attr) {
       
   156     case OMADownloadDescriptorName:
       
   157         return priv->m_downloadDesc->getAttribute(OMADownloadDescName);
       
   158     case OMADownloadDescriptorVersion:
       
   159         return priv->m_downloadDesc->getAttribute(OMADownloadDescVersion);
       
   160     case OMADownloadDescriptorType:
       
   161         return priv->m_downloadDesc->getAttribute(OMADownloadDescType);
       
   162     case OMADownloadDescriptorSize:
       
   163         return priv->m_downloadDesc->getAttribute(OMADownloadDescSize);
       
   164     case OMADownloadDescriptorVendor:
       
   165         return priv->m_downloadDesc->getAttribute(OMADownloadDescVendor);
       
   166     case OMADownloadDescriptorDescription:
       
   167         return priv->m_downloadDesc->getAttribute(OMADownloadDescDescription);
       
   168 
       
   169     case DlFileName:
       
   170     {
       
   171         if (!priv->m_isMediaDownload) {
       
   172             QString url = priv->m_downloadCore->url();
       
   173             QFileInfo fileUrl(url);
       
   174             return QVariant(fileUrl.fileName());
       
   175         } else
       
   176             return priv->m_downloadDesc->getAttribute(OMADownloadDescName);
       
   177     }
       
   178     case DlContentType:
       
   179     {
       
   180         if (!priv->m_isMediaDownload)
       
   181             return DownloadBackend::getAttribute(DlContentType);
       
   182             
       
   183         else
       
   184             return priv->m_mediaDownload->getAttribute(DlContentType);
       
   185     }
       
   186     default:
       
   187         return DownloadBackend::getAttribute(attr);
       
   188     }    
       
   189     return QVariant();
       
   190 }
       
   191 
       
   192 int OMADownloadBackend::setAttribute(DownloadAttribute attr, const QVariant& value)
       
   193 {
       
   194     return DownloadBackend::setAttribute(attr, value);
       
   195 }
       
   196 
       
   197 // stores the data in storage
       
   198 void OMADownloadBackend::store(QByteArray /*data*/, bool /*lastChunk=false*/)
       
   199 {
       
   200     return;
       
   201 }
       
   202 
       
   203 // deletes the storage
       
   204 void OMADownloadBackend::deleteStore()
       
   205 {
       
   206     return;
       
   207 }
       
   208 
       
   209 // returns the size of stored data
       
   210 qint64 OMADownloadBackend::storedDataSize()
       
   211 {
       
   212     return 0;
       
   213 }
       
   214 
       
   215 void OMADownloadBackend::bytesRecieved(qint64 /*bytesRecieved*/, qint64 /*bytesTotal*/)
       
   216 {
       
   217      //Do nothing. This is here to avoid this signal to reach to base class' slot.
       
   218      return;
       
   219 }
       
   220 
       
   221 void OMADownloadBackend::bytesUploaded(qint64 bytesUploaded, qint64 bytesTotal)
       
   222 {
       
   223     DM_PRIVATE(OMADownloadBackend); 
       
   224     // once data is uploaded, cancel the transaction
       
   225     if (bytesUploaded == bytesTotal)
       
   226         priv->m_downloadCore->abort() ;
       
   227 }
       
   228 
       
   229 void OMADownloadBackend::handleFinished()
       
   230 {
       
   231      DM_PRIVATE(OMADownloadBackend);
       
   232      QString contentType = priv->m_downloadCore->contentType();
       
   233      if (contentType == OMA_CONTENT_TYPE) {
       
   234          bool bSucceeded = parseDownloadDescriptor();
       
   235          if (bSucceeded) {
       
   236              priv->m_downloadDesc = priv->m_parser->downloadDescriptor();
       
   237              
       
   238              QString objectURI = priv->m_downloadDesc->getAttribute(OMADownloadDescObjectURI).toString();
       
   239              if (objectURI.isEmpty()) {
       
   240                  priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("905 Attribute Mismatch"));
       
   241                  priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
       
   242                  priv->m_downloadCore->setLastErrorString(tr("No ObjectURI"));
       
   243                  setDownloadState(DlFailed);
       
   244                  postEvent(Error, NULL);
       
   245                  return;
       
   246              }
       
   247              setDownloadState(DlPaused);
       
   248              postEvent(OMADownloadDescriptorReady, NULL);
       
   249          } else {
       
   250              priv->m_downloadDesc = priv->m_parser->downloadDescriptor();
       
   251              priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("906 Invalid descriptor"));
       
   252              priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
       
   253              priv->m_downloadCore->setLastErrorString(tr("Invalid Descriptor"));
       
   254              setDownloadState(DlFailed);
       
   255              postEvent(Error, NULL);
       
   256          }
       
   257      }
       
   258 }
       
   259           
       
   260 bool OMADownloadBackend::parseDownloadDescriptor()
       
   261 {
       
   262     DM_PRIVATE(OMADownloadBackend);
       
   263     priv->m_parser = new OMADownloadDescParser();
       
   264     QXmlInputSource source(priv->m_downloadCore->reply());
       
   265     QXmlSimpleReader reader;
       
   266     reader.setContentHandler(priv->m_parser);
       
   267     reader.setErrorHandler(priv->m_parser);
       
   268     return reader.parse(source);
       
   269 }
       
   270 
       
   271 // capability check on the descriptor
       
   272 bool OMADownloadBackend::checkDownloadDescriptor()
       
   273 {
       
   274     DM_PRIVATE(OMADownloadBackend);
       
   275 
       
   276     QString version = priv->m_downloadDesc->getAttribute(OMADownloadDescVersion).toString();
       
   277     if (! version.isEmpty() && (version != OMA_VERSION_1)) {
       
   278         priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("951 Invalid DDVersion"));
       
   279         priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
       
   280         priv->m_downloadCore->setLastErrorString(tr("951 Invalid DDVersion"));
       
   281         setDownloadState(DlFailed); 
       
   282         postEvent(Error, NULL);
       
   283         return false; 
       
   284     } 
       
   285 
       
   286 #ifdef Q_OS_LINUX
       
   287     // "Size" check needs to be done
       
   288     double fileSize =  priv->m_downloadDesc->getAttribute(OMADownloadDescSize).toDouble();
       
   289     double mbFactor = 1024*1024;
       
   290     fileSize = fileSize/mbFactor; //fileSize in MB
       
   291     double spaceLeft = freeSpace(ROOT_PATH); //spaze left in MB
       
   292     
       
   293     if (fileSize > spaceLeft) {
       
   294         priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("901 Insufficient memory"));
       
   295         priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
       
   296         priv->m_downloadCore->setLastErrorString(tr("901 Insufficient Memory"));
       
   297         setDownloadState(DlFailed);
       
   298         postEvent(Error, NULL);
       
   299         return false;       
       
   300     } 
       
   301 #endif
       
   302     return true;
       
   303 }
       
   304 
       
   305 bool OMADownloadBackend::event(QEvent *event)
       
   306 {
       
   307     DM_PRIVATE(OMADownloadBackend);
       
   308     DEventType type = (DEventType)event->type();
       
   309     switch(type) {
       
   310     case Started:
       
   311         break;
       
   312     case HeaderReceived:
       
   313     {
       
   314         // handling the events from media object downloads
       
   315         // Check the mismatch in total size returned by server with the size given in the descriptor.
       
   316         //This piece of code is commented as-of-now. when needed in future , will be uncommented
       
   317         /*int totalSize = dl->getAttribute(DlTotalSize).toInt();
       
   318         if (priv->m_downloadDesc->getAttribute(OMADownloadDescSize).toInt() != totalSize)
       
   319         {
       
   320             priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("905 Attribute Mismatch"));
       
   321              
       
   322             if (dl)
       
   323             {
       
   324                 dl->setError("905 Attribute Mismatch");
       
   325                 dl->cancel();
       
   326                 dl->setDownloadState(DlFailed);
       
   327                 dl->postEvent(Error, NULL);
       
   328             } 
       
   329             return true;
       
   330         }*/
       
   331         // Check the mismatch in content type returned by server with the content type given in the descriptor.
       
   332         QString contentType = priv->m_mediaDownload->getAttribute(DlContentType).toString();
       
   333         if (priv->m_downloadDesc->getAttribute(OMADownloadDescType).toString() != contentType) {
       
   334             // media object download cannot be proceeded
       
   335             if (priv->m_mediaDownload) {
       
   336                 priv->m_mediaDownload->setError("905 Attribute Mismatch");
       
   337                 priv->m_mediaDownload->cancel();
       
   338                 priv->m_mediaDownload->setDownloadState(DlFailed);
       
   339                 priv->m_mediaDownload->postEvent(Error, NULL);
       
   340             } 
       
   341             break;
       
   342         } 
       
   343     }
       
   344     case Progress:
       
   345     {
       
   346         QVariant tSize = priv->m_mediaDownload->getAttribute(DlTotalSize);
       
   347         setTotalSize(tSize.toInt());
       
   348         QVariant curDlsize = priv->m_mediaDownload->getAttribute(DlDownloadedSize);
       
   349         setDownloadedDataSize(curDlsize.toInt());
       
   350         setDownloadState(DlInprogress);
       
   351         postEvent(Progress, NULL);
       
   352         break;
       
   353     }
       
   354     case NetworkLoss:
       
   355     {
       
   356         postEvent(NetworkLoss, NULL);
       
   357         break;
       
   358     }
       
   359     case Cancelled:
       
   360     {
       
   361         if (priv->m_isUserCancelled)
       
   362             priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("902 User Cancelled"));
       
   363         setDownloadState(DlCancelled);
       
   364         postEvent(Cancelled, NULL);
       
   365         break;
       
   366     }
       
   367     case Completed:
       
   368     {
       
   369         priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("900 Success "));
       
   370         setDownloadState(DlCompleted);
       
   371         postEvent(Completed, NULL); 
       
   372         break;
       
   373     }
       
   374     case Error:
       
   375     {
       
   376         priv->m_downloadCore->post(priv->m_downloadDesc->getAttribute(OMADownloadDescInstallNotifyURI).toString(), QByteArray("905 Attribute Mismatch"));
       
   377         priv->m_downloadCore->setLastError(QNetworkReply::UnknownContentError);
       
   378         priv->m_downloadCore->setLastErrorString(tr("905 Attribute Mismatch"));
       
   379         setDownloadState(DlFailed);
       
   380         postEvent(Error, NULL);
       
   381         break;
       
   382     } 
       
   383     default:
       
   384         break;
       
   385     }
       
   386     return true;
       
   387 }
       
   388 
       
   389