Merge Fx-team to Mozilla-Central

This commit is contained in:
Carsten "Tomcat" Book 2013-10-29 13:22:29 +01:00
commit 89ad3c0e41
16 changed files with 427 additions and 224 deletions

View File

@ -1186,7 +1186,7 @@ pref("devtools.webconsole.filter.network", true);
pref("devtools.webconsole.filter.networkinfo", true);
pref("devtools.webconsole.filter.netwarn", true);
pref("devtools.webconsole.filter.csserror", true);
pref("devtools.webconsole.filter.cssparser", true);
pref("devtools.webconsole.filter.cssparser", false);
pref("devtools.webconsole.filter.csslog", false);
pref("devtools.webconsole.filter.exception", true);
pref("devtools.webconsole.filter.jswarn", true);

View File

@ -14,7 +14,7 @@ const {AppProjects} = require("devtools/app-manager/app-projects");
const {AppValidator} = require("devtools/app-manager/app-validator");
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
const {installHosted, installPackaged, getTargetForApp} = require("devtools/app-actor-front");
const {installHosted, installPackaged, getTargetForApp, reloadApp} = require("devtools/app-actor-front");
const {EventEmitter} = Cu.import("resource:///modules/devtools/shared/event-emitter.js");
const promise = require("sdk/core/promise");
@ -176,16 +176,26 @@ let UI = {
return this.install(project);
}
})
.then(
() => {
.then(() => {
button.disabled = false;
},
(res) => {
button.disabled = false;
let message = res.error + ": " + res.message;
alert(message);
this.connection.log(message);
});
// Finally try to reload the app if it is already opened
this.reload(project);
},
(res) => {
button.disabled = false;
let message = res.error + ": " + res.message;
alert(message);
this.connection.log(message);
});
},
reload: function (project) {
return reloadApp(this.connection.client,
this.listTabsResponse.webappsActor,
this._getProjectManifestURL(project)).
then(() => {
this.connection.log("App reloaded");
});
},
remove: function(location, event) {

View File

@ -238,7 +238,8 @@
autocompletesearch="history"
autocompletepopup="urlbar-autocomplete"
completeselectedindex="true"
placeholder="&urlbar.emptytext;"/>
placeholder="&urlbar.emptytext;"
onclick="SelectionHelperUI.urlbarClick();"/>
<toolbarbutton id="go-button" class="urlbar-button"
command="cmd_go"/>

View File

@ -25,6 +25,7 @@ var SelectionHandler = {
addMessageListener("Browser:SelectionSwitchMode", this);
addMessageListener("Browser:RepositionInfoRequest", this);
addMessageListener("Browser:SelectionHandlerPing", this);
addMessageListener("Browser:ResetLastPos", this);
},
shutdown: function shutdown() {
@ -44,6 +45,7 @@ var SelectionHandler = {
removeMessageListener("Browser:SelectionSwitchMode", this);
removeMessageListener("Browser:RepositionInfoRequest", this);
removeMessageListener("Browser:SelectionHandlerPing", this);
removeMessageListener("Browser:ResetLastPos", this);
},
sendAsync: function sendAsync(aMsg, aJson) {
@ -543,6 +545,10 @@ var SelectionHandler = {
case "Browser:SelectionHandlerPing":
this._onPing(json.id);
break;
case "Browser:ResetLastPos":
this._onClickCoords(json.xPos, json.yPos);
break;
}
},

View File

@ -792,6 +792,16 @@ var SelectionHelperUI = {
* Event handlers for document events
*/
urlbarClick: function() {
// Workaround for bug 925457: taping browser chrome resets last tap
// co-ordinates to 'undefined' so that we know not to shift the browser
// when the keyboard is up (in SelectionHandler._calcNewContentPosition())
Browser.selectedTab.browser.messageManager.sendAsyncMessage("Browser:ResetLastPos", {
xPos: null,
yPos: null
});
},
/*
* Handles taps that move the current caret around in text edits,
* clear active selection and focus when neccessary, or change

View File

@ -63,7 +63,8 @@
.theme-comment,
.cm-s-mozilla .cm-meta,
.cm-s-mozilla .cm-hr { /* grey */
.cm-s-mozilla .cm-hr,
.cm-s-mozilla .cm-comment { /* grey */
color: #5c6773;
}
@ -79,8 +80,7 @@
.theme-fg-color1,
.cm-s-mozilla .cm-variable-2,
.cm-s-mozilla .cm-quote,
.cm-s-mozilla .CodeMirror-matchingbracket { /* green */
.cm-s-mozilla .cm-quote { /* green */
color: #5c9966;
}
@ -101,8 +101,7 @@
color: #a673bf;
}
.theme-fg-color4,
.cm-s-mozilla .cm-comment { /* purple/violet */
.theme-fg-color4 { /* purple/violet */
color: #6270b2;
}
@ -119,7 +118,6 @@
}
.theme-fg-color7,
.cm-s-mozilla .CodeMirror-nonmatchingbracket,
.cm-s-mozilla .cm-string-2,
.cm-s-mozilla .cm-error { /* Red */
color: #bf5656;
@ -160,12 +158,20 @@
background: rgb(185, 215, 253);
}
.dcm-s-mozilla .CodeMirror-selected { /* selected text (unfocused) */
.cm-s-mozilla .CodeMirror-selected { /* selected text (unfocused) */
background: rgb(176, 176, 176);
}
.CodeMirror-activeline-background { /* selected color with alpha */
background: rgba(185, 215, 253, .05);
background: rgba(185, 215, 253, .15);
}
.cm-s-mozilla .CodeMirror-linenumber { /* line number text */
color: #5f7387;
}
.cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */
border-right-color: #343c45;
}
.cm-s-markup-view pre {

View File

@ -63,7 +63,8 @@
.theme-comment,
.cm-s-mozilla .cm-meta,
.cm-s-mozilla .cm-hr { /* grey */
.cm-s-mozilla .cm-hr,
.cm-s-mozilla .cm-comment { /* grey */
color: hsl(90,2%,46%);
}
@ -79,8 +80,7 @@
.theme-fg-color1,
.cm-s-mozilla .cm-variable-2,
.cm-s-mozilla .cm-quote,
.cm-s-mozilla .CodeMirror-matchingbracket { /* green */
.cm-s-mozilla .cm-quote { /* green */
color: hsl(72,100%,27%);
}
@ -101,8 +101,7 @@
color: hsl(208,81%,21%)
}
.theme-fg-color4,
.cm-s-mozilla .cm-comment { /* Orange */
.theme-fg-color4 { /* Orange */
color: hsl(24,85%,39%);
}
@ -119,7 +118,6 @@
}
.theme-fg-color7,
.cm-s-mozilla .CodeMirror-nonmatchingbracket,
.cm-s-mozilla .cm-string-2,
.cm-s-mozilla .cm-error { /* Red */
color: #bf5656;
@ -165,7 +163,20 @@
}
.CodeMirror-activeline-background { /* selected color with alpha */
background: rgba(185, 215, 253, .4);
background: rgba(185, 215, 253, .35);
}
div.cm-s-mozilla span.CodeMirror-matchingbracket { /* highlight brackets */
outline: solid 1px rgba(0, 0, 0, .25);
color: black;
}
.cm-s-mozilla .CodeMirror-linenumber { /* line number text */
color: #667380;
}
.cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */
border-right-color: #a6a6a6;
}
.cm-s-markup-view pre {

View File

@ -5,7 +5,12 @@
package @ANDROID_PACKAGE_NAME@;
import android.graphics.Bitmap;
import android.util.Base64;
import android.util.Base64OutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
@ -44,6 +49,15 @@ public class PaintedSurface {
return mHeight;
}
private int pixelAtIndex(int index) {
int b1 = mPixelBuffer.get(index) & 0xFF;
int b2 = mPixelBuffer.get(index + 1) & 0xFF;
int b3 = mPixelBuffer.get(index + 2) & 0xFF;
int b4 = mPixelBuffer.get(index + 3) & 0xFF;
int value = (b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0);
return value;
}
public final int getPixelAt(int x, int y) {
if (mPixelBuffer == null) {
throw new RoboCopException("Trying to access PaintedSurface with no active PixelBuffer");
@ -60,12 +74,27 @@ public class PaintedSurface {
// The rows are reversed so row 0 is at the end and we start with the last row.
// This is why we do mHeight-y;
int index = (x + ((mHeight - y - 1) * mWidth)) * 4;
int b1 = mPixelBuffer.get(index) & 0xFF;
int b2 = mPixelBuffer.get(index + 1) & 0xFF;
int b3 = mPixelBuffer.get(index + 2) & 0xFF;
int b4 = mPixelBuffer.get(index + 3) & 0xFF;
int value = (b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0);
return value;
return pixelAtIndex(index);
}
public final String asDataUri() {
try {
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
for (int y = 0; y < mHeight; y++) {
for (int x = 0; x < mWidth; x++) {
int index = (x + ((mHeight - y - 1) * mWidth)) * 4;
bm.setPixel(x, y, pixelAtIndex(index));
}
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write("data:image/png;base64,".getBytes());
Base64OutputStream b64 = new Base64OutputStream(out, Base64.NO_WRAP);
bm.compress(Bitmap.CompressFormat.PNG, 100, b64);
return new String(out.toByteArray());
} catch (Exception e) {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
throw new RoboCopException("Unable to convert surface to a PNG data:uri");
}
}
public void close() {

View File

@ -1161,26 +1161,18 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
values.put(Bookmarks.POSITION, position);
values.put(Bookmarks.IS_DELETED, 0);
// If this site is already pinned, unpin it
cr.delete(mBookmarksUriWithProfile,
Bookmarks.PARENT + " == ? AND " + Bookmarks.URL + " == ?",
new String[] {
String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID),
url
});
// If something is already pinned in this spot update it
int updated = cr.update(mBookmarksUriWithProfile,
values,
Bookmarks.POSITION + " = ? AND " +
Bookmarks.PARENT + " = ?",
new String[] { Integer.toString(position),
String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID) });
// Otherwise just insert a new item
if (updated == 0) {
cr.insert(mBookmarksUriWithProfile, values);
}
// We do an update-and-replace here without deleting any existing pins for the given URL.
// That means if the user pins a URL, then edits another thumbnail to use the same URL,
// we'll end up with two pins for that site. This is the intended behavior, which
// incidentally saves us a delete query.
Uri uri = mBookmarksUriWithProfile.buildUpon()
.appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
cr.update(uri,
values,
Bookmarks.POSITION + " = ? AND " +
Bookmarks.PARENT + " = ?",
new String[] { Integer.toString(position),
String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID) });
}
@Override

View File

@ -14,7 +14,7 @@ interface nsIDOMNode;
* tabs contained in them.
*/
[scriptable, uuid(15152edf-6c99-4277-9020-076be4653c69)]
[scriptable, uuid(fe116b56-0226-4562-b52a-a623dad07ead)]
interface nsISessionStore : nsISupports
{
/**

View File

@ -253,3 +253,24 @@ function getTargetForApp(client, webappsActor, manifestURL) {
}
exports.getTargetForApp = getTargetForApp;
function reloadApp(client, webappsActor, manifestURL) {
let deferred = promise.defer();
getTargetForApp(client,
webappsActor,
manifestURL).
then((target) => {
// Request the ContentAppActor to reload the app
let request = {
to: target.form.actor,
type: "reload",
manifestURL: manifestURL
};
client.request(request, (res) => {
deferred.resolve();
});
}, () => {
deferred.reject("Not running");
});
return deferred.promise;
}
exports.reloadApp = reloadApp;

View File

@ -418,12 +418,41 @@ WebappsActor.prototype = {
zipFile.moveTo(installDir, "application.zip");
let origin = "app://" + id;
let manifestURL = origin + "/manifest.webapp";
// Refresh application.zip content (e.g. reinstall app), as done here:
// http://hg.mozilla.org/mozilla-central/annotate/aaefec5d34f8/dom/apps/src/Webapps.jsm#l1125
// Do it in parent process for the simulator
let jar = installDir.clone();
jar.append("application.zip");
Services.obs.notifyObservers(jar, "flush-cache-entry", null);
// And then in app content process
// This function will be evaluated in the scope of the content process
// frame script. That will flush the jar cache for this app and allow
// loading fresh updated resources if we reload its document.
let FlushFrameScript = function (path) {
let jar = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
jar.initWithPath(path);
let obs = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
obs.notifyObservers(jar, "flush-cache-entry", null);
};
for each (let frame in self._appFrames()) {
if (frame.getAttribute("mozapp") == manifestURL) {
let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
mm.loadFrameScript("data:," +
encodeURIComponent("(" + FlushFrameScript.toString() + ")" +
"('" + jar.path + "')"), false);
}
}
// Create a fake app object with the minimum set of properties we need.
let app = {
origin: origin,
installOrigin: origin,
manifestURL: origin + "/manifest.webapp",
manifestURL: manifestURL,
appStatus: appType,
receipts: aReceipts,
}
@ -739,6 +768,10 @@ WebappsActor.prototype = {
},
_appFrames: function () {
// For now, we only support app frames on b2g
if (Services.appinfo.ID != "{3c2e2abc-06d4-11e1-ac3b-374f68613e61}") {
return;
}
// Register the system app
let chromeWindow = Services.wm.getMostRecentWindow('navigator:browser');
let systemAppFrame = chromeWindow.shell.contentBrowser;

View File

@ -0,0 +1,215 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
var gNextRunFunc;
var gExpectedStatusResult;
function run_test() {
setupTestCommon(true);
logTestInfo("testing mar download and mar hash verification");
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
// The HTTP server is only used for the mar file downloads since it is slow
start_httpserver();
setUpdateURLOverride(gURLData + "update.xml");
// The mock XMLHttpRequest is MUCH faster
overrideXHR(callHandleEvent);
standardInit();
do_execute_soon(run_test_pt1);
}
// The HttpServer must be stopped before calling do_test_finished
function finish_test() {
stop_httpserver(do_test_finished);
}
function end_test() {
cleanupTestCommon();
}
// Callback function used by the custom XMLHttpRequest implementation to
// call the nsIDOMEventListener's handleEvent method for onload.
function callHandleEvent() {
gXHR.status = 400;
gXHR.responseText = gResponseBody;
try {
var parser = AUS_Cc["@mozilla.org/xmlextras/domparser;1"].
createInstance(AUS_Ci.nsIDOMParser);
gXHR.responseXML = parser.parseFromString(gResponseBody, "application/xml");
}
catch(e) {
}
var e = { target: gXHR };
gXHR.onload(e);
}
// Helper function for testing mar downloads that have the correct size
// specified in the update xml.
function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
gUpdates = null;
gUpdateCount = null;
gStatusResult = null;
gCheckFunc = check_test_helper_pt1_1;
gNextRunFunc = aNextRunFunc;
gExpectedStatusResult = aExpectedStatusResult;
logTestInfo(aMsg, Components.stack.caller);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_helper_pt1_1() {
do_check_eq(gUpdateCount, 1);
gCheckFunc = check_test_helper_pt1_2;
var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
var state = gAUS.downloadUpdate(bestUpdate, false);
if (state == STATE_NONE || state == STATE_FAILED)
do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
gAUS.addDownloadListener(downloadListener);
}
function check_test_helper_pt1_2() {
do_check_eq(gStatusResult, gExpectedStatusResult);
gAUS.removeDownloadListener(downloadListener);
gNextRunFunc();
}
// The following 3 functions are a workaround for GONK due to Bug 828858 and
// can be removed after it is fixed and the callers are changed to use the
// regular helper functions.
function run_test_helper_bug828858_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
gUpdates = null;
gUpdateCount = null;
gStatusResult = null;
gCheckFunc = check_test_helper_bug828858_pt1_1;
gNextRunFunc = aNextRunFunc;
gExpectedStatusResult = aExpectedStatusResult;
logTestInfo(aMsg, Components.stack.caller);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_helper_bug828858_pt1_1() {
do_check_eq(gUpdateCount, 1);
gCheckFunc = check_test_helper_bug828858_pt1_2;
var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
var state = gAUS.downloadUpdate(bestUpdate, false);
if (state == STATE_NONE || state == STATE_FAILED)
do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
gAUS.addDownloadListener(downloadListener);
}
function check_test_helper_bug828858_pt1_2() {
if (gStatusResult == AUS_Cr.NS_ERROR_CONTENT_CORRUPTED) {
do_check_eq(gStatusResult, AUS_Cr.NS_ERROR_CONTENT_CORRUPTED);
} else {
do_check_eq(gStatusResult, gExpectedStatusResult);
}
gAUS.removeDownloadListener(downloadListener);
gNextRunFunc();
}
function setResponseBody(aHashFunction, aHashValue, aSize) {
var patches = getRemotePatchString(null, null,
aHashFunction, aHashValue, aSize);
var updates = getRemoteUpdateString(patches);
gResponseBody = getRemoteUpdatesXMLString(updates);
}
// mar download with a valid MD5 hash
function run_test_pt1() {
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid MD5 hash",
AUS_Cr.NS_OK, run_test_pt2);
}
// mar download with an invalid MD5 hash
function run_test_pt2() {
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid MD5 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt3);
}
// mar download with a valid SHA1 hash
function run_test_pt3() {
setResponseBody("SHA1", SHA1_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA1 hash",
AUS_Cr.NS_OK, run_test_pt4);
}
// mar download with an invalid SHA1 hash
function run_test_pt4() {
setResponseBody("SHA1", SHA1_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA1 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt5);
}
// mar download with a valid SHA256 hash
function run_test_pt5() {
setResponseBody("SHA256", SHA256_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA256 hash",
AUS_Cr.NS_OK, run_test_pt6);
}
// mar download with an invalid SHA256 hash
function run_test_pt6() {
setResponseBody("SHA256", SHA256_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA256 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt7);
}
// mar download with a valid SHA384 hash
function run_test_pt7() {
setResponseBody("SHA384", SHA384_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA384 hash",
AUS_Cr.NS_OK, run_test_pt8);
}
// mar download with an invalid SHA384 hash
function run_test_pt8() {
setResponseBody("SHA384", SHA384_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA384 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt9);
}
// mar download with a valid SHA512 hash
function run_test_pt9() {
setResponseBody("SHA512", SHA512_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA512 hash",
AUS_Cr.NS_OK, run_test_pt10);
}
// mar download with an invalid SHA512 hash
function run_test_pt10() {
setResponseBody("SHA512", SHA512_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA512 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt11);
}
// mar download with the mar not found
function run_test_pt11() {
var patches = getRemotePatchString(null, gURLData + "missing.mar");
var updates = getRemoteUpdateString(patches);
gResponseBody = getRemoteUpdatesXMLString(updates);
run_test_helper_pt1("mar download with the mar not found",
AUS_Cr.NS_ERROR_UNEXPECTED, run_test_pt12);
}
// mar download with a valid MD5 hash but invalid file size
function run_test_pt12() {
const arbitraryFileSize = 1024000;
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR, arbitraryFileSize);
if (IS_TOOLKIT_GONK) {
// There seems to be a race on the web server side when the patchFile is
// stored on the SDCard. Sometimes, the webserver will serve up an error
// 416 and the contents of the file, and sometimes it will serve up an error
// 200 and no contents. This can cause either NS_ERROR_UNEXPECTED or
// NS_ERROR_CONTENT_CORRUPTED.
// Bug 828858 was filed to follow up on this issue.
run_test_helper_bug828858_pt1("mar download with a valid MD5 hash but invalid file size",
AUS_Cr.NS_ERROR_UNEXPECTED, finish_test);
} else {
run_test_helper_pt1("mar download with a valid MD5 hash but invalid file size",
AUS_Cr.NS_ERROR_UNEXPECTED, finish_test);
}
}

View File

@ -7,15 +7,14 @@
const INC_CONTRACT_ID = "@mozilla.org/network/incremental-download;1";
var gNextRunFunc;
var gStatusResult;
var gExpectedStatusResult;
var gIncrementalDownloadClassID, gIncOldFactory;
// gIncrementalDownloadErrorType is used to loop through each of the connection
// error types in the Mock incremental downloader.
var gIncrementalDownloadErrorType = 0;
var gNextRunFunc;
var gExpectedStatusResult;
function run_test() {
setupTestCommon(true);
@ -87,40 +86,6 @@ function check_test_helper_pt1_2() {
gNextRunFunc();
}
// The following 3 functions are a workaround for GONK due to Bug 828858 and
// can be removed after it is fixed and the callers are changed to use the
// regular helper functions.
function run_test_helper_bug828858_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
gUpdates = null;
gUpdateCount = null;
gStatusResult = null;
gCheckFunc = check_test_helper_bug828858_pt1_1;
gNextRunFunc = aNextRunFunc;
gExpectedStatusResult = aExpectedStatusResult;
logTestInfo(aMsg, Components.stack.caller);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_helper_bug828858_pt1_1() {
do_check_eq(gUpdateCount, 1);
gCheckFunc = check_test_helper_bug828858_pt1_2;
var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
var state = gAUS.downloadUpdate(bestUpdate, false);
if (state == STATE_NONE || state == STATE_FAILED)
do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
gAUS.addDownloadListener(downloadListener);
}
function check_test_helper_bug828858_pt1_2() {
if (gStatusResult == AUS_Cr.NS_ERROR_CONTENT_CORRUPTED) {
do_check_eq(gStatusResult, AUS_Cr.NS_ERROR_CONTENT_CORRUPTED);
} else {
do_check_eq(gStatusResult, gExpectedStatusResult);
}
gAUS.removeDownloadListener(downloadListener);
gNextRunFunc();
}
function setResponseBody(aHashFunction, aHashValue, aSize) {
var patches = getRemotePatchString(null, null,
aHashFunction, aHashValue, aSize);
@ -128,104 +93,6 @@ function setResponseBody(aHashFunction, aHashValue, aSize) {
gResponseBody = getRemoteUpdatesXMLString(updates);
}
// mar download with a valid MD5 hash
function run_test_pt1() {
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid MD5 hash",
AUS_Cr.NS_OK, run_test_pt2);
}
// mar download with an invalid MD5 hash
function run_test_pt2() {
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid MD5 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt3);
}
// mar download with a valid SHA1 hash
function run_test_pt3() {
setResponseBody("SHA1", SHA1_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA1 hash",
AUS_Cr.NS_OK, run_test_pt4);
}
// mar download with an invalid SHA1 hash
function run_test_pt4() {
setResponseBody("SHA1", SHA1_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA1 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt5);
}
// mar download with a valid SHA256 hash
function run_test_pt5() {
setResponseBody("SHA256", SHA256_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA256 hash",
AUS_Cr.NS_OK, run_test_pt6);
}
// mar download with an invalid SHA256 hash
function run_test_pt6() {
setResponseBody("SHA256", SHA256_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA256 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt7);
}
// mar download with a valid SHA384 hash
function run_test_pt7() {
setResponseBody("SHA384", SHA384_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA384 hash",
AUS_Cr.NS_OK, run_test_pt8);
}
// mar download with an invalid SHA384 hash
function run_test_pt8() {
setResponseBody("SHA384", SHA384_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA384 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt9);
}
// mar download with a valid SHA512 hash
function run_test_pt9() {
setResponseBody("SHA512", SHA512_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with a valid SHA512 hash",
AUS_Cr.NS_OK, run_test_pt10);
}
// mar download with an invalid SHA384 hash
function run_test_pt10() {
setResponseBody("SHA512", SHA512_HASH_SIMPLE_MAR + "0");
run_test_helper_pt1("mar download with an invalid SHA512 hash",
AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt11);
}
// mar download with the mar not found
function run_test_pt11() {
var patches = getRemotePatchString(null, gURLData + "missing.mar");
var updates = getRemoteUpdateString(patches);
gResponseBody = getRemoteUpdatesXMLString(updates);
run_test_helper_pt1("mar download with the mar not found",
AUS_Cr.NS_ERROR_UNEXPECTED, run_test_pt12);
}
// mar download with a valid MD5 hash but invalid file size
function run_test_pt12() {
const arbitraryFileSize = 1024000;
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR, arbitraryFileSize);
if (IS_TOOLKIT_GONK) {
// There seems to be a race on the web server side when the patchFile is
// stored on the SDCard. Sometimes, the webserver will serve up an error
// 416 and the contents of the file, and sometimes it will serve up an error
// 200 and no contents. This can cause either NS_ERROR_UNEXPECTED or
// NS_ERROR_CONTENT_CORRUPTED.
// Bug 828858 was filed to follow up on this issue.
run_test_helper_bug828858_pt1("mar download with a valid MD5 hash but invalid file size",
AUS_Cr.NS_ERROR_UNEXPECTED, run_test_pt13);
} else {
run_test_helper_pt1("mar download with a valid MD5 hash but invalid file size",
AUS_Cr.NS_ERROR_UNEXPECTED, run_test_pt13);
}
}
var newFactory = {
createInstance: function(aOuter, aIID) {
if (aOuter)
@ -263,7 +130,7 @@ function cleanupMockIncrementalDownload() {
* interrupts work correctly in updater code. The implementation of
* the mock incremental downloader is very simple, it simply copies
* the file to the destination location.
*/
*/
function IncrementalDownload() {
this.wrappedJSObject = this;
@ -379,15 +246,15 @@ IncrementalDownload.prototype = {
}
// Test disconnecting during an update
function run_test_pt13() {
function run_test_pt1() {
initMockIncrementalDownload();
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with connection interruption",
AUS_Cr.NS_OK, run_test_pt14);
AUS_Cr.NS_OK, run_test_pt2);
}
// Test disconnecting during an update
function run_test_pt14() {
function run_test_pt2() {
gIncrementalDownloadErrorType = 0;
Services.prefs.setIntPref(PREF_APP_UPDATE_SOCKET_ERRORS, 2);
Services.prefs.setIntPref(PREF_APP_UPDATE_RETRY_TIMEOUT, 0);
@ -404,39 +271,13 @@ function run_test_pt14() {
expectedResult = AUS_Cr.NS_ERROR_NET_RESET;
}
run_test_helper_pt1("mar download with connection interruption without recovery",
expectedResult, run_test_pt15);
expectedResult, run_test_pt3);
}
// Test entering offline mode while downloading
function run_test_pt15() {
function run_test_pt3() {
gIncrementalDownloadErrorType = 4;
setResponseBody("MD5", MD5_HASH_SIMPLE_MAR);
run_test_helper_pt1("mar download with offline mode",
AUS_Cr.NS_OK, finish_test);
}
/* Update download listener - nsIRequestObserver */
const downloadListener = {
onStartRequest: function DL_onStartRequest(request, context) {
},
onProgress: function DL_onProgress(request, context, progress, maxProgress) {
},
onStatus: function DL_onStatus(request, context, status, statusText) {
},
onStopRequest: function DL_onStopRequest(request, context, status) {
gStatusResult = status;
// Use a timeout to allow the request to complete
do_execute_soon(gCheckFunc);
},
QueryInterface: function DL_QueryInterface(iid) {
if (!iid.equals(AUS_Ci.nsIRequestObserver) &&
!iid.equals(AUS_Ci.nsIProgressEventSink) &&
!iid.equals(AUS_Ci.nsISupports))
throw AUS_Cr.NS_ERROR_NO_INTERFACE;
return this;
}
};

View File

@ -147,6 +147,7 @@ var gUpdateCount;
var gUpdates;
var gStatusCode;
var gStatusText;
var gStatusResult;
// Variables are used instead of contants so tests can override these values
var gCallbackBinFile = "callback_app" + BIN_SUFFIX;
@ -1951,6 +1952,32 @@ const updateCheckListener = {
}
};
/* Update download listener - nsIRequestObserver */
const downloadListener = {
onStartRequest: function DL_onStartRequest(request, context) {
},
onProgress: function DL_onProgress(request, context, progress, maxProgress) {
},
onStatus: function DL_onStatus(request, context, status, statusText) {
},
onStopRequest: function DL_onStopRequest(request, context, status) {
gStatusResult = status;
// Use a timeout to allow the request to complete
do_execute_soon(gCheckFunc);
},
QueryInterface: function DL_QueryInterface(aIID) {
if (!aIID.equals(AUS_Ci.nsIRequestObserver) &&
!aIID.equals(AUS_Ci.nsIProgressEventSink) &&
!aIID.equals(AUS_Ci.nsISupports))
throw AUS_Cr.NS_ERROR_NO_INTERFACE;
return this;
}
};
/**
* Helper for starting the http server used by the tests
*/

View File

@ -12,7 +12,7 @@ generated-files = head_update.js
[updateCheckOnLoadOnErrorStatusText.js]
[updateManagerXML.js]
[remoteUpdateXML.js]
[downloadMar.js]
[downloadAndHashCheckMar.js]
[cleanupDownloadingForOlderAppVersion.js]
[cleanupDownloadingForDifferentChannel.js]
[cleanupDownloadingForSameVersionAndBuildID.js]
@ -20,6 +20,7 @@ generated-files = head_update.js
[cleanupPendingVersionFileIncorrectStatus.js]
[cleanupSuccessLogMove.js]
[cleanupSuccessLogsFIFO.js]
[downloadInterruptedRecovery.js]
[downloadResumeForSameAppVersion.js]
[downloadCompleteAfterPartialFailure.js]
skip-if = toolkit == 'gonk'