Bug 437415 - Entering offline mode should pause active downloads

This has the download manager listen to the online and offline observer topics
sent out by necko.  Downloads will now pause when going offline, and resume when
going back online, just like we do with sleep and wakeup notifications.
r=gavin

--HG--
rename : toolkit/components/downloads/test/unit/test_sleep_wake.js => toolkit/components/downloads/test/unit/test_offline_support.js
This commit is contained in:
Shawn Wilsher 2008-07-08 17:25:48 -04:00
parent 7dfd2524b5
commit ad702f184f
2 changed files with 200 additions and 1 deletions

View File

@ -959,6 +959,8 @@ nsDownloadManager::Init()
mObserverService->AddObserver(this, "offline-requested", PR_FALSE);
mObserverService->AddObserver(this, "sleep_notification", PR_FALSE);
mObserverService->AddObserver(this, "wake_notification", PR_FALSE);
mObserverService->AddObserver(this, NS_IOSERVICE_GOING_OFFLINE_TOPIC, PR_FALSE);
mObserverService->AddObserver(this, NS_IOSERVICE_OFFLINE_STATUS_TOPIC, PR_FALSE);
if (history)
(void)history->AddObserver(this, PR_FALSE);
@ -1920,7 +1922,17 @@ nsDownloadManager::Observe(nsISupports *aSubject,
NS_LITERAL_STRING("offlineCancelDownloadsAlertMsgMultiple").get(),
NS_LITERAL_STRING("offlineCancelDownloadsAlertMsg").get(),
NS_LITERAL_STRING("dontGoOfflineButton").get());
} else if (strcmp(aTopic, "alertclickcallback") == 0) {
}
else if (strcmp(aTopic, NS_IOSERVICE_GOING_OFFLINE_TOPIC) == 0) {
// Pause all downloads, and mark them to auto-resume.
(void)PauseAllDownloads(PR_TRUE);
}
else if (strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC) == 0 &&
nsDependentString(aData).EqualsLiteral(NS_IOSERVICE_ONLINE)) {
// We can now resume all downloads that are supposed to auto-resume.
(void)ResumeAllDownloads(PR_FALSE);
}
else if (strcmp(aTopic, "alertclickcallback") == 0) {
nsCOMPtr<nsIDownloadManagerUI> dmui =
do_GetService("@mozilla.org/download-manager-ui;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -0,0 +1,187 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Download Manager Test Code.
*
* The Initial Developer of the Original Code is
* Edward Lee <edward.lee@engineering.uiuc.edu>.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Shawn Wilsher <me@shawnwilsher.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Test bug 437415 by making sure the download manager responds to offline and
* online notifications by pausing and resuming downloads.
*/
/**
* Used to indicate if we should error out or not. See bug 431745 for more
* details.
*/
let doNotError = false;
const nsIF = Ci.nsIFile;
const nsIDM = Ci.nsIDownloadManager;
const nsIWBP = Ci.nsIWebBrowserPersist;
const nsIWPL = Ci.nsIWebProgressListener;
const dm = Cc["@mozilla.org/download-manager;1"].getService(nsIDM);
dm.cleanUp();
function setOnlineState(aOnline)
{
// We do not actually set the offline state because that introduces some neat
// conditions when being called within a listener. We do dispatch the right
// observer topics though, so this tests just the download manager.
let topic = aOnline ?
"network:offline-status-changed" :
"network:offline-about-to-go-offline";
let state = aOnline ? "online" : "offline";
Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService).
notifyObservers(null, topic, state);
}
function run_test()
{
/**
* 1. Create data for http server to send
*/
// data starts at 10 bytes
let data = "1234567890";
// data * 10^4 = 100,000 bytes (actually 101,111 bytes with newline)
for (let i = 0; i < 4; i++)
data = [data,data,data,data,data,data,data,data,data,data,"\n"].join("");
/**
* 2. Start the http server that can handle resume
*/
let httpserv = new nsHttpServer();
let didResumeServer = false;
httpserv.registerPathHandler("/resume", function(meta, resp) {
let body = data;
resp.setHeader("Content-Type", "text/html", false);
if (meta.hasHeader("Range")) {
// track that we resumed for testing
didResumeServer = true;
// Syntax: bytes=[from]-[to] (we don't support multiple ranges)
let matches = meta.getHeader("Range").match(/^\s*bytes=(\d+)?-(\d+)?\s*$/);
let from = (matches[1] === undefined) ? 0 : matches[1];
let to = (matches[2] === undefined) ? data.length - 1 : matches[2];
if (from >= data.length) {
resp.setStatusLine(meta.httpVersion, 416, "Start pos too high");
resp.setHeader("Content-Range", "*/" + data.length);
dump("Returning early - from >= data.length. Not an error (bug 431745)\n");
doNotError = true;
return;
}
body = body.substring(from, to + 1);
// always respond to successful range requests with 206
resp.setStatusLine(meta.httpVersion, 206, "Partial Content");
resp.setHeader("Content-Range", from + "-" + to + "/" + data.length);
}
resp.bodyOutputStream.write(body, body.length);
});
httpserv.start(4444);
/**
* 3. Perform various actions for certain download states
*/
let didPause = false;
let didResumeDownload = false;
dm.addListener({
onDownloadStateChange: function(a, aDl) {
if (aDl.state == nsIDM.DOWNLOAD_DOWNLOADING && !didPause) {
/**
* (1) queued -> downloading = pause the download by going offline
*/
setOnlineState(false);
} else if (aDl.state == nsIDM.DOWNLOAD_PAUSED) {
/**
* (2) downloading -> paused
*/
didPause = true;
} else if (aDl.state == nsIDM.DOWNLOAD_FINISHED) {
/**
* (4) downloading (resumed) -> finished = check tests
*/
// did we pause at all?
do_check_true(didPause);
// did we real-resume and not fake-resume?
do_check_true(didResumeDownload);
// extra real-resume check for the server
do_check_true(didResumeServer);
httpserv.stop();
aDl.targetFile.remove(false);
// we're done with the test!
do_test_finished();
}
else if (aDl.state == nsIDM.DOWNLOAD_FAILED) {
// this is only ok if we are not supposed to fail
do_check_true(doNotError);
httpserv.stop();
// we're done with the test!
do_test_finished();
}
},
onStateChange: function(a, b, aState, d, aDl) {
if ((aState & nsIWPL.STATE_STOP) && didPause && !didResumeServer &&
!didResumeDownload) {
/**
* (3) paused -> stopped = resume the download by coming online
*/
setOnlineState(true);
didResumeDownload = true;
}
},
onProgressChange: function(a, b, c, d, e, f, g) { },
onSecurityChange: function(a, b, c, d) { }
});
dm.addListener(getDownloadListener());
/**
* 4. Start the download
*/
let destFile = dirSvc.get("ProfD", nsIF);
destFile.append("offline_online");
let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
createInstance(nsIWBP);
persist.persistFlags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
nsIWBP.PERSIST_FLAGS_BYPASS_CACHE |
nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
let dl = dm.addDownload(nsIDM.DOWNLOAD_TYPE_DOWNLOAD,
createURI("http://localhost:4444/resume"),
createURI(destFile), null, null,
Math.round(Date.now() * 1000), null, persist);
persist.progressListener = dl.QueryInterface(nsIWPL);
persist.saveURI(dl.source, null, null, null, null, dl.targetFile);
// Mark as pending, so clear this when we actually finish the download
do_test_pending();
}