utilities/downloadmanager/src/downloadmanager.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 "downloadmanager.h"
       
    18 #include "download.h"
       
    19 #include "clientdownload.h"
       
    20 #include "downloadevent.h"
       
    21 #include "downloadinfo.h"
       
    22 #include "downloadcoremanager.h"
       
    23 #include "backgrounddownloadmanager.h"
       
    24 #include "paralleldownloadmanager.h"
       
    25 #include "sequentialdownloadmanager.h"
       
    26 #include <QNetworkReply>
       
    27 #include <QNetworkProxy>
       
    28 #include <QList>
       
    29 #include <QDir>
       
    30 #include <QCoreApplication>
       
    31 
       
    32 // defualt download path
       
    33 #define DOWNLOAD_PATH QDir::homePath() + QObject::tr("/Downloads")
       
    34 
       
    35 class DownloadManagerPrivate
       
    36 {
       
    37     //declare public implementation
       
    38     DM_DECLARE_PUBLIC(DownloadManager);
       
    39 public:
       
    40     DownloadManagerPrivate();
       
    41     ~DownloadManagerPrivate();
       
    42 
       
    43     QString m_clientName; // client name
       
    44     QNetworkProxy *m_proxy;
       
    45     QObject *m_receiver; // event reciever
       
    46     DownloadInfo *m_dlInfo;
       
    47     DownloadCoreManager *m_dlCoreManager; // manages all the download cores
       
    48     QString m_destPath; // download destination path
       
    49     BackgroundDownloadManager* m_backgroundManager;
       
    50     ParallelDownloadManager *m_parallelManager; // manages parallel downloads
       
    51     SequentialDownloadManager *m_sequentialManager; // manages sequential downloads
       
    52     QList<Download*> m_totalDownloads; // has a list of both parallel and sequential downloads, but doesnt own it
       
    53     DownloadMgrProgressMode m_progressMode;
       
    54     DownloadMgrPersistantMode m_persistantMode;
       
    55 };
       
    56 
       
    57 DownloadManagerPrivate::DownloadManagerPrivate()
       
    58 {
       
    59     m_clientName = "";
       
    60     m_proxy = 0;
       
    61     m_receiver = 0;
       
    62     m_dlInfo = 0;
       
    63     m_dlCoreManager = 0;
       
    64     // set the download destination path to default path
       
    65     m_destPath = DOWNLOAD_PATH;
       
    66     m_backgroundManager = 0;
       
    67     m_parallelManager = 0;
       
    68     m_sequentialManager = 0;
       
    69     m_progressMode = NonQuiet;
       
    70     m_persistantMode = Active;
       
    71 }
       
    72 
       
    73 DownloadManagerPrivate::~DownloadManagerPrivate()
       
    74 {
       
    75     if(m_sequentialManager)
       
    76     {
       
    77         delete m_sequentialManager;
       
    78         m_sequentialManager = 0;
       
    79     }
       
    80     if(m_parallelManager)
       
    81     {
       
    82         delete m_parallelManager;
       
    83         m_parallelManager = 0;
       
    84     }
       
    85     if (m_backgroundManager)
       
    86     {
       
    87         delete m_backgroundManager;
       
    88         m_backgroundManager = 0;
       
    89     }
       
    90     if(m_proxy)
       
    91     {
       
    92         delete m_proxy;
       
    93         m_proxy = 0;
       
    94     }
       
    95     if(m_dlInfo)
       
    96     {
       
    97         m_dlInfo->update();
       
    98         delete m_dlInfo;
       
    99         m_dlInfo = 0;
       
   100     }
       
   101     if(m_dlCoreManager)
       
   102     {
       
   103         delete m_dlCoreManager;
       
   104         m_dlCoreManager = 0;
       
   105     }
       
   106 }
       
   107 
       
   108 /*!
       
   109  * \class DownloadManager
       
   110  *
       
   111  * \brief The public APIs for managing the downloads
       
   112  *
       
   113  * This class has the public APIs for managing the downloads
       
   114  */
       
   115 
       
   116 /*!
       
   117   creates an instance of download manager
       
   118   \a clientName indicates the name of the client
       
   119 */
       
   120 Q_DECL_EXPORT DownloadManager::DownloadManager(const QString& clientName)
       
   121 {
       
   122     DM_INITIALIZE(DownloadManager);
       
   123     priv->m_clientName = clientName;
       
   124     //create a download info to save download informations
       
   125     priv->m_dlInfo = new DownloadInfo(clientName);
       
   126     // create download core manager
       
   127     priv->m_dlCoreManager = new DownloadCoreManager(clientName);
       
   128     // create background download manager
       
   129     priv->m_backgroundManager = new BackgroundDownloadManager(this);
       
   130     // create parallel download manager
       
   131     priv->m_parallelManager = new ParallelDownloadManager();
       
   132     // create sequential download manager
       
   133     priv->m_sequentialManager = new SequentialDownloadManager();
       
   134 }
       
   135 
       
   136 /*!
       
   137   destructor for the download manager
       
   138 */
       
   139 Q_DECL_EXPORT DownloadManager::~DownloadManager()
       
   140 {
       
   141     DM_UNINITIALIZE(DownloadManager);
       
   142 }
       
   143 
       
   144 /*!
       
   145   initialises all the downloads which belongs to last download manager session
       
   146 */
       
   147 Q_DECL_EXPORT void DownloadManager::init()
       
   148 {
       
   149     //load all downloads which were created in the last session
       
   150     loadAllDownloads();
       
   151 }
       
   152 
       
   153 /*!
       
   154   returns new download
       
   155   \a url indicates download url
       
   156   \a type indicates whether it is sequential or parallel download
       
   157 */
       
   158 Q_DECL_EXPORT Download* DownloadManager::createDownload(const QString& url, DownloadType type/*=Parallel*/, DownloadScope scope/*=Normal*/)
       
   159 {
       
   160     DM_PRIVATE(DownloadManager);
       
   161     if(url == "")
       
   162         return NULL;
       
   163     Download* dl(0);
       
   164 
       
   165     if (scope == Normal) {
       
   166         dl = new ClientDownload(this, url, generateDlId());
       
   167         if(type == Parallel)
       
   168             priv->m_parallelManager->addToParallelDownload(dl);
       
   169         else if(type == Sequential) {
       
   170             // by default the priority is low
       
   171             dl->setAttribute(DlPriority, (int)Low);
       
   172             priv->m_sequentialManager->addToSequentialDownload(dl);
       
   173         }
       
   174         postEvent(DownloadCreated, NULL);
       
   175     }
       
   176     else if (scope == Background) {
       
   177         dl = priv->m_backgroundManager->createDownload(url, type);
       
   178     }
       
   179     return dl;
       
   180 }
       
   181 
       
   182 /*!
       
   183   returns new download
       
   184   \a reply indicates network reply which is already initiated
       
   185 */
       
   186 Q_DECL_EXPORT Download* DownloadManager::createDownload(QNetworkReply *reply)
       
   187 {
       
   188     DM_PRIVATE(DownloadManager);
       
   189     if(!reply)
       
   190         return NULL;
       
   191     ClientDownload *dl = new ClientDownload(this, reply, generateDlId());
       
   192     priv->m_parallelManager->addToParallelDownload(dl);
       
   193     postEvent(DownloadCreated, NULL);
       
   194     return dl;
       
   195 }
       
   196 
       
   197 Download* DownloadManager::createDownload(int dlId, DownloadScope scope)
       
   198 {
       
   199     DM_PRIVATE(DownloadManager);
       
   200     if(dlId == INVALID_DL_ID)
       
   201         return NULL;
       
   202     Download *dl = NULL;
       
   203     if (scope == Normal){
       
   204         dl = new ClientDownload(this, dlId);
       
   205         DownloadType type = (DownloadType)(dl->getAttribute(DlDownloadType).toInt());
       
   206         if(type == Parallel)
       
   207             priv->m_parallelManager->addToParallelDownload(dl);
       
   208         else
       
   209             priv->m_sequentialManager->addToSequentialDownload(dl);
       
   210     } else if (scope == Background){
       
   211         dl = priv->m_backgroundManager->createDownload(dlId);
       
   212     } else
       
   213         return NULL;
       
   214      
       
   215     if (dl)
       
   216          postEvent(DownloadCreated, NULL);
       
   217     return dl;
       
   218 }
       
   219 
       
   220 /*!
       
   221   sets the proxy
       
   222   \a proxyServer indicates proxy server name
       
   223   \a port indicates port number
       
   224 */
       
   225 Q_DECL_EXPORT void DownloadManager::setProxy(const QString& proxyServer, int port)
       
   226 {
       
   227     DM_PRIVATE(DownloadManager);
       
   228     if(priv->m_proxy)
       
   229     {
       
   230         delete priv->m_proxy;
       
   231         priv->m_proxy = 0;
       
   232     }
       
   233     priv->m_proxy = new QNetworkProxy(QNetworkProxy::HttpCachingProxy, proxyServer, port );
       
   234     return;
       
   235 }
       
   236 
       
   237 /*!
       
   238   registers event listener
       
   239   \a reciever indicates reciever object to be registered for download events
       
   240 */
       
   241 Q_DECL_EXPORT void DownloadManager::registerEventReceiver(QObject *receiver)
       
   242 {
       
   243     DM_PRIVATE(DownloadManager);
       
   244     if (receiver)
       
   245         priv->m_receiver = receiver;
       
   246     return;
       
   247 }
       
   248 
       
   249 /*!
       
   250   unregister event listener
       
   251   \a reciever indicates reciever object to be unregistered
       
   252 */
       
   253 Q_DECL_EXPORT void DownloadManager::unregisterEventReceiver(QObject *receiver)
       
   254 {
       
   255     DM_PRIVATE(DownloadManager);
       
   256     if(receiver == priv->m_receiver)
       
   257     {
       
   258         priv->m_receiver = 0;
       
   259     }
       
   260     return;
       
   261 }
       
   262 
       
   263 /*!
       
   264   sets download manager attribute
       
   265   \a attr indicates download manager attribute
       
   266   \a value indicates value to be set
       
   267 */
       
   268 Q_DECL_EXPORT int DownloadManager::setAttribute(DownloadManagerAttribute attr, const QVariant& value)
       
   269 {
       
   270     DM_PRIVATE(DownloadManager);
       
   271     switch(attr)
       
   272     {
       
   273         case DlMgrDestPath:
       
   274         {
       
   275             priv->m_destPath = value.toString();
       
   276             return 0;
       
   277         }
       
   278         case DlMgrProgressMode:
       
   279         {
       
   280             priv->m_progressMode = (DownloadMgrProgressMode)value.toInt();
       
   281             return 0;
       
   282         }
       
   283         case DlMgrPersistantMode:
       
   284         {
       
   285             priv->m_persistantMode = (DownloadMgrPersistantMode)value.toInt();
       
   286             return 0;
       
   287         }
       
   288         default :
       
   289             return -1;
       
   290     }
       
   291     return -1;
       
   292 }
       
   293 
       
   294 /*!
       
   295   fetches download manager attribute
       
   296   \a attr indicates download manager attribute whos value to be returned
       
   297 */
       
   298 Q_DECL_EXPORT QVariant DownloadManager::getAttribute(DownloadManagerAttribute attr)
       
   299 {
       
   300     DM_PRIVATE(DownloadManager);
       
   301     switch(attr)
       
   302     {
       
   303         case DlMgrDlCount:
       
   304         {
       
   305             int count(0);
       
   306             if(priv->m_parallelManager)
       
   307                 count += priv->m_parallelManager->currentDownloads().count();
       
   308             if(priv->m_sequentialManager)
       
   309                 count += priv->m_sequentialManager->currentDownloads().count();
       
   310             if(priv->m_backgroundManager)
       
   311                 count += priv->m_backgroundManager->currentDownloads().count();
       
   312             return QVariant(count);
       
   313         }
       
   314         case DlMgrClientName:
       
   315         {
       
   316             return QVariant(priv->m_clientName);
       
   317         }
       
   318         case DlMgrDestPath:
       
   319         {
       
   320             return QVariant(priv->m_destPath);
       
   321         }
       
   322         case DlMgrServerError:
       
   323         {
       
   324             // These cases apply only for Background Download Manager as this attribute
       
   325             // is for getting download manager client-server communication related errors
       
   326             QVariant value;
       
   327             if(priv->m_backgroundManager)
       
   328                 value = priv->m_backgroundManager->getAttribute(attr);
       
   329             return value;
       
   330         }
       
   331         case DlMgrProgressMode:
       
   332         {
       
   333             return QVariant(priv->m_progressMode);
       
   334         }
       
   335         case DlMgrPersistantMode:
       
   336         {
       
   337             return QVariant(priv->m_persistantMode);
       
   338         }
       
   339         default :
       
   340             return QVariant();
       
   341     }
       
   342     return QVariant();
       
   343 }
       
   344 
       
   345 /*!
       
   346   returns all the current downloads
       
   347 */
       
   348 Q_DECL_EXPORT QList<Download*>& DownloadManager::currentDownloads()
       
   349 {
       
   350     DM_PRIVATE(DownloadManager);
       
   351     priv->m_totalDownloads.clear();
       
   352     if(priv->m_parallelManager) {
       
   353         for(int i = 0;i < priv->m_parallelManager->currentDownloads().size(); ++i)
       
   354             priv->m_totalDownloads.append(priv->m_parallelManager->currentDownloads()[i]);
       
   355     }
       
   356     if(priv->m_sequentialManager) {
       
   357         for(int i = 0;i < priv->m_sequentialManager->currentDownloads().size(); ++i)
       
   358             priv->m_totalDownloads.append(priv->m_sequentialManager->currentDownloads()[i]);
       
   359     }
       
   360     if(priv->m_backgroundManager) {
       
   361         for(int i = 0;i < priv->m_backgroundManager->currentDownloads().size(); ++i)
       
   362             priv->m_totalDownloads.append(priv->m_backgroundManager->currentDownloads()[i]);
       
   363     }
       
   364     return priv->m_totalDownloads;
       
   365 }
       
   366 
       
   367 /*!
       
   368   finds a download provided id if exists
       
   369   \a id indicates identifier for download
       
   370 */
       
   371 Q_DECL_EXPORT Download* DownloadManager::findDownload(int dlId)
       
   372 {
       
   373     DM_PRIVATE(DownloadManager);
       
   374     Download* dl = NULL;
       
   375     if(priv->m_parallelManager)
       
   376     {
       
   377         dl = priv->m_parallelManager->findDownload(dlId);
       
   378         if(dl)
       
   379             return dl;
       
   380     }
       
   381     if(priv->m_sequentialManager)
       
   382     {
       
   383         dl = priv->m_sequentialManager->findDownload(dlId);
       
   384         if(dl)
       
   385             return dl;
       
   386     }
       
   387     if(priv->m_backgroundManager)
       
   388     {
       
   389         dl = priv->m_backgroundManager->findDownload(dlId);
       
   390         if(dl)
       
   391             return dl;
       
   392     }
       
   393     return NULL;
       
   394 }
       
   395 
       
   396 /*!
       
   397   cancels all the downloads
       
   398 */
       
   399 Q_DECL_EXPORT void DownloadManager::removeAll()
       
   400 {
       
   401     DM_PRIVATE(DownloadManager);
       
   402     if(priv->m_parallelManager)
       
   403         priv->m_parallelManager->removeAll();
       
   404     if(priv->m_sequentialManager)
       
   405         priv->m_sequentialManager->removeAll();
       
   406     if(priv->m_backgroundManager)
       
   407         priv->m_backgroundManager->removeAll();
       
   408     postEvent(DownloadsCleared, NULL);
       
   409     return;
       
   410 }
       
   411 
       
   412 /*!
       
   413   cancels and removes the download
       
   414   \a dl indicates the download to be canceled and removed
       
   415 */
       
   416 Q_DECL_EXPORT void DownloadManager::removeOne(Download *dl)
       
   417 {
       
   418     if (!dl)
       
   419         return;
       
   420 
       
   421     DM_PRIVATE(DownloadManager);
       
   422     if(priv->m_parallelManager)
       
   423         priv->m_parallelManager->removeOne(dl);
       
   424     if(priv->m_sequentialManager)
       
   425         priv->m_sequentialManager->removeOne(dl);
       
   426     if(priv->m_backgroundManager)
       
   427         priv->m_backgroundManager->removeOne(dl);
       
   428 
       
   429     if((priv->m_parallelManager->currentDownloads().count() == 0) &&
       
   430         (priv->m_sequentialManager->currentDownloads().count() == 0) &&
       
   431         (priv->m_backgroundManager->currentDownloads().count() == 0))
       
   432         postEvent(DownloadsCleared, NULL);
       
   433     return;
       
   434 }
       
   435 
       
   436 /*!
       
   437   pauses all the downloads which are in progress
       
   438 */
       
   439 Q_DECL_EXPORT void DownloadManager::pauseAll()
       
   440 {
       
   441     DM_PRIVATE(DownloadManager);
       
   442     if(priv->m_parallelManager)
       
   443         priv->m_parallelManager->pauseAll();
       
   444     if(priv->m_sequentialManager)
       
   445         priv->m_sequentialManager->pauseAll();
       
   446     if(priv->m_backgroundManager)
       
   447         priv->m_backgroundManager->pauseAll();
       
   448     return;
       
   449 }
       
   450 
       
   451 /*!
       
   452   resumes all the downloads which are paused
       
   453 */
       
   454 Q_DECL_EXPORT void DownloadManager::resumeAll()
       
   455 {
       
   456     DM_PRIVATE(DownloadManager);
       
   457     if(priv->m_parallelManager)
       
   458         priv->m_parallelManager->resumeAll();
       
   459     if(priv->m_sequentialManager)
       
   460         priv->m_sequentialManager->resumeAll();
       
   461     if(priv->m_backgroundManager)
       
   462         priv->m_backgroundManager->resumeAll();
       
   463     return;
       
   464 }
       
   465 
       
   466 /*!
       
   467   returns the proxy used
       
   468 */
       
   469 Q_DECL_EXPORT QNetworkProxy* DownloadManager::proxy()
       
   470 {
       
   471     DM_PRIVATE(DownloadManager);
       
   472     return priv->m_proxy;
       
   473 }
       
   474 
       
   475 DownloadInfo* DownloadManager::downloadInfo()
       
   476 {
       
   477     DM_PRIVATE(DownloadManager);
       
   478     return priv->m_dlInfo;
       
   479 }
       
   480 
       
   481 DownloadCoreManager* DownloadManager::downloadCoreManager()
       
   482 {
       
   483     DM_PRIVATE(DownloadManager);
       
   484     return priv->m_dlCoreManager;
       
   485 }
       
   486 
       
   487 SequentialDownloadManager* DownloadManager::sequentialManager()
       
   488 {
       
   489     DM_PRIVATE(DownloadManager);
       
   490     return priv->m_sequentialManager;
       
   491 }
       
   492 
       
   493 BackgroundDownloadManager* DownloadManager::backgroundManager()
       
   494 {
       
   495     DM_PRIVATE(DownloadManager);
       
   496     return priv->m_backgroundManager;
       
   497 }
       
   498 
       
   499 void DownloadManager::loadAllDownloads()
       
   500 {
       
   501     DM_PRIVATE(DownloadManager);
       
   502     // read the saved downloads information and create download
       
   503     QVector<int> ids = DownloadInfo::getAllDownloads(priv->m_clientName);
       
   504     for(int i=0; i<ids.size(); i++)
       
   505     {
       
   506         if(!findDownload(ids[i])) {
       
   507             long scope;
       
   508             priv->m_dlInfo->getValue(ids[i], DownloadInfo::EScope, scope);
       
   509             createDownload(ids[i], (DownloadScope)scope);
       
   510         }
       
   511     }
       
   512     return;
       
   513 }
       
   514 
       
   515 // generate unique id for download
       
   516 long DownloadManager::generateDlId()
       
   517 {
       
   518     DM_PRIVATE(DownloadManager);
       
   519     long id = 1;
       
   520     long totDls = (priv->m_parallelManager->currentDownloads().count() + 
       
   521                 priv->m_sequentialManager->currentDownloads().count() +
       
   522                 priv->m_backgroundManager->currentDownloads().count());
       
   523 
       
   524     if(totDls <= 0)
       
   525     {
       
   526         return id;
       
   527     }
       
   528     while(1)
       
   529     {
       
   530         int i;
       
   531         for(i = 0; i <= totDls ; ++i)
       
   532         {
       
   533             Download* parallelDl = NULL;
       
   534             parallelDl = priv->m_parallelManager ? priv->m_parallelManager->findDownload(i) : NULL;
       
   535             Download* sequentialDl = NULL;
       
   536             sequentialDl = priv->m_sequentialManager ? priv->m_sequentialManager->findDownload(i) : NULL;
       
   537             Download* backgroundDl = NULL;
       
   538             backgroundDl = priv->m_backgroundManager ? priv->m_backgroundManager->findDownload(i) : NULL;
       
   539             if((parallelDl && (parallelDl->id() == id)) ||
       
   540                 (sequentialDl && (sequentialDl->id() == id)) ||
       
   541                 (backgroundDl && (backgroundDl->id() == id)))
       
   542             {
       
   543                 break;
       
   544             }
       
   545         }
       
   546         if(i>totDls)
       
   547         {
       
   548             return id;
       
   549         }
       
   550         id++;
       
   551     }
       
   552     return -1;
       
   553 }
       
   554 
       
   555 void DownloadManager::postEvent(DEventType type, DlManagerEventAttributeMap* attrMap)
       
   556 {
       
   557     DM_PRIVATE(DownloadManager);
       
   558     if(priv->m_receiver)
       
   559     {
       
   560         DownloadManagerEvent *event = new DownloadManagerEvent(type, attrMap);
       
   561         QCoreApplication::postEvent(priv->m_receiver, event);
       
   562     }
       
   563 }
       
   564