Merge m-c to inbound

This commit is contained in:
Wes Kocher 2013-10-01 18:54:45 -07:00
commit f16d44a104
61 changed files with 6456 additions and 634 deletions

View File

@ -1,4 +1,4 @@
{
"revision": "aa012c91dbe05dbcdcc7a29cae8ad3e35f8fcdec",
"revision": "f175ff82509151d5b4fe45e145199cc2dd710cbc",
"repo_path": "/integration/gaia-central"
}

View File

@ -20,6 +20,9 @@ support-files =
code_script-switching-02.js
code_test-editor-mode
code_ugly.js
code_ugly-2.js
code_ugly-3.js
code_ugly-4.js
doc_binary_search.html
doc_blackboxing.html
doc_closures.html
@ -41,6 +44,7 @@ support-files =
doc_minified.html
doc_pause-exceptions.html
doc_pretty-print.html
doc_pretty-print-2.html
doc_recursion-stack.html
doc_script-switching-01.html
doc_script-switching-02.html
@ -104,6 +108,9 @@ support-files =
[browser_dbg_pretty-print-04.js]
[browser_dbg_pretty-print-05.js]
[browser_dbg_pretty-print-06.js]
[browser_dbg_pretty-print-07.js]
[browser_dbg_pretty-print-08.js]
[browser_dbg_pretty-print-09.js]
[browser_dbg_progress-listener-bug.js]
[browser_dbg_reload-preferred-script-01.js]
[browser_dbg_reload-preferred-script-02.js]

View File

@ -0,0 +1,46 @@
/* -*- Mode: javascript; js-indent-level: 2; -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test basic pretty printing functionality. Would be an xpcshell test, except
// for bug 921252.
let gTab, gDebuggee, gPanel, gClient, gThreadClient;
const TAB_URL = EXAMPLE_URL + "doc_pretty-print-2.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gClient = gPanel.panelWin.gClient;
gThreadClient = gPanel.panelWin.DebuggerController.activeThread;
findSource();
});
}
function findSource() {
gThreadClient.getSources(({ error, sources }) => {
ok(!error);
sources = sources.filter(s => s.url.contains('code_ugly-2.js'));
is(sources.length, 1);
prettyPrintSource(sources[0]);
});
}
function prettyPrintSource(source) {
gThreadClient.source(source).prettyPrint(4, testPrettyPrinted);
}
function testPrettyPrinted({ error, source}) {
ok(!error);
ok(source.contains("\n "));
closeDebuggerAndFinish(gPanel);
}
registerCleanupFunction(function() {
gTab = gDebuggee = gPanel = gClient = gThreadClient = null;
});

View File

@ -0,0 +1,95 @@
/* -*- Mode: javascript; js-indent-level: 2; -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test stepping through pretty printed sources.
let gTab, gDebuggee, gPanel, gClient, gThreadClient, gSource;
const TAB_URL = EXAMPLE_URL + "doc_pretty-print-2.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gClient = gPanel.panelWin.gClient;
gThreadClient = gPanel.panelWin.DebuggerController.activeThread;
gDebuggee.noop = x => x;
findSource();
});
}
let CODE_URL;
const BP_LOCATION = {
line: 5,
column: 11
};
function findSource() {
gThreadClient.getSources(({ error, sources }) => {
ok(!error);
sources = sources.filter(s => s.url.contains("code_ugly-3.js"));
is(sources.length, 1);
[gSource] = sources;
CODE_URL = BP_LOCATION.url = gSource.url;
prettyPrintSource(sources[0]);
});
}
function prettyPrintSource(source) {
gThreadClient.source(gSource).prettyPrint(2, runCode);
}
function runCode({ error }) {
ok(!error);
gClient.addOneTimeListener("paused", testDbgStatement);
gDebuggee.main3();
}
function testDbgStatement(event, { why, frame }) {
is(why.type, "debuggerStatement");
const { url, line, column } = frame.where;
is(url, CODE_URL);
is(line, 3);
setBreakpoint();
}
function setBreakpoint() {
gThreadClient.setBreakpoint(BP_LOCATION, ({ error, actualLocation }) => {
ok(!error);
ok(!actualLocation);
testStepping();
});
}
function testStepping() {
gClient.addOneTimeListener("paused", (event, { why, frame }) => {
is(why.type, "resumeLimit");
const { url, line } = frame.where;
is(url, CODE_URL);
is(line, 4);
testHitBreakpoint();
});
gThreadClient.stepIn();
}
function testHitBreakpoint() {
gClient.addOneTimeListener("paused", (event, { why, frame }) => {
is(why.type, "breakpoint");
const { url, line, column } = frame.where;
is(url, CODE_URL);
is(line, BP_LOCATION.line);
is(column, BP_LOCATION.column);
resumeDebuggerThenCloseAndFinish(gPanel);
});
gThreadClient.resume();
}
registerCleanupFunction(function() {
gTab = gDebuggee = gPanel = gClient = gThreadClient = gSource = null;
});

View File

@ -0,0 +1,73 @@
/* -*- Mode: javascript; js-indent-level: 2; -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test pretty printing source mapped sources.
var gDebuggee;
var gClient;
var gThreadClient;
var gSource;
let gTab, gDebuggee, gPanel, gClient, gThreadClient;
const TAB_URL = EXAMPLE_URL + "doc_pretty-print-2.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gClient = gPanel.panelWin.gClient;
gThreadClient = gPanel.panelWin.DebuggerController.activeThread;
findSource();
});
}
const dataUrl = s => "data:text/javascript," + s;
// These should match the instructions in code_ugly-4.js.
const A = "function a(){b()}";
const A_URL = dataUrl(A);
const B = "function b(){debugger}";
const B_URL = dataUrl(B);
function findSource() {
gThreadClient.getSources(({ error, sources }) => {
ok(!error);
sources = sources.filter(s => s.url === B_URL);
is(sources.length, 1);
prettyPrint(sources[0]);
});
}
function prettyPrint(source) {
gThreadClient.source(source).prettyPrint(2, runCode);
}
function runCode({ error }) {
ok(!error);
gClient.addOneTimeListener("paused", testDbgStatement);
gDebuggee.a();
}
function testDbgStatement(event, { frame, why }) {
dump("FITZGEN: inside testDbgStatement\n");
try {
is(why.type, "debuggerStatement");
const { url, line, column } = frame.where;
is(url, B_URL);
is(line, 2);
is(column, 2);
resumeDebuggerThenCloseAndFinish(gPanel);
} catch (e) {
dump("FITZGEN: got an error! " + DevToolsUtils.safeErrorString(e) + "\n");
}
}
registerCleanupFunction(function() {
gTab = gDebuggee = gPanel = gClient = gThreadClient = null;
});

View File

@ -0,0 +1 @@
function main2() { var a = 1 + 3; var b = a++; return b + a; }

View File

@ -0,0 +1 @@
function main3() { var a = 1; debugger; noop(a); return 10; };

View File

@ -0,0 +1,24 @@
function a(){b()}function b(){debugger}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJjLmpzIiwic291cmNlcyI6WyJkYXRhOnRleHQvamF2YXNjcmlwdCxmdW5jdGlvbiBhKCl7YigpfSIsImRhdGE6dGV4dC9qYXZhc2NyaXB0LGZ1bmN0aW9uIGIoKXtkZWJ1Z2dlcn0iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaUJDQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMifQ==
// Generate this file by evaluating the following in a browser-environment
// scratchpad:
//
// Components.utils.import('resource://gre/modules/devtools/SourceMap.jsm');
//
// let dataUrl = s => "data:text/javascript," + s;
//
// let A = "function a(){b()}";
// let A_URL = dataUrl(A);
// let B = "function b(){debugger}";
// let B_URL = dataUrl(B);
//
// let result = (new SourceNode(null, null, null, [
// new SourceNode(1, 0, A_URL, A),
// B.split("").map((ch, i) => new SourceNode(1, i, B_URL, ch))
// ])).toStringWithSourceMap({
// file: "abc.js"
// });
//
// result.code + "\n//# sourceMappingURL=data:application/json;base64," + btoa(JSON.stringify(result.map));

View File

@ -0,0 +1,10 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE html>
<head>
<meta charset="utf-8"/>
<title>Debugger Pretty Printing Test Page</title>
</head>
<script src="code_ugly-2.js"></script>
<script src="code_ugly-3.js"></script>
<script src="code_ugly-4.js"></script>

View File

@ -267,6 +267,43 @@ let Util = {
return this.displayDPI = this.getWindowUtils(window).displayDPI;
},
/*
* aViewHeight - the height of the viewable area in the browser
* aRect - a bounding rectangle of a selection or element.
*
* return - number of pixels for the browser to be shifted up by such
* that aRect is centered vertically within aViewHeight.
*/
centerElementInView: function centerElementInView(aViewHeight, aRect) {
// If the bottom of the target bounds is higher than the new height,
// there's no need to adjust. It will be above the keyboard.
if (aRect.bottom <= aViewHeight) {
return 0;
}
// height of the target element
let targetHeight = aRect.bottom - aRect.top;
// height of the browser view.
let viewBottom = content.innerHeight;
// If the target is shorter than the new content height, we can go ahead
// and center it.
if (targetHeight <= aViewHeight) {
// Try to center the element vertically in the new content area, but
// don't position such that the bottom of the browser view moves above
// the top of the chrome. We purposely do not resize the browser window
// by making it taller when trying to center elements that are near the
// lower bounds. This would trigger reflow which can cause content to
// shift around.
let splitMargin = Math.round((aViewHeight - targetHeight) * .5);
let distanceToPageBounds = viewBottom - aRect.bottom;
let distanceFromChromeTop = aRect.bottom - aViewHeight;
let distanceToCenter =
distanceFromChromeTop + Math.min(distanceToPageBounds, splitMargin);
return distanceToCenter;
}
},
/*
* Local system utilities
*/

View File

@ -68,6 +68,16 @@ var FindHandler = {
let rangeRect = selection.getRangeAt(0).getBoundingClientRect();
let rect = new Rect(scroll.x + rangeRect.left, scroll.y + rangeRect.top, rangeRect.width, rangeRect.height);
let aNewViewHeight = content.innerHeight - Services.metro.keyboardHeight;
let position = Util.centerElementInView(aNewViewHeight, rangeRect);
if (position !== undefined) {
sendAsyncMessage("Content:RepositionInfoResponse", {
reposition: true,
raiseContent: position,
});
}
// Ensure the potential "scroll" event fired during a search as already fired
let timer = new Util.Timeout(function() {
sendAsyncMessage("FindAssist:Show", { rect: rect.isEmpty() ? null: rect , result: findResult });

View File

@ -427,32 +427,9 @@ var SelectionHandler = {
return 0;
}
// If the bottom of the target bounds is higher than the new height,
// there's no need to adjust. It will be above the keyboard.
if (this._cache.element.bottom <= aNewViewHeight) {
return 0;
}
// height of the target element
let targetHeight = this._cache.element.bottom - this._cache.element.top;
// height of the browser view.
let viewBottom = content.innerHeight;
// If the target is shorter than the new content height, we can go ahead
// and center it.
if (targetHeight <= aNewViewHeight) {
// Try to center the element vertically in the new content area, but
// don't position such that the bottom of the browser view moves above
// the top of the chrome. We purposely do not resize the browser window
// by making it taller when trying to center elements that are near the
// lower bounds. This would trigger reflow which can cause content to
// shift around.
let splitMargin = Math.round((aNewViewHeight - targetHeight) * .5);
let distanceToPageBounds = viewBottom - this._cache.element.bottom;
let distanceFromChromeTop = this._cache.element.bottom - aNewViewHeight;
let distanceToCenter =
distanceFromChromeTop + Math.min(distanceToPageBounds, splitMargin);
return distanceToCenter;
let position = Util.centerElementInView(aNewViewHeight, this._cache.element);
if (position !== undefined) {
return position;
}
// Special case: we are dealing with an input that is taller than the

View File

@ -153,12 +153,10 @@ var FindHelperUI = {
},
goToPrevious: function findHelperGoToPrevious() {
this._textbox.blur();
Browser.selectedBrowser.messageManager.sendAsyncMessage("FindAssist:Previous", { });
},
goToNext: function findHelperGoToNext() {
this._textbox.blur();
Browser.selectedBrowser.messageManager.sendAsyncMessage("FindAssist:Next", { });
},

View File

@ -8,17 +8,17 @@ dir-tests := $(DEPTH)/$(mobile-tests)
ANDROID_APK_NAME := robocop-debug
ROBOTIUM_PATH = $(srcdir)/robotium-solo-4.2.jar
JAVAFILES = \
R.java \
ANDROID_EXTRA_JARS += \
$(srcdir)/robotium-solo-4.2.jar \
$(NULL)
ANDROID_RESFILES = \
res/values/strings.xml \
$(NULL)
_JAVA_HARNESS = \
ANDROID_ASSETS_DIR := $(TESTPATH)/assets
_JAVA_HARNESS := \
Actions.java \
Assert.java \
Driver.java \
@ -51,7 +51,6 @@ PP_TARGETS += manifest
manifest := $(srcdir)/AndroidManifest.xml.in
manifest_TARGET := AndroidManifest.xml
# Install robocop configs and helper
INSTALL_TARGETS += robocop
robocop_TARGET := libs
@ -75,50 +74,25 @@ MOCHITEST_ROBOCOP_FILES := \
GARBAGE += \
AndroidManifest.xml \
$(java-tests-dep) \
$(_JAVA_HARNESS) \
classes.dex \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(java-harness-dep) \
$(robocop-deps) \
$(NULL)
JAVAFILES += \
$(robocop-deps) \
$(java-harness-dep) \
$(java-tests-dep) \
$(NULL)
DEFINES += \
-DANDROID_PACKAGE_NAME=$(ANDROID_PACKAGE_NAME) \
$(NULL)
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar:$(ROBOTIUM_PATH)
include $(topsrcdir)/config/rules.mk
# Override rules.mk java flags with the android specific ones
include $(topsrcdir)/config/android-common.mk
GENERATED_DIRS_tools = classes $(dir-tests)
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(ANDROID_APK_NAME).ap_
classes.dex: $(robocop-deps)
classes.dex: $(java-harness-dep)
classes.dex: $(java-tests-dep)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(java-tests-dep)
$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH) $(ANDROID_COMPT_LIB)
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml $(TESTPATH)/assets/*
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@
GENERATED_DIRS += $(dir-tests)
# PP_java-tests not fully usable here
# Intermediate step toward a library rule.

View File

@ -18,7 +18,6 @@ JAVAFILES = \
RunDataThread.java \
SUTAgentAndroid.java \
WifiConfiguration.java \
R.java \
$(NULL)
ANDROID_RESFILES = \
@ -31,42 +30,11 @@ ANDROID_RESFILES = \
res/values/strings.xml \
$(NULL)
GARBAGE += \
AndroidManifest.xml \
classes.dex \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
ANDROID_EXTRA_JARS = \
$(srcdir)/network-libs/commons-net-2.0.jar \
$(srcdir)/network-libs/jmdns.jar \
$(NULL)
GARBAGE_DIRS += network-libs
EXTRA_JARS = $(srcdir)/network-libs/commons-net-2.0.jar:$(srcdir)/network-libs/jmdns.jar
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar:$(EXTRA_JARS)
include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes $(subst :, ,$(EXTRA_JARS))
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -1,37 +0,0 @@
/* 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/. */
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.mozilla.SUTAgentAndroid;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int ateamlogo=0x7f020000;
public static final int ic_stat_first=0x7f020001;
public static final int ic_stat_neterror=0x7f020002;
public static final int ic_stat_second=0x7f020003;
public static final int ic_stat_warning=0x7f020004;
public static final int icon=0x7f020005;
}
public static final class id {
public static final int Button01=0x7f050001;
public static final int Textview01=0x7f050000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int foreground_service_started=0x7f040002;
public static final int hello=0x7f040000;
}
}

View File

@ -9,7 +9,6 @@ JAVAFILES = \
FenCP.java \
FenCPFP.java \
FileCursor.java \
R.java \
$(NULL)
ANDROID_RESFILES = \
@ -20,40 +19,6 @@ ANDROID_RESFILES = \
res/values/strings.xml \
$(NULL)
GARBAGE += \
AndroidManifest.xml \
classes.dex \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
GARBAGE_DIRS += network-libs
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar
include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -1,27 +0,0 @@
/* 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/. */
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package org.mozilla.fencp;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}

View File

@ -9,7 +9,6 @@ JAVAFILES = \
ffxcp.java \
FfxCPFP.java \
FileCursor.java \
R.java \
$(NULL)
ANDROID_RESFILES = \
@ -20,40 +19,6 @@ ANDROID_RESFILES = \
res/values/strings.xml \
$(NULL)
GARBAGE += \
AndroidManifest.xml \
classes.dex \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
GARBAGE_DIRS += network-libs
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar
include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -1,27 +0,0 @@
/* 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/. */
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package org.mozilla.ffxcp;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}

View File

@ -7,7 +7,6 @@ ANDROID_APK_NAME := Watcher
JAVAFILES = \
IWatcherService.java \
RedirOutputThread.java \
R.java \
WatcherMain.java \
WatcherReceiver.java \
WatcherService.java \
@ -24,41 +23,6 @@ ANDROID_RESFILES = \
res/values/strings.xml \
$(NULL)
GARBAGE += \
AndroidManifest.xml \
classes.dex \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
GARBAGE_DIRS += res classes network-libs
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar
include $(topsrcdir)/config/rules.mk
# include Android specific java flags - using these instead of what's in rules.mk
include $(topsrcdir)/config/android-common.mk
tools:: $(ANDROID_APK_NAME).apk
classes.dex: $(JAVAFILES)
$(NSINSTALL) -D classes
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
$(ANDROID_APK_NAME).ap_: AndroidManifest.xml
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@

View File

@ -1,29 +0,0 @@
/* 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/. */
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.mozilla.watcher;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int ateamlogo=0x7f020000;
public static final int icon=0x7f020001;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int foreground_service_started=0x7f040002;
public static final int hello=0x7f040000;
}
}

View File

@ -25,7 +25,7 @@ res-dep-preqs := \
$(res-dep): $(res-dep-preqs)
$(call copy_dir,$(srcdir)/res,$(CURDIR)/res)
@$(TOUCH) $@
endif #}
endif #} ANDROID_RESFILES
ifdef JAVAFILES #{
@ -33,7 +33,62 @@ GENERATED_DIRS += classes
export:: classes
classes: $(call mkdir_deps,classes)
endif #}
endif #} JAVAFILES
ifdef ANDROID_APK_NAME #{
_ANDROID_RES_FLAG := -S $(or $(ANDROID_RES_DIR),res)
_ANDROID_ASSETS_FLAG := $(addprefix -A ,$(ANDROID_ASSETS_DIR))
GENERATED_DIRS += classes
classes.dex: $(call mkdir_deps,classes)
classes.dex: R.java
classes.dex: $(ANDROID_APK_NAME).ap_
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(filter %.java,$^)
$(DX) --dex --output=$@ classes $(ANDROID_EXTRA_JARS)
# R.java and $(ANDROID_APK_NAME).ap_ are both produced by aapt. To
# save an aapt invocation, we produce them both at the same time.
R.java: .aapt.deps
$(ANDROID_APK_NAME).ap_: .aapt.deps
.aapt.deps: AndroidManifest.xml $(wildcard $(ANDROID_RES_DIR)) $(wildcard $(ANDROID_ASSETS_DIR))
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar $(_ANDROID_RES_FLAG) $(_ANDROID_ASSETS_FLAG) \
-J ${@D} \
-F $(ANDROID_APK_NAME).ap_
@$(TOUCH) $@
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@
GARBAGE += \
R.java \
classes.dex \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar
ifdef ANDROID_EXTRA_JARS #{
JAVA_CLASSPATH := $(JAVA_CLASSPATH):$(subst $(NULL) ,:,$(strip $(ANDROID_EXTRA_JARS)))
endif #} ANDROID_EXTRA_JARS
# Include Android specific java flags, instead of what's in rules.mk.
include $(topsrcdir)/config/android-common.mk
endif #} ANDROID_APK_NAME
INCLUDED_JAVA_BUILD_MK := 1

View File

@ -25,7 +25,7 @@ res-dep-preqs := \
$(res-dep): $(res-dep-preqs)
$(call copy_dir,$(srcdir)/res,$(CURDIR)/res)
@$(TOUCH) $@
endif #}
endif #} ANDROID_RESFILES
ifdef JAVAFILES #{
@ -33,7 +33,62 @@ GENERATED_DIRS += classes
export:: classes
classes: $(call mkdir_deps,classes)
endif #}
endif #} JAVAFILES
ifdef ANDROID_APK_NAME #{
_ANDROID_RES_FLAG := -S $(or $(ANDROID_RES_DIR),res)
_ANDROID_ASSETS_FLAG := $(addprefix -A ,$(ANDROID_ASSETS_DIR))
GENERATED_DIRS += classes
classes.dex: $(call mkdir_deps,classes)
classes.dex: R.java
classes.dex: $(ANDROID_APK_NAME).ap_
classes.dex: $(JAVAFILES)
$(JAVAC) $(JAVAC_FLAGS) -d classes $(filter %.java,$^)
$(DX) --dex --output=$@ classes $(ANDROID_EXTRA_JARS)
# R.java and $(ANDROID_APK_NAME).ap_ are both produced by aapt. To
# save an aapt invocation, we produce them both at the same time.
R.java: .aapt.deps
$(ANDROID_APK_NAME).ap_: .aapt.deps
.aapt.deps: AndroidManifest.xml $(wildcard $(ANDROID_RES_DIR)) $(wildcard $(ANDROID_ASSETS_DIR))
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar $(_ANDROID_RES_FLAG) $(_ANDROID_ASSETS_FLAG) \
-J ${@D} \
-F $(ANDROID_APK_NAME).ap_
@$(TOUCH) $@
$(ANDROID_APK_NAME)-unsigned-unaligned.apk: $(ANDROID_APK_NAME).ap_ classes.dex
cp $< $@
$(ZIP) -0 $@ classes.dex
$(ANDROID_APK_NAME)-unaligned.apk: $(ANDROID_APK_NAME)-unsigned-unaligned.apk
cp $< $@
$(DEBUG_JARSIGNER) $@
$(ANDROID_APK_NAME).apk: $(ANDROID_APK_NAME)-unaligned.apk
$(ZIPALIGN) -f -v 4 $< $@
GARBAGE += \
R.java \
classes.dex \
$(ANDROID_APK_NAME).ap_ \
$(ANDROID_APK_NAME)-unsigned-unaligned.apk \
$(ANDROID_APK_NAME)-unaligned.apk \
$(ANDROID_APK_NAME).apk \
$(NULL)
JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar
ifdef ANDROID_EXTRA_JARS #{
JAVA_CLASSPATH := $(JAVA_CLASSPATH):$(subst $(NULL) ,:,$(strip $(ANDROID_EXTRA_JARS)))
endif #} ANDROID_EXTRA_JARS
# Include Android specific java flags, instead of what's in rules.mk.
include $(topsrcdir)/config/android-common.mk
endif #} ANDROID_APK_NAME
INCLUDED_JAVA_BUILD_MK := 1

View File

@ -108,6 +108,9 @@ public class TopSitesPage extends HomeFragment {
// Max number of entries shown in the grid from the cursor.
private int mMaxGridEntries;
// Time in ms until the Gecko thread is reset to normal priority.
private static final long PRIORITY_RESET_TIMEOUT = 10000;
/**
* Class to hold the bitmap of cached thumbnails/favicons.
*/
@ -359,6 +362,14 @@ public class TopSitesPage extends HomeFragment {
@Override
protected void load() {
getLoaderManager().initLoader(LOADER_ID_TOP_SITES, null, mCursorLoaderCallbacks);
// Since this is the primary fragment that loads whenever about:home is
// visited, we want to load it as quickly as possible. Heavy load on
// the Gecko thread can slow down the time it takes for thumbnails to
// appear, especially during startup (bug 897162). By minimizing the
// Gecko thread priority, we ensure that the UI appears quickly. The
// priority is reset to normal once thumbnails are loaded.
ThreadUtils.reduceGeckoPriority(PRIORITY_RESET_TIMEOUT);
}
/**
@ -769,6 +780,10 @@ public class TopSitesPage extends HomeFragment {
if (mGridAdapter != null) {
mGridAdapter.updateThumbnails(thumbnails);
}
// Once thumbnails have finished loading, the UI is ready. Reset
// Gecko to normal priority.
ThreadUtils.resetGeckoPriority();
}
@Override

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#000000"/>
</shape>
</item>
<item android:drawable="@drawable/tabs_button_tail"/>
</layer-list>

View File

@ -27,6 +27,9 @@ public final class ThreadUtils {
public static MessageQueue sGeckoQueue;
public static Thread sGeckoThread;
// Delayed Runnable that resets the Gecko thread priority.
private static volatile Runnable sPriorityResetRunnable;
@SuppressWarnings("serial")
public static class UiThreadBlockedException extends RuntimeException {
public UiThreadBlockedException() {
@ -127,4 +130,37 @@ public final class ThreadUtils {
public static boolean isOnThread(Thread thread) {
return (Thread.currentThread().getId() == thread.getId());
}
/**
* Reduces the priority of the Gecko thread, allowing other operations
* (such as those related to the UI and database) to take precedence.
*
* Note that there are no guards in place to prevent multiple calls
* to this method from conflicting with each other.
*
* @param timeout Timeout in ms after which the priority will be reset
*/
public static void reduceGeckoPriority(long timeout) {
sGeckoThread.setPriority(Thread.MIN_PRIORITY);
sPriorityResetRunnable = new Runnable() {
@Override
public void run() {
resetGeckoPriority();
}
};
getUiHandler().postDelayed(sPriorityResetRunnable, timeout);
}
/**
* Resets the priority of a thread whose priority has been reduced
* by reduceGeckoPriority.
*/
public static void resetGeckoPriority() {
if (sPriorityResetRunnable != null) {
sGeckoThread.setPriority(Thread.NORM_PRIORITY);
getUiHandler().removeCallbacks(sPriorityResetRunnable);
sPriorityResetRunnable = null;
}
}
}

View File

@ -22,3 +22,6 @@ DIRS += [
if not CONFIG['LIBXUL_SDK']:
PARALLEL_DIRS += ['../../xulrunner/tools/redit']
TEST_DIRS += [
'tests',
]

View File

@ -15,7 +15,7 @@
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
android:label="@ANDROID_BACKGROUND_APP_DISPLAYNAME@">
<uses-library android:name="android.test.runner" />
</application>

View File

@ -0,0 +1,37 @@
# 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/.
ANDROID_APK_NAME := background-debug
PP_TARGETS += manifest
manifest := $(srcdir)/AndroidManifest.xml.in
manifest_TARGET := AndroidManifest.xml
manifest_FLAGS += \
-DANDROID_BACKGROUND_TARGET_PACKAGE_NAME="$(ANDROID_PACKAGE_NAME)" \
-DANDROID_BACKGROUND_TEST_PACKAGE_NAME="org.mozilla.background.test" \
-DANDROID_BACKGROUND_APP_DISPLAYNAME="$(MOZ_APP_DISPLAYNAME) Background Tests" \
-DMOZ_ANDROID_SHARED_ID="$(ANDROID_PACKAGE_NAME).sharedID" \
-DMOZ_ANDROID_SHARED_ACCOUNT_TYPE="$(ANDROID_PACKAGE_NAME)_sync" \
$(NULL)
GARBAGE += AndroidManifest.xml
include $(srcdir)/android-services-files.mk
# BACKGROUND_TESTS_{JAVA,RES}_FILES are defined in android-services-files.mk.
JAVAFILES := $(BACKGROUND_TESTS_JAVA_FILES)
ANDROID_RESFILES := $(BACKGROUND_TESTS_RES_FILES)
# The test APK needs to know the contents of the target APK while not
# being linked against them. This is a best effort to avoid getting
# out of sync with base's build config.
JARS_DIR := $(DEPTH)/mobile/android/base/jars
JAVA_BOOTCLASSPATH := $(JAVA_BOOTCLASSPATH):$(subst $(NULL) ,:,$(wildcard $(JARS_DIR)/*.jar))
# We also want to re-compile classes.dex when the associated base
# content changes.
classes.dex: $(wildcard $(JARS_DIR)/*.jar)
tools:: $(ANDROID_APK_NAME).apk
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,5 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.

View File

@ -0,0 +1,9 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
TEST_DIRS += [
'junit3',
]

View File

@ -0,0 +1,9 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
TEST_DIRS += [
'background',
]

View File

@ -126,6 +126,7 @@
<li><a href="about:license#webrtc">WebRTC License</a></li>
<li><a href="about:license#xiph">Xiph.org Foundation License</a></li>
<li><a href="about:license#codemirror">CodeMirror License</a></li>
<li><a href="about:license#escodegen">Escodegen License</a></li>
</ul>
<br>
@ -4100,6 +4101,39 @@ licences.
</pre>
<hr>
<h1><a id="escodegen"></a>Escodegen License</h1>
<p>This license applies to all files in
<span class="path">toolkit/devtools/escodegen</span>.
</p>
<pre>
Copyright (C) 2012 Yusuke Suzuki (twitter: @Constellation) and other contributors.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
</pre>
<hr>
<h1><a id="other-notices"></a>Other Required Notices</h1>

View File

@ -6,6 +6,9 @@
/* General utilities used throughout devtools. */
let { Promise: promise } = Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
let { Services } = Components.utils.import("resource://gre/modules/Services.jsm", {});
/**
* Turn the error |aError| into a string, without fail.
*/
@ -79,3 +82,55 @@ this.makeInfallible = function makeInfallible(aHandler, aName) {
}
}
}
const executeSoon = aFn => {
Services.tm.mainThread.dispatch({
run: this.makeInfallible(aFn)
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
}
/**
* Like Array.prototype.forEach, but doesn't cause jankiness when iterating over
* very large arrays by yielding to the browser and continuing execution on the
* next tick.
*
* @param Array aArray
* The array being iterated over.
* @param Function aFn
* The function called on each item in the array.
* @returns Promise
* A promise that is resolved once the whole array has been iterated
* over.
*/
this.yieldingEach = function yieldingEach(aArray, aFn) {
const deferred = promise.defer();
let i = 0;
let len = aArray.length;
(function loop() {
const start = Date.now();
while (i < len) {
// Don't block the main thread for longer than 16 ms at a time. To
// maintain 60fps, you have to render every frame in at least 16ms; we
// aren't including time spent in non-JS here, but this is Good
// Enough(tm).
if (Date.now() - start > 16) {
executeSoon(loop);
return;
}
try {
aFn(aArray[i++]);
} catch (e) {
deferred.reject(e);
return;
}
}
deferred.resolve();
}());
return deferred.promise;
}

View File

@ -21,5 +21,6 @@ Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
this.DevToolsUtils = {
safeErrorString: safeErrorString,
reportException: reportException,
makeInfallible: makeInfallible
makeInfallible: makeInfallible,
yieldingEach: yieldingEach
};

View File

@ -30,3 +30,23 @@ JSON data is exported, and we can load package.json as a module.
6. Copy the estraverse.js that escodegen depends on into our tree:
$ cp node_modules/estraverse/estraverse.js /path/to/mozilla-central/devtools/escodegen/estraverse.js
7. Build the version of the escodegen that we can use in workers:
First we need to alias `self` as `window`:
$ echo 'let window = self;' >> /path/to/mozilla-central/toolkit/devtools/escodegen/escodegen.worker.js
Then we need to add the browser build of the source map library:
$ git clone https://github.com/mozilla/source-map
$ cd source-map
$ git co <latest release tag compatible with escodegen>
$ npm run-script build
$ cat dist/source-map.js >> /path/to/mozilla-central/toolkit/devtools/escodegen/escodegen.worker.js
Then we need to build the browser version of escodegen:
$ cd /path/to/escodegen
$ npm run-script build
$ cat escodegen.browser.js >> /path/to/mozilla-central/toolkit/devtools/escodegen/escodegen.worker.js

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,7 @@ JS_MODULES_PATH = 'modules/devtools/escodegen'
EXTRA_JS_MODULES += [
'escodegen.js',
'escodegen.worker.js',
'estraverse.js',
'package.json.js',
]

View File

@ -0,0 +1,54 @@
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; js-indent-level: 2; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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/. */
/**
* This file is meant to be loaded as a ChromeWorker. It accepts messages which
* have data of the form:
*
* { id, url, indent, ast }
*
* Where `id` is a unique ID to identify this request, `url` is the url of the
* source being pretty printed, `indent` is the number of spaces to indent the
* code by, and `ast` is the source's abstract syntax tree.
*
* On success, the worker responds with a message of the form:
*
* { id, code, mappings }
*
* Where `id` is the same unique ID from the request, `code` is the pretty
* printed source text, and `mappings` is an array or source mappings from the
* pretty printed code to the AST's source locations.
*
* In the case of an error, the worker responds with a message of the form:
*
* { error }
*/
importScripts("resource://gre/modules/devtools/escodegen/escodegen.worker.js");
self.onmessage = ({ data: { id, url, indent, ast } }) => {
try {
const prettified = escodegen.generate(ast, {
format: {
indent: {
style: " ".repeat(indent)
}
},
sourceMap: url,
sourceMapWithCode: true
});
self.postMessage({
id: id,
code: prettified.code,
mappings: prettified.map._mappings
});
} catch (e) {
self.postMessage({
error: e.message + "\n" + e.stack
});
}
};

View File

@ -467,6 +467,38 @@ ThreadActor.prototype = {
return this._sources;
},
_prettyPrintWorker: null,
get prettyPrintWorker() {
if (!this._prettyPrintWorker) {
this._prettyPrintWorker = new ChromeWorker(
"resource://gre/modules/devtools/server/actors/pretty-print-worker.js");
this._prettyPrintWorker.addEventListener(
"error", this._onPrettyPrintError, false);
if (wantLogging) {
this._prettyPrintWorker.addEventListener("message", this._onPrettyPrintMsg, false);
const postMsg = this._prettyPrintWorker.postMessage;
this._prettyPrintWorker.postMessage = data => {
dumpn("Sending message to prettyPrintWorker: "
+ JSON.stringify(data, null, 2) + "\n");
return postMsg.call(this._prettyPrintWorker, data);
};
}
}
return this._prettyPrintWorker;
},
_onPrettyPrintError: function (error) {
reportError(new Error(error));
},
_onPrettyPrintMsg: function ({ data }) {
dumpn("Received message from prettyPrintWorker: "
+ JSON.stringify(data, null, 2) + "\n");
},
/**
* Keep track of all of the nested event loops we use to pause the debuggee
* when we hit a breakpoint/debugger statement/etc in one place so we can
@ -598,6 +630,15 @@ ThreadActor.prototype = {
this.clearDebuggees();
if (this._prettyPrintWorker) {
this._prettyPrintWorker.removeEventListener(
"error", this._onPrettyPrintError, false);
this._prettyPrintWorker.removeEventListener(
"message", this._onPrettyPrintMsg, false);
this._prettyPrintWorker.terminate();
this._prettyPrintWorker = null;
}
if (!this.dbg) {
return;
}
@ -2335,6 +2376,10 @@ SourceActor.prototype = {
get threadActor() this._threadActor,
get url() this._url,
get prettyPrintWorker() {
return this.threadActor.prettyPrintWorker;
},
form: function SA_form() {
return {
actor: this.actorID,
@ -2401,7 +2446,7 @@ SourceActor.prototype = {
onPrettyPrint: function ({ indent }) {
return this._getSourceText()
.then(this._parseAST)
.then(this._generatePrettyCodeAndMap(indent))
.then(this._sendToPrettyPrintWorker(indent))
.then(this._invertSourceMap)
.then(this._saveMap)
.then(this.onSource)
@ -2420,23 +2465,45 @@ SourceActor.prototype = {
},
/**
* Take the number of spaces to indent and return a function that takes an AST
* and generates code and a source map from the ugly code to the pretty code.
* Return a function that sends a request to the pretty print worker, waits on
* the worker's response, and then returns the pretty printed code.
*
* @param Number aIndent
* The number of spaces to indent by the code by, when we send the
* request to the pretty print worker.
* @returns Function
* Returns a function which takes an AST, and returns a promise that
* is resolved with `{ code, mappings }` where `code` is the pretty
* printed code, and `mappings` is an array of source mappings.
*/
_generatePrettyCodeAndMap: function SA__generatePrettyCodeAndMap(aNumSpaces) {
let indent = "";
for (let i = 0; i < aNumSpaces; i++) {
indent += " ";
}
return aAST => escodegen.generate(aAST, {
format: {
indent: {
style: indent
_sendToPrettyPrintWorker: function SA__sendToPrettyPrintWorker(aIndent) {
return aAST => {
const deferred = promise.defer();
const id = Math.random();
const onReply = ({ data }) => {
if (data.id !== id) {
return;
}
},
sourceMap: this._url,
sourceMapWithCode: true
});
this.prettyPrintWorker.removeEventListener("message", onReply, false);
if (data.error) {
deferred.reject(new Error(data.error));
} else {
deferred.resolve(data);
}
};
this.prettyPrintWorker.addEventListener("message", onReply, false);
this.prettyPrintWorker.postMessage({
id: id,
url: this._url,
indent: aIndent,
ast: aAST
});
return deferred.promise;
};
},
/**
@ -2447,35 +2514,55 @@ SourceActor.prototype = {
*
* Note that the source map is modified in place.
*/
_invertSourceMap: function SA__invertSourceMap({ code, map }) {
// XXX bug 918802: Monkey punch the source map consumer, because iterating
// over all mappings and inverting each of them, and then creating a new
// SourceMapConsumer is *way* too slow.
_invertSourceMap: function SA__invertSourceMap({ code, mappings }) {
const generator = new SourceMapGenerator({ file: this._url });
return DevToolsUtils.yieldingEach(mappings, m => {
let mapping = {
generated: {
line: m.generatedLine,
column: m.generatedColumn
}
};
if (m.source) {
mapping.source = m.source;
mapping.original = {
line: m.originalLine,
column: m.originalColumn
};
mapping.name = m.name;
}
generator.addMapping(mapping);
}).then(() => {
generator.setSourceContent(this._url, code);
const consumer = SourceMapConsumer.fromSourceMap(generator);
map.setSourceContent(this._url, code);
const consumer = new SourceMapConsumer.fromSourceMap(map);
const getOrigPos = consumer.originalPositionFor.bind(consumer);
const getGenPos = consumer.generatedPositionFor.bind(consumer);
// XXX bug 918802: Monkey punch the source map consumer, because iterating
// over all mappings and inverting each of them, and then creating a new
// SourceMapConsumer is slow.
consumer.originalPositionFor = ({ line, column }) => {
const location = getGenPos({
const getOrigPos = consumer.originalPositionFor.bind(consumer);
const getGenPos = consumer.generatedPositionFor.bind(consumer);
consumer.originalPositionFor = ({ line, column }) => {
const location = getGenPos({
line: line,
column: column,
source: this._url
});
location.source = this._url;
return location;
};
consumer.generatedPositionFor = ({ line, column }) => getOrigPos({
line: line,
column: column,
source: this._url
column: column
});
location.source = this._url;
return location;
};
consumer.generatedPositionFor = ({ line, column }) => getOrigPos({
line: line,
column: column
return {
code: code,
map: consumer
};
});
return {
code: code,
map: consumer
};
},
/**

View File

@ -37,6 +37,7 @@ var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
.createInstance(Ci.nsIPrincipal);
var gGlobal = Cu.Sandbox(systemPrincipal);
gGlobal.ChromeWorker = ChromeWorker;
Cu.evalInSandbox(loadSubScript, gGlobal, "1.8");
gGlobal.loadSubScript("resource://gre/modules/devtools/server/main.js");

View File

@ -1,42 +0,0 @@
/* -*- Mode: javascript; js-indent-level: 2; -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
var gDebuggee;
var gClient;
var gThreadClient;
// Test basic pretty printing functionality
function run_test() {
initTestDebuggerServer();
gDebuggee = addTestGlobal("test-pretty-print");
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect(function() {
attachTestTabAndResume(gClient, "test-pretty-print", function(aResponse, aTabClient, aThreadClient) {
gThreadClient = aThreadClient;
evalCode();
});
});
do_test_pending();
}
function evalCode() {
gClient.addOneTimeListener("newSource", prettyPrintSource);
const code = "" + function main() { let a = 1 + 3; let b = a++; return b + a; };
Cu.evalInSandbox(
code,
gDebuggee,
"1.8",
"data:text/javascript," + code);
}
function prettyPrintSource(event, { source }) {
gThreadClient.source(source).prettyPrint(4, testPrettyPrinted);
}
function testPrettyPrinted({ error, source}) {
do_check_true(!error);
do_check_true(source.contains("\n "));
finishClient(gClient);
}

View File

@ -1,94 +0,0 @@
/* -*- Mode: javascript; js-indent-level: 2; -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
var gDebuggee;
var gClient;
var gThreadClient;
var gSource;
// Test stepping through pretty printed sources.
function run_test() {
initTestDebuggerServer();
gDebuggee = addTestGlobal("test-pretty-print");
gDebuggee.noop = x => x;
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect(function() {
attachTestTabAndResume(gClient, "test-pretty-print", function(aResponse, aTabClient, aThreadClient) {
gThreadClient = aThreadClient;
evalCode();
});
});
do_test_pending();
}
const CODE = "" + function main() { var a = 1; debugger; noop(a); return 10; };
const CODE_URL = "data:text/javascript," + CODE;
const BP_LOCATION = {
url: CODE_URL,
line: 5,
column: 2
};
function evalCode() {
gClient.addOneTimeListener("newSource", prettyPrintSource);
Cu.evalInSandbox(
CODE,
gDebuggee,
"1.8",
CODE_URL,
1
);
}
function prettyPrintSource(event, { source }) {
gSource = source;
gThreadClient.source(gSource).prettyPrint(2, runCode);
}
function runCode({ error }) {
do_check_true(!error);
gClient.addOneTimeListener("paused", testDbgStatement);
gDebuggee.main();
}
function testDbgStatement(event, { why, frame }) {
do_check_eq(why.type, "debuggerStatement");
const { url, line, column } = frame.where;
do_check_eq(url, CODE_URL);
do_check_eq(line, 3);
setBreakpoint();
}
function setBreakpoint() {
gThreadClient.setBreakpoint(BP_LOCATION, ({ error, actualLocation }) => {
do_check_true(!error);
do_check_true(!actualLocation);
testStepping();
});
}
function testStepping() {
gClient.addOneTimeListener("paused", (event, { why, frame }) => {
do_check_eq(why.type, "resumeLimit");
const { url, line } = frame.where;
do_check_eq(url, CODE_URL);
do_check_eq(line, 4);
testHitBreakpoint();
});
gThreadClient.stepIn();
}
function testHitBreakpoint() {
gClient.addOneTimeListener("paused", (event, { why, frame }) => {
do_check_eq(why.type, "breakpoint");
const { url, line, column } = frame.where;
do_check_eq(url, CODE_URL);
do_check_eq(line, BP_LOCATION.line);
do_check_eq(column, BP_LOCATION.column);
finishClient(gClient);
});
gThreadClient.resume();
}

View File

@ -1,74 +0,0 @@
/* -*- Mode: javascript; js-indent-level: 2; -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test pretty printing source mapped sources.
var gDebuggee;
var gClient;
var gThreadClient;
var gSource;
Components.utils.import('resource:///modules/devtools/SourceMap.jsm');
function run_test() {
initTestDebuggerServer();
gDebuggee = addTestGlobal("test-pretty-print");
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect(function() {
attachTestTabAndResume(gClient, "test-pretty-print", function(aResponse, aTabClient, aThreadClient) {
gThreadClient = aThreadClient;
evalCode();
});
});
do_test_pending();
}
const dataUrl = s => "data:text/javascript," + s;
const A = "function a(){b()}";
const A_URL = dataUrl(A);
const B = "function b(){debugger}";
const B_URL = dataUrl(B);
function evalCode() {
let { code, map } = (new SourceNode(null, null, null, [
new SourceNode(1, 0, A_URL, A),
B.split("").map((ch, i) => new SourceNode(1, i, B_URL, ch))
])).toStringWithSourceMap({
file: "abc.js"
});
code += "//# sourceMappingURL=data:text/json;base64," + btoa(map.toString());
gClient.addListener("newSource", waitForB);
Components.utils.evalInSandbox(code, gDebuggee, "1.8",
"http://example.com/foo.js", 1);
}
function waitForB(event, { source }) {
if (source.url !== B_URL) {
return;
}
gClient.removeListener("newSource", waitForB);
prettyPrint(source);
}
function prettyPrint(source) {
gThreadClient.source(source).prettyPrint(2, runCode);
}
function runCode({ error }) {
do_check_true(!error);
gClient.addOneTimeListener("paused", testDbgStatement);
gDebuggee.a();
}
function testDbgStatement(event, { frame, why }) {
do_check_eq(why.type, "debuggerStatement");
const { url, line, column } = frame.where;
do_check_eq(url, B_URL);
do_check_eq(line, 2);
do_check_eq(column, 2);
finishClient(gClient);
}

View File

@ -169,9 +169,6 @@ reason = bug 820380
[test_longstringactor.js]
[test_longstringgrips-01.js]
[test_longstringgrips-02.js]
[test_pretty_print-01.js]
[test_pretty_print-02.js]
[test_pretty_print-03.js]
[test_source-01.js]
skip-if = toolkit == "gonk"
reason = bug 820380

View File

@ -59,7 +59,7 @@ this.DebuggerTransport = function DebuggerTransport(aInput, aOutput)
DebuggerTransport.prototype = {
/**
* Transmit a packet.
*
*
* This method returns immediately, without waiting for the entire
* packet to be transmitted, registering event handlers as needed to
* transmit the entire packet. Packets are transmitted in the order

View File

@ -1258,7 +1258,12 @@ define('source-map/source-map-generator', ['require', 'exports', 'module' , 'so
return;
}
else {
throw new Error('Invalid mapping.');
throw new Error('Invalid mapping: ' + JSON.stringify({
generated: aGenerated,
source: aSource,
orginal: aOriginal,
name: aName
}));
}
};
@ -1335,6 +1340,9 @@ define('source-map/source-map-generator', ['require', 'exports', 'module' , 'so
SourceMapGenerator.prototype._generateSourcesContent =
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
return aSources.map(function (source) {
if (!this._sourcesContents) {
return null;
}
if (aSourceRoot) {
source = util.relative(aSourceRoot, source);
}

View File

@ -0,0 +1,12 @@
Rather than make changes to the built files here, make them upstream and then
upgrade our tree's copy of the built files.
To upgrade the source-map library:
$ git clone https://github.com/mozilla/source-map.git
$ git co source-map
$ git co <latest-tagged-version>
$ npm run-script build
$ cp dist/SourceMap.jsm /path/to/mozilla-central/toolkit/devtools/sourcemap/SourceMap.jsm
$ cp dist/test/* /path/to/mozilla-central/toolkit/devtools/sourcemap/tests/unit/

View File

@ -328,20 +328,34 @@ GECKO_APP_AP_PATH = $(call core_abspath,$(DEPTH)/mobile/android/base)
ifdef ENABLE_TESTS
INNER_ROBOCOP_PACKAGE=echo
INNER_BACKGROUND_TESTS_PACKAGE=echo
ifeq ($(MOZ_BUILD_APP),mobile/android)
UPLOAD_EXTRA_FILES += robocop.apk
UPLOAD_EXTRA_FILES += fennec_ids.txt
# Robocop/Robotium tests, Android Background tests, and Fennec need to
# be signed with the same key, which means release signing them all.
# $(1) is the full path to input: foo-debug-unsigned-unaligned.apk.
# $(2) is the full path to output: foo.apk.
RELEASE_SIGN_ANDROID_APK = \
cp $(1) $(2)-unaligned.apk && \
$(RELEASE_JARSIGNER) $(2)-unaligned.apk && \
$(ZIPALIGN) -f -v 4 $(2)-unaligned.apk $(2) && \
$(RM) $(2)-unaligned.apk
ROBOCOP_PATH = $(call core_abspath,$(_ABS_DIST)/../build/mobile/robocop)
# Robocop and Fennec need to be signed with the same key, which means
# release signing them both.
INNER_ROBOCOP_PACKAGE= \
$(NSINSTALL) $(GECKO_APP_AP_PATH)/fennec_ids.txt $(_ABS_DIST) && \
cp $(ROBOCOP_PATH)/robocop-debug-unsigned-unaligned.apk $(_ABS_DIST)/robocop-unaligned.apk && \
$(RELEASE_JARSIGNER) $(_ABS_DIST)/robocop-unaligned.apk && \
$(ZIPALIGN) -f -v 4 $(_ABS_DIST)/robocop-unaligned.apk $(_ABS_DIST)/robocop.apk
$(call RELEASE_SIGN_ANDROID_APK,$(ROBOCOP_PATH)/robocop-debug-unsigned-unaligned.apk,$(_ABS_DIST)/robocop.apk)
BACKGROUND_TESTS_PATH = $(call core_abspath,$(_ABS_DIST)/../mobile/android/tests/background/junit3)
INNER_BACKGROUND_TESTS_PACKAGE= \
$(call RELEASE_SIGN_ANDROID_APK,$(BACKGROUND_TESTS_PATH)/background-debug-unsigned-unaligned.apk,$(_ABS_DIST)/background.apk)
endif
else
INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Robocop for you'
INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Android Robocop for you'
INNER_BACKGROUND_TESTS_PACKAGE=echo 'Testing is disabled - No Android Background tests for you'
endif
# Create geckoview_library/geckoview_{assets,library}.zip for third-party GeckoView consumers.
@ -403,6 +417,7 @@ INNER_MAKE_PACKAGE = \
$(RELEASE_JARSIGNER) $(_ABS_DIST)/gecko.apk && \
$(ZIPALIGN) -f -v 4 $(_ABS_DIST)/gecko.apk $(PACKAGE) && \
$(INNER_ROBOCOP_PACKAGE) && \
$(INNER_BACKGROUND_TESTS_PACKAGE) && \
$(INNER_MAKE_GECKOVIEW_LIBRARY)
# Language repacks root the resources contained in assets/omni.ja

View File

@ -39,7 +39,7 @@ function runTest() {
let url = URL_UPDATE + "?showDetails=1" + getVersionParams();
setUpdateURLOverride(url);
setupTimer(90000); // 90 seconds
setupTimer(180000); // 180 seconds
gUP.checkForUpdates();
}

View File

@ -46,7 +46,7 @@ function runTest() {
let url = URL_UPDATE + "?showBillboard=1&showDetails=1" + getVersionParams();
setUpdateURLOverride(url);
setupTimer(90000); // 90 seconds
setupTimer(180000); // 180 seconds
gUP.checkForUpdates();
}

View File

@ -139,9 +139,9 @@ const PAGEID_INSTALLED = "installed"; // Done
const UPDATE_WINDOW_NAME = "Update:Wizard";
const URL_HOST = "http://example.com/";
const URL_HOST = "http://example.com";
const URL_PATH = "chrome/toolkit/mozapps/update/test/chrome";
const URL_UPDATE = URL_HOST + URL_PATH + "/update.sjs";
const URL_UPDATE = URL_HOST + "/" + URL_PATH + "/update.sjs";
const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
@ -158,7 +158,6 @@ const TEST_ADDONS = [ "appdisabled_1", "appdisabled_2",
"updateversion_1", "updateversion_2",
"userdisabled_1", "userdisabled_2", "hotfix" ];
var gTestTimeout = 45000; // 45 seconds
var gTimeoutTimer;

View File

@ -181,11 +181,11 @@ var observer = {
* Sets the app.update.url.override preference.
*
* @param aURL
* The update url. If not specified 'URL_HOST + "update.xml"' will be
* The update url. If not specified 'URL_HOST + "/update.xml"' will be
* used.
*/
function setUpdateURLOverride(aURL) {
let url = aURL ? aURL : URL_HOST + "update.xml";
let url = aURL ? aURL : URL_HOST + "/update.xml";
debugDump("setting " + PREF_APP_UPDATE_URL_OVERRIDE + " to " + url);
Services.prefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
}

View File

@ -50,6 +50,8 @@ const STATE_SUCCEEDED = "succeeded";
const STATE_DOWNLOAD_FAILED = "download-failed";
const STATE_FAILED = "failed";
var gTestserverPort;
/**
* Constructs a string representing a remote update xml file.
*
@ -344,7 +346,8 @@ function getUpdateString(aType, aName, aDisplayVersion, aAppVersion,
* @param aURL (optional)
* The patch's url to the mar file.
* If not specified it will default to the value of:
* URL_HOST + URL_PATH + "/" + FILE_SIMPLE_MAR
* URL_HOST + (gTestserverPort ? ":" + gTestserverPort : "") + "/" +
* URL_PATH + "/" + FILE_SIMPLE_MAR
* @param aHashFunction (optional)
* The patch's hash function used to verify the mar file.
* If not specified it will default to 'MD5'.
@ -360,7 +363,9 @@ function getUpdateString(aType, aName, aDisplayVersion, aAppVersion,
*/
function getPatchString(aType, aURL, aHashFunction, aHashValue, aSize) {
let type = aType ? aType : "complete";
let url = aURL ? aURL : URL_HOST + URL_PATH + "/" + FILE_SIMPLE_MAR;
let url = aURL ? aURL : URL_HOST +
(gTestserverPort ? ":" + gTestserverPort : "") +
"/" + URL_PATH + "/" + FILE_SIMPLE_MAR;
let hashFunction = aHashFunction ? aHashFunction : "MD5";
let hashValue = aHashValue ? aHashValue : MD5_HASH_SIMPLE_MAR;
let size = aSize ? aSize : SIZE_SIMPLE_MAR;

View File

@ -64,7 +64,7 @@ const IS_MAR_CHECKS_ENABLED = true;
const IS_MAR_CHECKS_ENABLED = false;
#endif
const URL_HOST = "http://localhost:4444/";
const URL_HOST = "http://localhost";
const URL_PATH = "data";
const APPLY_TO_DIR_SUFFIX = "_applyToDir/";
@ -1874,7 +1874,9 @@ function start_httpserver(aRelativeDirName) {
Components.utils.import("resource://testing-common/httpd.js");
gTestserver = new HttpServer();
gTestserver.registerDirectory("/data/", dir);
gTestserver.start(4444);
gTestserver.start(-1);
gTestserverPort = gTestserver.identity.primaryPort;
logTestInfo("http server port = " + gTestserverPort);
}
/* Helper for stopping the http server used by the tests */

View File

@ -124,7 +124,7 @@ function check_test_pt02() {
do_check_true(bestUpdate.showPrompt);
do_check_true(bestUpdate.showNeverForVersion);
do_check_eq(bestUpdate.promptWaitTime, "345600");
do_check_eq(bestUpdate.serviceURL, URL_HOST + "update.xml?force=1");
do_check_eq(bestUpdate.serviceURL, URL_HOST + "/update.xml?force=1");
do_check_eq(bestUpdate.channel, "test_channel");
do_check_false(bestUpdate.isCompleteUpdate);
do_check_false(bestUpdate.isSecurityUpdate);
@ -204,7 +204,7 @@ function check_test_pt03() {
do_check_true(bestUpdate.showPrompt);
do_check_true(bestUpdate.showNeverForVersion);
do_check_eq(bestUpdate.promptWaitTime, "691200");
do_check_eq(bestUpdate.serviceURL, URL_HOST + "update.xml?force=1");
do_check_eq(bestUpdate.serviceURL, URL_HOST + "/update.xml?force=1");
do_check_eq(bestUpdate.channel, "test_channel");
do_check_false(bestUpdate.isCompleteUpdate);
do_check_false(bestUpdate.isSecurityUpdate);

View File

@ -29,12 +29,12 @@ function run_test() {
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
removeUpdateDirsAndFiles();
setUpdateURLOverride();
// The HTTP server is only used for the mar file downloads since it is slow
start_httpserver(URL_PATH);
setUpdateURLOverride(URL_HOST + ":" + gTestserverPort + "/update.xml");
// The mock XMLHttpRequest is MUCH faster
overrideXHR(callHandleEvent);
standardInit();
// The HTTP server is only used for the mar file downloads which is slow
start_httpserver(URL_PATH);
do_execute_soon(run_test_pt1);
}
@ -206,7 +206,8 @@ function run_test_pt10() {
// mar download with the mar not found
function run_test_pt11() {
var patches = getRemotePatchString(null, URL_HOST + URL_PATH + "/missing.mar");
var patches = getRemotePatchString(null, URL_HOST + ":" + gTestserverPort +
"/" + URL_PATH + "/missing.mar");
var updates = getRemoteUpdateString(patches);
gResponseBody = getRemoteUpdatesXMLString(updates);
run_test_helper_pt1("mar download with the mar not found",
@ -216,7 +217,7 @@ function run_test_pt11() {
// 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);
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

View File

@ -178,7 +178,7 @@ function run_test() {
patch = update.selectedPatch;
do_check_eq(patch.type, "complete");
do_check_eq(patch.URL, URL_HOST + URL_PATH + "/" + FILE_SIMPLE_MAR);
do_check_eq(patch.URL, URL_HOST + "/" + URL_PATH + "/" + FILE_SIMPLE_MAR);
do_check_eq(patch.hashFunction, "MD5");
do_check_eq(patch.hashValue, MD5_HASH_SIMPLE_MAR);
do_check_eq(patch.size, SIZE_SIMPLE_MAR);
@ -208,7 +208,7 @@ function run_test() {
patch = update.selectedPatch;
do_check_eq(patch.type, "complete");
do_check_eq(patch.URL, URL_HOST + URL_PATH + "/" + FILE_SIMPLE_MAR);
do_check_eq(patch.URL, URL_HOST + "/" + URL_PATH + "/" + FILE_SIMPLE_MAR);
do_check_eq(patch.hashFunction, "MD5");
do_check_eq(patch.hashValue, MD5_HASH_SIMPLE_MAR);
do_check_eq(patch.size, SIZE_SIMPLE_MAR);

View File

@ -13,7 +13,7 @@ function run_test() {
// adjustGeneralPaths registers a cleanup function that calls end_test.
adjustGeneralPaths();
logTestInfo("testing removing an active update for a channel that is not" +
logTestInfo("testing removal of an active update for a channel that is not" +
"valid due to switching channels (bug 486275)");
removeUpdateDirsAndFiles();

View File

@ -9,7 +9,6 @@ support-files =
[test_0010_general.js]
[test_0020_general.js]
[test_0030_general.js]
run-sequentially = Uses a hardcoded http port.
[test_0040_general.js]
[test_0050_general.js]
[test_0060_manager.js]
@ -26,7 +25,6 @@ run-sequentially = Uses a hardcoded http port.
skip-if = toolkit == 'gonk'
reason = custom nsIUpdatePrompt
[test_0082_prompt_unsupportAlreadyNotified.js]
run-sequentially = Uses a hardcoded http port.
skip-if = toolkit == 'gonk'
reason = custom nsIUpdatePrompt