diff -r 6aeb7a756187 -r 3c88a81ff781 utilities/downloadmanager/src/sequentialdownloadmanager.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utilities/downloadmanager/src/sequentialdownloadmanager.cpp Fri Oct 15 17:30:59 2010 -0400
@@ -0,0 +1,366 @@
+/**
+ 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 "downloadmanager.h"
+#include "download.h"
+#include "sequentialdownloadmanager.h"
+#include "downloadevent.h"
+#include "clientdownload.h"
+
+class SequentialDownloadManagerPrivate
+{
+ //declare public implementation
+ DM_DECLARE_PUBLIC(SequentialDownloadManager);
+public:
+ SequentialDownloadManagerPrivate();
+ ~SequentialDownloadManagerPrivate();
+
+ QList m_createdDownloads; // list of downloads which have been created by the client and owns them
+ QQueue m_downloadsQueue; // queue of downloads scheduled for downloading and owns them
+ QList m_completedDownloads; // list of downloads which have been completed and owns them
+ QList m_failedDownloads; // list of failed downloads
+ QList m_totalDownloads; // total of all the above downloads, but this doesnt own downloads
+};
+
+SequentialDownloadManagerPrivate::SequentialDownloadManagerPrivate()
+{ }
+
+SequentialDownloadManagerPrivate::~SequentialDownloadManagerPrivate()
+{
+ int createdSize = m_createdDownloads.size();
+ for (int i = 0; i < createdSize; i++)
+ delete m_createdDownloads[i];
+ m_createdDownloads.clear();
+
+ int completedSize = m_completedDownloads.size();
+ for (int i = 0; i < completedSize; i++)
+ delete m_completedDownloads[i];
+ m_completedDownloads.clear();
+
+ int size = m_downloadsQueue.size();
+ for (int i = 0; i < size; i++) {
+ DownloadState state = (DownloadState)((m_downloadsQueue[i]->getAttribute(DlDownloadState)).toInt());
+ if (state == DlInprogress) {
+ // pause the download if it is in progress
+ m_downloadsQueue[i]->pause();
+ } else if (state == DlFailed) {
+ // cancel the download if it has failed
+ m_downloadsQueue[i]->cancel();
+ }
+ delete (m_downloadsQueue[i]);
+ }
+ m_downloadsQueue.clear();
+}
+
+/*
+ constructor
+*/
+SequentialDownloadManager::SequentialDownloadManager()
+{
+ DM_INITIALIZE(SequentialDownloadManager);
+}
+
+/*
+ destructor
+*/
+SequentialDownloadManager::~SequentialDownloadManager()
+{
+ DM_UNINITIALIZE(SequentialDownloadManager);
+}
+
+/*
+ returns all the current downloads
+*/
+QList& SequentialDownloadManager::currentDownloads()
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ priv->m_totalDownloads.clear();
+ for (int i = 0; i < priv->m_completedDownloads.size(); ++i)
+ priv->m_totalDownloads.append(priv->m_completedDownloads[i]);
+ for (int i = 0; i < priv->m_downloadsQueue.size(); ++i)
+ priv->m_totalDownloads.append(priv->m_downloadsQueue[i]);
+ for (int i = 0; i < priv->m_createdDownloads.size(); ++i)
+ priv->m_totalDownloads.append(priv->m_createdDownloads[i]);
+ for (int i = 0; i < priv->m_failedDownloads.size(); ++i)
+ priv->m_totalDownloads.append(priv->m_failedDownloads[i]);
+ return priv->m_totalDownloads;
+}
+
+/*
+ finds a download provided id if exists
+ \a id indicates identifier for download
+*/
+Download* SequentialDownloadManager::findDownload(int dlId)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ for (int i = 0; i < priv->m_completedDownloads.size(); ++i) {
+ if (priv->m_completedDownloads[i]->id() == dlId)
+ return priv->m_completedDownloads[i];
+ }
+ for (int i = 0; i < priv->m_downloadsQueue.size(); ++i) {
+ if (priv->m_downloadsQueue[i]->id() == dlId)
+ return priv->m_downloadsQueue[i];
+ }
+ for (int i = 0; i < priv->m_createdDownloads.size(); ++i) {
+ if (priv->m_createdDownloads[i]->id() == dlId)
+ return priv->m_createdDownloads[i];
+ }
+ return 0;
+}
+
+/*
+ cancels all the downloads
+*/
+void SequentialDownloadManager::removeAll()
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ //traverse the list and delete each download in the list
+ for(int i = 0; i < priv->m_downloadsQueue.count(); ) {
+ // cancel the download
+ priv->m_downloadsQueue[0]->cancel();
+ delete (priv->m_downloadsQueue[0]);
+ priv->m_downloadsQueue.removeAt(0);
+ }
+ priv->m_downloadsQueue.clear();
+
+ int createdDownloadsCount = priv->m_createdDownloads.count();
+ //traverse the list and delete each download in the list
+ for(int i = 0; i < createdDownloadsCount; i++)
+ delete (priv->m_createdDownloads[i]);
+ priv->m_createdDownloads.clear();
+
+ int completedDownloadsCount = priv->m_completedDownloads.count();
+ //traverse the list and delete each download in the list
+ for(int i = 0; i < completedDownloadsCount; i++)
+ delete (priv->m_completedDownloads[i]);
+ priv->m_completedDownloads.clear();
+
+ int failedDownloadsCount = priv->m_failedDownloads.count();
+ //traverse the list and delete each download in the list
+ for(int i = 0; i < failedDownloadsCount; i++)
+ delete (priv->m_failedDownloads[i]);
+ priv->m_failedDownloads.clear();
+}
+
+/*
+ cancels and removes the download
+ \a dl indicates the download to be canceled and removed
+*/
+void SequentialDownloadManager::removeOne(Download *dl)
+{
+ if(!dl)
+ return;
+ DM_PRIVATE(SequentialDownloadManager);
+ if (currentDownloads().contains(dl)) {
+ dl->cancel();
+ // download might be there in any of the following list
+ priv->m_downloadsQueue.removeOne(dl);
+ priv->m_createdDownloads.removeOne(dl);
+ priv->m_completedDownloads.removeOne(dl);
+ delete dl;
+ dl = 0;
+ }
+}
+
+/*
+ pauses all the downloads which are in progress
+*/
+void SequentialDownloadManager::pauseAll()
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ if (!priv->m_downloadsQueue.isEmpty()) {
+ QQueue::iterator i;
+ i = priv->m_downloadsQueue.begin();
+ DownloadState state = (DownloadState)(((*i)->getAttribute(DlDownloadState)).toInt());
+ if ((state == DlInprogress || state == DlStarted))
+ dynamic_cast(*i)->pauseDownload();
+ }
+}
+
+/*
+ resumes all the downloads which are paused
+*/
+void SequentialDownloadManager::resumeAll()
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ if (!priv->m_downloadsQueue.isEmpty()) {
+ QQueue::iterator i;
+ i = priv->m_downloadsQueue.begin();
+ DownloadState state = (DownloadState)(((*i)->getAttribute(DlDownloadState)).toInt());
+ if (state == DlPaused)
+ dynamic_cast(*i)->resumeDownload();
+ }
+}
+
+void SequentialDownloadManager::addToSequentialDownload(Download* dl)
+{
+ // Here the downloads are added first to a download list. When the downloads are in this list,
+ // the client can set some attributes on the download.
+ // Later the client has to explicitly call start() on the download after which,
+ // download gets added to the downloadsQueue and the download starts.
+
+ DM_PRIVATE(SequentialDownloadManager);
+
+ // set the download type
+ ClientDownload* download = dynamic_cast(dl);
+ if(download)
+ download->attributes().insert(DlDownloadType, (int)Sequential);
+
+ // if the download is already in queue but the prority has been changed
+ if( findDownload(dl->id()))
+ priv->m_createdDownloads.removeOne(dl);
+
+ DownloadPriority priority = (DownloadPriority)(dl->getAttribute(DlPriority)).toInt();
+ if (priority == High) {
+ QList::iterator i;
+ for (i = priv->m_createdDownloads.begin(); i != priv->m_createdDownloads.end(); i++) {
+ if ((*i)->getAttribute(DlPriority).toInt() == Low) {
+ priv->m_createdDownloads.insert(i, dl);
+ return;
+ }
+ }
+ priv->m_createdDownloads.insert(i, dl); // if no low priority download is found then just insert the high priority download
+ }
+ else
+ priv->m_createdDownloads.append(dl);
+}
+
+void SequentialDownloadManager::addToDownloadQueue(Download* dl)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ priv->m_downloadsQueue.append(dl);
+}
+
+void SequentialDownloadManager::addToCompletedList(Download* dl)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ priv->m_completedDownloads.append(dl);
+}
+
+void SequentialDownloadManager::process(int dlId)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ // Start() has been called on a download present in the createdDownloads list. Move that download from the list to the queue
+ ClientDownload* dl = dynamic_cast(findDownload(dlId));
+ dl->registerEventReceiver(this);
+ priv->m_createdDownloads.removeOne(dl); // Once start() is called on download, add it to downloadQueue & remove it from createdDownloads list
+ if (priv->m_downloadsQueue.isEmpty()) {
+ addToDownloadQueue(dl);
+ dl->startDownload();
+ return;
+ }
+ DownloadPriority priority = (DownloadPriority)((dl->getAttribute(DlPriority)).toInt());
+ // checking for priority
+ if (priority == High) {
+ // Add the download before the first low priority item
+ QQueue::iterator i;
+ for (i = priv->m_downloadsQueue.begin(); i != priv->m_downloadsQueue.end(); i++) {
+ if ((*i)->getAttribute(DlPriority).toInt() == Low) {
+ if (i == priv->m_downloadsQueue.begin()) {
+ dynamic_cast(*i)->pauseDownload();
+ priv->m_downloadsQueue.insert(i, dl); // low priority dl is in progress so pause it, insert the high priority dl and start it.
+ dl->startDownload();
+ }
+ else {
+ // low priority download is present in the queue but it's not the first one as it is not yet started,
+ // so there's already a high priority dl in progress. So this high priority dl should just be inserted into the queue.
+ priv->m_downloadsQueue.insert(i, dl);
+ }
+ return;
+ }
+ }
+ priv->m_downloadsQueue.insert(i, dl); // insert the high priority download if there are no low priority downloads in the queue
+ }
+ else
+ addToDownloadQueue(dl); // If priority is low then just append to the queue.
+}
+
+bool SequentialDownloadManager::event(QEvent *event)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ DEventType type = (DEventType)event->type();
+ switch(type) {
+ case Completed:
+ {
+ int dlId = ((DownloadEvent*)event)->getId();
+ ClientDownload *dl = dynamic_cast(findDownload(dlId));
+ addToCompletedList(dl);
+ // After adding the download to completed list, remove it from downloadQueue
+ priv->m_downloadsQueue.removeOne(dl);
+ startNext();
+ break;
+ }
+ case Error:
+ {
+ int dlId = ((DownloadEvent*)event)->getId();
+ ClientDownload *dl = dynamic_cast(findDownload(dlId));
+ priv->m_failedDownloads.append(dl);
+ priv->m_downloadsQueue.removeOne(dl);
+ startNext();
+ break;
+ }
+ default:
+ break;
+ }
+ return true;
+}
+
+void SequentialDownloadManager::startNext()
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ QQueue::iterator i;
+ if (!priv->m_downloadsQueue.isEmpty()) {
+ i = priv->m_downloadsQueue.begin();
+ DownloadState state = (DownloadState)(((*i)->getAttribute(DlDownloadState)).toInt());
+ if (state == DlPaused)
+ (*i)->resume();
+ else
+ dynamic_cast(*i)->startDownload();
+ }
+}
+
+void SequentialDownloadManager::pauseDownload(int dlId)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ QQueue::iterator i;
+ if (!priv->m_downloadsQueue.isEmpty()) {
+ i = priv->m_downloadsQueue.begin();
+ if (dlId == (*i)->id())
+ dynamic_cast(*i)->pauseDownload();
+ }
+}
+
+void SequentialDownloadManager::resumeDownload(int dlId)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ QQueue::iterator i;
+ if (!priv->m_downloadsQueue.isEmpty()) {
+ i = priv->m_downloadsQueue.begin();
+ if (dlId == (*i)->id())
+ dynamic_cast(*i)->resumeDownload();
+ }
+}
+
+void SequentialDownloadManager::cancelDownload(int dlId)
+{
+ DM_PRIVATE(SequentialDownloadManager);
+ QQueue::iterator i;
+ if (!priv->m_downloadsQueue.isEmpty()) {
+ i = priv->m_downloadsQueue.begin();
+ if (dlId == (*i)->id())
+ dynamic_cast(*i)->cancelDownload();
+ }
+}