Merge inbound to central, a=merge

MozReview-Commit-ID: DpCZgRV1csS
This commit is contained in:
Wes Kocher 2017-02-24 16:46:12 -08:00
commit e84fc624ff
727 changed files with 182678 additions and 53420 deletions

View file

@ -108,8 +108,6 @@ devtools/server/actors/object.js
devtools/server/actors/script.js
devtools/server/actors/styleeditor.js
devtools/server/actors/stylesheets.js
devtools/server/tests/browser/**
!devtools/server/tests/browser/browser_webextension_inspected_window.js
devtools/server/tests/mochitest/**
devtools/server/tests/unit/**
devtools/shared/heapsnapshot/**

View file

@ -44,6 +44,8 @@ _OPT\.OBJ/
# SpiderMonkey test result logs
^js/src/tests/results-.*\.(html|txt)$
^js/src/devtools/rootAnalysis/t/out
# SpiderMonkey clone of the webassembly spec repository
^js/src/wasm/spec
# Java HTML5 parser classes
^parser/html/java/(html|java)parser/

View file

@ -398,10 +398,15 @@ DocAccessibleParent::RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uin
ipc::IPCResult result = AddChildDoc(childDoc, aID, false);
MOZ_ASSERT(result);
MOZ_ASSERT(CheckDocTree());
#ifdef DEBUG
if (!result) {
return result;
}
return IPC_OK();
#else
result = IPC_OK();
#endif
return result;
}
ipc::IPCResult
@ -412,11 +417,7 @@ DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
// document it self.
ProxyEntry* e = mAccessibles.GetEntry(aParentID);
if (!e) {
#ifdef DEBUG
return IPC_FAIL(this, "binding to nonexistant proxy!");
#else
return IPC_OK();
#endif
}
ProxyAccessible* outerDoc = e->mProxy;

View file

@ -46,6 +46,7 @@ PlatformChild::PlatformChild()
: mAccTypelib(mozilla::mscom::RegisterTypelib(L"oleacc.dll",
mozilla::mscom::RegistrationFlags::eUseSystemDirectory))
, mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb"))
, mSdnTypelib(mozilla::mscom::RegisterTypelib(L"AccessibleMarshal.dll"))
{
mozilla::mscom::InterceptorLog::Init();
mozilla::mscom::RegisterArrayData(sPlatformChildArrayData);

View file

@ -27,6 +27,7 @@ private:
UniquePtr<mozilla::mscom::RegisteredProxy> mIA2Proxy;
UniquePtr<mozilla::mscom::RegisteredProxy> mAccTypelib;
UniquePtr<mozilla::mscom::RegisteredProxy> mMiscTypelib;
UniquePtr<mozilla::mscom::RegisteredProxy> mSdnTypelib;
};
} // namespace mozilla

View file

@ -427,6 +427,7 @@ skip-if = true # Bug 1005420 - fails intermittently. also with e10s enabled: biz
skip-if = (os == "win" && !debug)
[browser_web_channel.js]
[browser_windowopen_reflows.js]
skip-if = os == "mac" # bug 1339317
[browser_zbug569342.js]
skip-if = e10s || debug # Bug 1094240 - has findbar-related failures
[browser_registerProtocolHandler_notification.js]

View file

@ -15,5 +15,5 @@ skip-if = (e10s && debug) || (os == "linux" && !debug) # bug 1320754 for e10s de
[browser_devices_get_user_media_unprompted_access.js]
[browser_devices_get_user_media_unprompted_access_in_frame.js]
[browser_devices_get_user_media_unprompted_access_tear_off_tab.js]
skip-if = (os == "linux") # linux: bug 1331616
skip-if = (os == "linux") || (os == "win" && bits == 64) # linux: bug 1331616, win8: bug 1334752
[browser_webrtc_hooks.js]

View file

@ -35,7 +35,7 @@ gyp_vars.update({
'build_json': 0,
'build_icu': 0,
'build_opus': 0,
'libyuv_dir': '/media/libyuv',
'libyuv_dir': '/media/libyuv/libyuv',
'yuv_disable_avx2': 0 if CONFIG['HAVE_X86_AVX2'] else 1,
# don't use openssl
'use_openssl': 0,

View file

@ -22,6 +22,7 @@
<link rel="stylesheet" href="resource://devtools/client/inspector/components/inspector-tab-panel.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/splitter/split-box.css"/>
<link rel="stylesheet" href="resource://devtools/client/inspector/layout/components/Accordion.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/reps/reps.css"/>
<script type="application/javascript;version=1.8"
src="chrome://devtools/content/shared/theme-switching.js"></script>

View file

@ -30,6 +30,7 @@ const App = createClass({
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
setSelectedNode: PropTypes.func.isRequired,
showBoxModelProperties: PropTypes.bool.isRequired,
onHideBoxModelHighlighter: PropTypes.func.isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,

View file

@ -21,7 +21,10 @@ module.exports = createClass({
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
setSelectedNode: PropTypes.func.isRequired,
onHideBoxModelHighlighter: PropTypes.func.isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
onToggleShowGridLineNumbers: PropTypes.func.isRequired,
onToggleShowInfiniteLines: PropTypes.func.isRequired,
@ -34,7 +37,10 @@ module.exports = createClass({
getSwatchColorPickerTooltip,
grids,
highlighterSettings,
setSelectedNode,
onHideBoxModelHighlighter,
onSetGridOverlayColor,
onShowBoxModelHighlighterForNode,
onToggleGridHighlighter,
onToggleShowGridLineNumbers,
onToggleShowInfiniteLines,
@ -48,7 +54,10 @@ module.exports = createClass({
GridList({
getSwatchColorPickerTooltip,
grids,
setSelectedNode,
onHideBoxModelHighlighter,
onSetGridOverlayColor,
onShowBoxModelHighlighterForNode,
onToggleGridHighlighter,
}),
GridDisplaySettings({

View file

@ -4,9 +4,14 @@
"use strict";
const { addons, createClass, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
const { addons, createClass, createFactory, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
// Reps
const { REPS } = require("devtools/client/shared/components/reps/reps");
const Rep = createFactory(REPS.Rep);
const ElementNode = REPS.ElementNode;
const Types = require("../types");
module.exports = createClass({
@ -16,7 +21,10 @@ module.exports = createClass({
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grid: PropTypes.shape(Types.grid).isRequired,
setSelectedNode: PropTypes.func.isRequired,
onHideBoxModelHighlighter: PropTypes.func.isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
},
@ -50,7 +58,46 @@ module.exports = createClass({
this.props.onSetGridOverlayColor(this.props.grid.nodeFront, color);
},
onGridCheckboxClick() {
/**
* While waiting for a reps fix in https://github.com/devtools-html/reps/issues/92,
* translate nodeFront to a grip-like object that can be used with an ElementNode rep.
*
* @params {NodeFront} nodeFront
* The NodeFront for which we want to create a grip-like object.
* @returns {Object} a grip-like object that can be used with Reps.
*/
translateNodeFrontToGrip(nodeFront) {
let { attributes } = nodeFront;
// The main difference between NodeFront and grips is that attributes are treated as
// a map in grips and as an array in NodeFronts.
let attributesMap = {};
for (let {name, value} of attributes) {
attributesMap[name] = value;
}
return {
actor: nodeFront.actorID,
preview: {
attributes: attributesMap,
attributesLength: attributes.length,
// nodeName is already lowerCased in Node grips
nodeName: nodeFront.nodeName.toLowerCase(),
nodeType: nodeFront.nodeType,
}
};
},
onGridCheckboxClick(e) {
// If the click was on the svg icon to select the node in the inspector, bail out.
let originalTarget = e.nativeEvent && e.nativeEvent.explicitOriginalTarget;
if (originalTarget && originalTarget.namespaceURI === "http://www.w3.org/2000/svg") {
// We should be able to cancel the click event propagation after the following reps
// issue is implemented : https://github.com/devtools-html/reps/issues/95 .
e.preventDefault();
return;
}
let {
grid,
onToggleGridHighlighter,
@ -60,21 +107,13 @@ module.exports = createClass({
},
render() {
let { grid } = this.props;
let {
grid,
onHideBoxModelHighlighter,
onShowBoxModelHighlighterForNode,
setSelectedNode,
} = this.props;
let { nodeFront } = grid;
let { displayName, attributes } = nodeFront;
let gridName = displayName;
let idIndex = attributes.findIndex(({ name }) => name === "id");
if (idIndex > -1 && attributes[idIndex].value) {
gridName += "#" + attributes[idIndex].value;
}
let classIndex = attributes.findIndex(({name}) => name === "class");
if (classIndex > -1 && attributes[classIndex].value) {
gridName += "." + attributes[classIndex].value.split(" ").join(".");
}
return dom.li(
{
@ -91,7 +130,15 @@ module.exports = createClass({
onChange: this.onGridCheckboxClick,
}
),
gridName
Rep(
{
defaultRep: ElementNode,
object: this.translateNodeFrontToGrip(nodeFront),
onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(nodeFront),
onInspectIconClick: () => setSelectedNode(nodeFront),
}
)
),
dom.div(
{

View file

@ -19,7 +19,10 @@ module.exports = createClass({
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
setSelectedNode: PropTypes.func.isRequired,
onHideBoxModelHighlighter: PropTypes.func.isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
},
@ -29,7 +32,10 @@ module.exports = createClass({
let {
getSwatchColorPickerTooltip,
grids,
setSelectedNode,
onHideBoxModelHighlighter,
onSetGridOverlayColor,
onShowBoxModelHighlighterForNode,
onToggleGridHighlighter,
} = this.props;
@ -46,7 +52,10 @@ module.exports = createClass({
grids.map(grid => GridItem({
getSwatchColorPickerTooltip,
grid,
setSelectedNode,
onHideBoxModelHighlighter,
onSetGridOverlayColor,
onShowBoxModelHighlighterForNode,
onToggleGridHighlighter,
}))
)

View file

@ -99,6 +99,15 @@ LayoutView.prototype = {
return this.swatchColorPickerTooltip;
},
/**
* Set the inspector selection.
* @param {NodeFront} nodeFront
* The NodeFront corresponding to the new selection.
*/
setSelectedNode: (nodeFront) => {
this.inspector.selection.setNodeFront(nodeFront, "layout-panel");
},
/**
* Shows the box model properties under the box model if true, otherwise, hidden by
* default.
@ -106,8 +115,6 @@ LayoutView.prototype = {
showBoxModelProperties: true,
onHideBoxModelHighlighter,
onShowBoxModelEditor,
onShowBoxModelHighlighter,
/**
* Handler for a change in the grid overlay color picker for a grid container.
@ -132,6 +139,23 @@ LayoutView.prototype = {
}
},
onShowBoxModelEditor,
onShowBoxModelHighlighter,
/**
* Shows the box-model highlighter on the element corresponding to the provided
* NodeFront.
*
* @param {NodeFront} nodeFront
* The node to highlight.
* @param {Object} options
* Options passed to the highlighter actor.
*/
onShowBoxModelHighlighterForNode: (nodeFront, options) => {
let toolbox = this.inspector.toolbox;
toolbox.highlighterUtils.highlightNodeFront(nodeFront, options);
},
/**
* Handler for a change in the input checkboxes in the GridList component.
* Toggles on/off the grid highlighter for the provided grid container element.

View file

@ -161,9 +161,9 @@
<div class="multiple-animations-2"></div>
<div class="all-transitions"></div>
<script type="text/javascript">
"use strict";
// Get the transitions started when the page loads
var players;
addEventListener("load", function() {
addEventListener("load", function () {
document.querySelector(".transition").classList.add("get-round");
document.querySelector(".delayed-transition").classList.add("get-round");
});

View file

@ -1,32 +1,30 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that the AnimationPlayerActor exposes a getFrames method that returns
// the list of keyframes in the animation.
const URL = MAIN_DOMAIN + "animation.html";
add_task(function* () {
let {client, walker, animations} =
yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
info("Get the test node and its animation front");
let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
let [player] = yield animations.getAnimationPlayersForNode(node);
ok(player.getFrames, "The front has the getFrames method");
let frames = yield player.getFrames();
is(frames.length, 2, "The correct number of keyframes was retrieved");
ok(frames[0].transform, "Frame 0 has the transform property");
ok(frames[1].transform, "Frame 1 has the transform property");
// Note that we don't really test the content of the frame object here on
// purpose. This object comes straight out of the web animations API
// unmodified.
yield client.close();
gBrowser.removeCurrentTab();
});
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that the AnimationPlayerActor exposes a getFrames method that returns
// the list of keyframes in the animation.
add_task(function* () {
let {client, walker, animations} =
yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
info("Get the test node and its animation front");
let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
let [player] = yield animations.getAnimationPlayersForNode(node);
ok(player.getFrames, "The front has the getFrames method");
let frames = yield player.getFrames();
is(frames.length, 2, "The correct number of keyframes was retrieved");
ok(frames[0].transform, "Frame 0 has the transform property");
ok(frames[1].transform, "Frame 1 has the transform property");
// Note that we don't really test the content of the frame object here on
// purpose. This object comes straight out of the web animations API
// unmodified.
yield client.close();
gBrowser.removeCurrentTab();
});

View file

@ -1,36 +1,36 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that the AnimationPlayerActor exposes a getProperties method that
// returns the list of animated properties in the animation.
const URL = MAIN_DOMAIN + "animation.html";
add_task(function* () {
let {client, walker, animations} = yield initAnimationsFrontForUrl(URL);
info("Get the test node and its animation front");
let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
let [player] = yield animations.getAnimationPlayersForNode(node);
ok(player.getProperties, "The front has the getProperties method");
let properties = yield player.getProperties();
is(properties.length, 1, "The correct number of properties was retrieved");
let propertyObject = properties[0];
is(propertyObject.name, "transform", "Property 0 is transform");
is(propertyObject.values.length, 2,
"The correct number of property values was retrieved");
// Note that we don't really test the content of the frame object here on
// purpose. This object comes straight out of the web animations API
// unmodified.
yield client.close();
gBrowser.removeCurrentTab();
});
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that the AnimationPlayerActor exposes a getProperties method that
// returns the list of animated properties in the animation.
const URL = MAIN_DOMAIN + "animation.html";
add_task(function* () {
let {client, walker, animations} = yield initAnimationsFrontForUrl(URL);
info("Get the test node and its animation front");
let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
let [player] = yield animations.getAnimationPlayersForNode(node);
ok(player.getProperties, "The front has the getProperties method");
let properties = yield player.getProperties();
is(properties.length, 1, "The correct number of properties was retrieved");
let propertyObject = properties[0];
is(propertyObject.name, "transform", "Property 0 is transform");
is(propertyObject.values.length, 2,
"The correct number of property values was retrieved");
// Note that we don't really test the content of the frame object here on
// purpose. This object comes straight out of the web animations API
// unmodified.
yield client.close();
gBrowser.removeCurrentTab();
});

View file

@ -21,8 +21,10 @@ add_task(function* () {
info("Play a transition by adding the expand class, wait for mutations");
let onMutations = expectMutationEvents(animations, 2);
let cpow = content.document.querySelector(".all-transitions");
cpow.classList.add("expand");
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
let el = content.document.querySelector(".all-transitions");
el.classList.add("expand");
});
let reportedMutations = yield onMutations;
is(reportedMutations.length, 2, "2 mutation events were received");
@ -35,7 +37,10 @@ add_task(function* () {
info("Play the transition back by removing the class, wait for mutations");
onMutations = expectMutationEvents(animations, 4);
cpow.classList.remove("expand");
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
let el = content.document.querySelector(".all-transitions");
el.classList.remove("expand");
});
reportedMutations = yield onMutations;
is(reportedMutations.length, 4, "4 new mutation events were received");

View file

@ -41,9 +41,9 @@ add_task(function* () {
yield animations.setPlaybackRates(players, .5);
info("Query their states and check they are correct");
for (let player of players) {
let state = yield player.getCurrentState();
is(state.playbackRate, .5, "The playbackRate was updated");
for (let animPlayer of players) {
let animPlayerState = yield animPlayer.getCurrentState();
is(animPlayerState.playbackRate, .5, "The playbackRate was updated");
}
yield client.close();

View file

@ -19,6 +19,7 @@ const TEST_URL = "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper
add_task(function* () {
let browser = yield addTab(TEST_URL);
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
let nodeBuilder = () => {

View file

@ -19,6 +19,7 @@ const {
add_task(function* () {
let browser = yield addTab("about:preferences");
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
let nodeBuilder = () => {

View file

@ -20,6 +20,7 @@ const TEST_URL = "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper
add_task(function* () {
let browser = yield addTab(TEST_URL);
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
let nodeBuilder = () => {
@ -97,6 +98,6 @@ function synthesizeMouseDown(x, y, win) {
// We need to make sure the inserted anonymous content can be targeted by the
// event right after having been inserted, and so we need to force a sync
// reflow.
let forceReflow = win.document.documentElement.offsetWidth;
win.document.documentElement.offsetWidth;
EventUtils.synthesizeMouseAtPoint(x, y, {type: "mousedown"}, win);
}

View file

@ -10,7 +10,6 @@
// This makes sure the 'domnode' protocol actor type is known when importing
// highlighter.
require("devtools/server/actors/inspector");
const events = require("sdk/event/core");
const {HighlighterEnvironment} = require("devtools/server/actors/highlighters");
@ -18,11 +17,14 @@ const {
CanvasFrameAnonymousContentHelper
} = require("devtools/server/actors/highlighters/utils/markup");
const TEST_URL_1 = "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test 1";
const TEST_URL_2 = "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test 2";
const TEST_URL_1 =
"data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test 1";
const TEST_URL_2 =
"data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test 2";
add_task(function* () {
let browser = yield addTab(TEST_URL_2);
let browser = yield addTab(TEST_URL_1);
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
let nodeBuilder = () => {
@ -66,8 +68,9 @@ add_task(function* () {
info("Navigating to a new page");
let loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
content.location = TEST_URL_2;
BrowserTestUtils.loadURI(browser, TEST_URL_2);
yield loaded;
// eslint-disable-next-line mozilla/no-cpows-in-tests
doc = gBrowser.selectedBrowser.contentWindow.document;
info("Try to access the element again");
@ -93,6 +96,6 @@ function synthesizeMouseDown(x, y, win) {
// We need to make sure the inserted anonymous content can be targeted by the
// event right after having been inserted, and so we need to force a sync
// reflow.
let forceReflow = win.document.documentElement.offsetWidth;
win.document.documentElement.offsetWidth;
EventUtils.synthesizeMouseAtPoint(x, y, {type: "mousedown"}, win);
}

View file

@ -21,6 +21,7 @@ const TEST_URL = "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper
add_task(function* () {
let browser = yield addTab(TEST_URL);
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
let nodeBuilder = () => {
@ -107,6 +108,6 @@ function synthesizeMouseDown(x, y, win) {
// We need to make sure the inserted anonymous content can be targeted by the
// event right after having been inserted, and so we need to force a sync
// reflow.
let forceReflow = win.document.documentElement.offsetWidth;
win.document.documentElement.offsetWidth;
EventUtils.synthesizeMouseAtPoint(x, y, {type: "mousedown"}, win);
}

View file

@ -21,6 +21,7 @@ const TEST_URL = "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper
add_task(function* () {
let browser = yield addTab(TEST_URL);
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
let nodeBuilder = () => {
@ -95,6 +96,6 @@ function synthesizeMouseDown(x, y, win) {
// We need to make sure the inserted anonymous content can be targeted by the
// event right after having been inserted, and so we need to force a sync
// reflow.
let forceReflow = win.document.documentElement.offsetWidth;
win.document.documentElement.offsetWidth;
EventUtils.synthesizeMouseAtPoint(x, y, {type: "mousedown"}, win);
}

View file

@ -8,8 +8,7 @@ const {DirectorManagerFront} = require("devtools/shared/fronts/director-manager"
const {DirectorRegistry} = require("devtools/server/actors/director-registry");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "director-script-target.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "director-script-target.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -50,8 +49,8 @@ function* testDirectorScriptMessagePort(directorManager) {
let { port } = yield installAndEnableDirectorScript(directorManager, {
scriptId: "testDirectorScript_MessagePort",
scriptCode: "(" + (function () {
exports.attach = function ({port}) {
port.onmessage = function (evt) {
exports.attach = function ({port: messagePort}) {
messagePort.onmessage = function (evt) {
// echo messages
evt.target.postMessage(evt.data);
};
@ -69,22 +68,23 @@ function* testDirectorScriptMessagePort(directorManager) {
// needs to explicit start the port
port.start();
var msg = { k1: "v1", k2: [1, 2, 3] };
let msg = { k1: "v1", k2: [1, 2, 3] };
port.postMessage(msg);
var reply = yield waitForMessagePortEvent;
let reply = yield waitForMessagePortEvent;
is(JSON.stringify(reply.data), JSON.stringify(msg), "echo reply received on the MessagePortClient");
is(JSON.stringify(reply.data), JSON.stringify(msg),
"echo reply received on the MessagePortClient");
}
function* testDirectorScriptWindowEval(directorManager) {
let { port } = yield installAndEnableDirectorScript(directorManager, {
scriptId: "testDirectorScript_WindowEval",
scriptCode: "(" + (function () {
exports.attach = function ({window, port}) {
var onpageloaded = function () {
var globalVarValue = window.eval("globalAccessibleVar;");
port.postMessage(globalVarValue);
exports.attach = function ({window, port: evalPort}) {
let onpageloaded = function () {
let globalVarValue = window.eval("globalAccessibleVar;");
evalPort.postMessage(globalVarValue);
};
if (window.document && window.document.readyState === "complete") {
@ -106,19 +106,20 @@ function* testDirectorScriptWindowEval(directorManager) {
// needs to explicit start the port
port.start();
var portEvent = yield waitForMessagePortEvent;
let portEvent = yield waitForMessagePortEvent;
ok(portEvent.data !== "unsecure-eval", "window.eval should be wrapped and safe");
is(portEvent.data, "global-value", "globalAccessibleVar should be accessible through window.eval");
is(portEvent.data, "global-value",
"globalAccessibleVar should be accessible through window.eval");
}
function* testDirectorScriptUnloadOnDetach(directorManager) {
let { port } = yield installAndEnableDirectorScript(directorManager, {
scriptId: "testDirectorScript_unloadOnDetach",
scriptCode: "(" + (function () {
exports.attach = function ({port, onUnload}) {
exports.attach = function ({port: unloadPort, onUnload}) {
onUnload(function () {
port.postMessage("ONUNLOAD");
unloadPort.postMessage("ONUNLOAD");
});
};
}).toString() + ")();",
@ -133,7 +134,8 @@ function* testDirectorScriptUnloadOnDetach(directorManager) {
let waitForDetach = once(directorManager, "director-script-detach");
let waitForMessage = once(port, "message");
directorManager.disableByScriptIds(["testDirectorScript_unloadOnDetach"], {reload: false});
directorManager.disableByScriptIds(["testDirectorScript_unloadOnDetach"],
{reload: false});
let { directorScriptId } = yield waitForDetach;
is(directorScriptId, "testDirectorScript_unloadOnDetach",

View file

@ -8,8 +8,7 @@ const {DirectorManagerFront} = require("devtools/shared/fronts/director-manager"
const {DirectorRegistry} = require("devtools/server/actors/director-registry");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "director-script-target.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "director-script-target.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -43,12 +42,13 @@ function* testErrorOnRequire(directorManager) {
assertIsDirectorScriptError(errorOnRequire);
let { message } = errorOnRequire;
is(message, "Error: NOT IMPLEMENTED", "error.message contains the expected error message");
is(message, "Error: NOT IMPLEMENTED",
"error.message contains the expected error message");
}
function* testErrorOnEvaluate(directorManager) {
// director scripts should send an error events if the director script raise an exception on
// evaluation
// director scripts should send an error events if the director script
// raise an exception on evaluation
let errorOnEvaluate = yield installAndEnableDirectorScript(directorManager, {
scriptId: "testDirectorScript_errorOnEvaluate",
scriptCode: "(" + (function () {
@ -62,8 +62,8 @@ function* testErrorOnEvaluate(directorManager) {
}
function* testErrorOnAttach(directorManager) {
// director scripts should send an error events if the director script raise an exception on
// evaluation
// director scripts should send an error events if the director script
// raise an exception on evaluation
let errorOnAttach = yield installAndEnableDirectorScript(directorManager, {
scriptId: "testDirectorScript_errorOnAttach",
scriptCode: "(" + (function () {
@ -79,9 +79,9 @@ function* testErrorOnAttach(directorManager) {
}
function* testErrorOnDetach(directorManager) {
// director scripts should send an error events if the director script raise an exception on
// evaluation
let attach = yield installAndEnableDirectorScript(directorManager, {
// director scripts should send an error events if the director script
// raise an exception on evaluation
yield installAndEnableDirectorScript(directorManager, {
scriptId: "testDirectorScript_errorOnDetach",
scriptCode: "(" + (function () {
module.exports = function ({onUnload}) {
@ -97,7 +97,8 @@ function* testErrorOnDetach(directorManager) {
let waitForDetach = once(directorManager, "director-script-detach");
let waitForError = once(directorManager, "director-script-error");
directorManager.disableByScriptIds(["testDirectorScript_errorOnDetach"], {reload: false});
directorManager.disableByScriptIds(["testDirectorScript_errorOnDetach"],
{reload: false});
let detach = yield waitForDetach;
let error = yield waitForError;

View file

@ -10,8 +10,7 @@ const {DirectorRegistry} = require("devtools/server/actors/director-registry");
DirectorRegistry.clear();
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "director-script-target.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "director-script-target.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

View file

@ -5,6 +5,7 @@
* Test that we get "nsCycleCollector::Collect" and
* "nsCycleCollector::ForgetSkippable" markers when we force cycle collection.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
@ -12,8 +13,7 @@ add_task(function* () {
// This test runs very slowly on linux32 debug EC2 instances.
requestLongerTimeout(2);
let browser = yield addTab(MAIN_DOMAIN + "doc_force_cc.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_force_cc.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -22,11 +22,14 @@ add_task(function* () {
yield front.connect();
let rec = yield front.startRecording({ withMarkers: true });
let markers = yield waitForMarkerType(front, ["nsCycleCollector::Collect", "nsCycleCollector::ForgetSkippable"]);
let markers = yield waitForMarkerType(front,
["nsCycleCollector::Collect", "nsCycleCollector::ForgetSkippable"]);
yield front.stopRecording(rec);
ok(markers.some(m => m.name === "nsCycleCollector::Collect"), "got some nsCycleCollector::Collect markers");
ok(markers.some(m => m.name === "nsCycleCollector::ForgetSkippable"), "got some nsCycleCollector::Collect markers");
ok(markers.some(m => m.name === "nsCycleCollector::Collect"),
"got some nsCycleCollector::Collect markers");
ok(markers.some(m => m.name === "nsCycleCollector::ForgetSkippable"),
"got some nsCycleCollector::Collect markers");
yield client.close();
gBrowser.removeCurrentTab();

View file

@ -4,12 +4,14 @@
/**
* Test that we get DOMContentLoaded and Load markers
*/
"use strict";
const { TimelineFront } = require("devtools/shared/fronts/timeline");
const MARKER_NAMES = ["document::DOMContentLoaded", "document::Load"];
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
initDebuggerServer();

View file

@ -4,12 +4,14 @@
/**
* Test that we get DOMContentLoaded and Load markers
*/
"use strict";
const { TimelineFront } = require("devtools/shared/fronts/timeline");
const MARKER_NAMES = ["document::DOMContentLoaded", "document::Load"];
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
initDebuggerServer();

View file

@ -4,12 +4,14 @@
/**
* Test that we get DOMContentLoaded and Load markers
*/
"use strict";
const { TimelineFront } = require("devtools/shared/fronts/timeline");
const MARKER_NAMES = ["document::DOMContentLoaded", "document::Load"];
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
initDebuggerServer();

View file

@ -4,13 +4,13 @@
/**
* Test that we get "GarbageCollection" markers.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const MARKER_NAME = "GarbageCollection";
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_force_gc.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_force_gc.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -37,7 +37,8 @@ add_task(function* () {
return current.start;
}
if (current.start < previousStart) {
ok(false, `markers must be in order. ${current.name} marker has later start time (${current.start}) thanprevious: ${previousStart}`);
ok(false, `markers must be in order. ${current.name} marker has later\
start time (${current.start}) thanprevious: ${previousStart}`);
ordered = false;
}
return current.start;

View file

@ -5,6 +5,7 @@
* Test that we get "MinorGC" markers when we continue to steadily allocate
* objects.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
@ -12,7 +13,7 @@ add_task(function* () {
// This test runs very slowly on linux32 debug EC2 instances.
requestLongerTimeout(2);
let doc = yield addTab(MAIN_DOMAIN + "doc_allocations.html");
yield addTab(MAIN_DOMAIN + "doc_allocations.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

View file

@ -4,13 +4,13 @@
/**
* Test that we get "Parse HTML" markers.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const MARKER_NAME = "Parse HTML";
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_innerHTML.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

View file

@ -4,13 +4,13 @@
/**
* Test that we get "Styles" markers with correct meta.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const MARKER_NAME = "Styles";
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -19,8 +19,8 @@ add_task(function* () {
yield front.connect();
let rec = yield front.startRecording({ withMarkers: true });
let markers = yield waitForMarkerType(front, MARKER_NAME, function (markers) {
return markers.some(({restyleHint}) => restyleHint != void 0);
let markers = yield waitForMarkerType(front, MARKER_NAME, function (marker) {
return marker.some(({restyleHint}) => restyleHint != void 0);
});
yield front.stopRecording(rec);

View file

@ -4,14 +4,15 @@
/**
* Test that we get a "TimeStamp" marker.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmConsoleMethod, pmmLoadFrameScripts, pmmClearFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
const { pmmConsoleMethod, pmmLoadFrameScripts, pmmClearFrameScripts }
= require("devtools/client/performance/test/helpers/profiler-mm-utils");
const MARKER_NAME = "TimeStamp";
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -24,12 +25,14 @@ add_task(function* () {
pmmConsoleMethod("timeStamp");
pmmConsoleMethod("timeStamp", "myLabel");
let markers = yield waitForMarkerType(front, MARKER_NAME, markers => markers.length >= 2);
let markers = yield waitForMarkerType(front, MARKER_NAME, m => m.length >= 2);
yield front.stopRecording(rec);
ok(markers.every(({stack}) => typeof stack === "number"), "All markers have stack references.");
ok(markers.every(({name}) => name === "TimeStamp"), "All markers found are TimeStamp markers");
ok(markers.every(({stack}) => typeof stack === "number"),
"All markers have stack references.");
ok(markers.every(({name}) => name === "TimeStamp"),
"All markers found are TimeStamp markers");
ok(markers.length === 2, "found 2 TimeStamp markers");
ok(markers.every(({start, end}) => typeof start === "number" && start === end),
"All markers have equal start and end times");

View file

@ -10,50 +10,56 @@ const URL2 = MAIN_DOMAIN + "navigate-second.html";
var events = require("sdk/event/core");
var client;
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
SpecialPowers.pushPrefEnv(
{"set": [["dom.require_user_interaction_for_beforeunload", false]]});
// State machine to check events order
var i = 0;
function assertEvent(event, data) {
let x = 0;
switch (i++) {
case x++:
case 0:
is(event, "request", "Get first page load");
is(data, URL1);
break;
case x++:
case 1:
is(event, "load-new-document", "Ask to load the second page");
break;
case x++:
case 2:
is(event, "unload-dialog", "We get the dialog on first page unload");
break;
case x++:
case 3:
is(event, "will-navigate", "The very first event is will-navigate on server side");
is(data.newURI, URL2, "newURI property is correct");
break;
case x++:
is(event, "request", "RDP is async with messageManager, the request happens after will-navigate");
case 4:
is(event, "request",
"RDP is async with messageManager, the request happens after will-navigate");
is(data, URL2);
break;
case x++:
case 5:
is(event, "tabNavigated", "After the request, the client receive tabNavigated");
is(data.state, "start", "state is start");
is(data.url, URL2, "url property is correct");
is(data.nativeConsoleAPI, true, "nativeConsoleAPI is correct");
break;
case x++:
case 6:
is(event, "DOMContentLoaded");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(content.document.readyState, "interactive");
break;
case x++:
case 7:
is(event, "load");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(content.document.readyState, "complete");
break;
case x++:
is(event, "navigate", "Then once the second doc is loaded, we get the navigate event");
is(content.document.readyState, "complete", "navigate is emitted only once the document is fully loaded");
case 8:
is(event, "navigate",
"Then once the second doc is loaded, we get the navigate event");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(content.document.readyState, "complete",
"navigate is emitted only once the document is fully loaded");
break;
case x++:
case 9:
is(event, "tabNavigated", "Finally, the receive the client event");
is(data.state, "stop", "state is stop");
is(data.url, URL2, "url property is correct");
@ -102,22 +108,21 @@ function getServerTabActor(callback) {
client = new DebuggerClient(transport);
connectDebuggerClient(client).then(form => {
let actorID = form.actor;
client.attachTab(actorID, function (aResponse, aTabClient) {
client.attachTab(actorID, function (response, tabClient) {
// !Hack! Retrieve a server side object, the BrowserTabActor instance
let tabActor = DebuggerServer._searchAllConnectionsForActor(actorID);
callback(tabActor);
});
});
client.addListener("tabNavigated", function (aEvent, aPacket) {
assertEvent("tabNavigated", aPacket);
client.addListener("tabNavigated", function (event, packet) {
assertEvent("tabNavigated", packet);
});
}
function test() {
// Open a test tab
addTab(URL1).then(function (browser) {
let doc = browser.contentDocument;
getServerTabActor(function (tabActor) {
// In order to listen to internal will-navigate/navigate events
events.on(tabActor, "will-navigate", function (data) {
@ -140,9 +145,8 @@ function test() {
// Load another document in this doc to dispatch these events
assertEvent("load-new-document");
content.location = URL2;
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, URL2);
});
});
}

View file

@ -5,11 +5,12 @@
* Test that we have allocation data coming from the front.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_allocations.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_allocations.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -17,7 +18,8 @@ add_task(function* () {
let front = PerformanceFront(client, form);
yield front.connect();
let rec = yield front.startRecording({ withMarkers: true, withAllocations: true, withTicks: true });
let rec = yield front.startRecording(
{ withMarkers: true, withAllocations: true, withTicks: true });
yield waitUntil(() => rec.getAllocations().frames.length);
yield waitUntil(() => rec.getAllocations().timestamps.length);
@ -26,10 +28,11 @@ add_task(function* () {
yield front.stopRecording(rec);
let { frames, timestamps, sizes, sites } = rec.getAllocations();
let { timestamps, sizes } = rec.getAllocations();
is(timestamps.length, sizes.length, "we have the same amount of timestamps and sizes");
ok(timestamps.every(time => time > 0 && typeof time === "number"), "all timestamps have numeric values");
ok(timestamps.every(time => time > 0 && typeof time === "number"),
"all timestamps have numeric values");
ok(sizes.every(n => n > 0 && typeof n === "number"), "all sizes are positive numbers");
yield front.destroy();

View file

@ -7,12 +7,13 @@
* a recording is stopped.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmIsProfilerActive, pmmStopProfiler, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
const { pmmIsProfilerActive, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

View file

@ -6,8 +6,10 @@
* is destroyed if there are other consumers using it.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmIsProfilerActive, pmmStopProfiler, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
const { pmmIsProfilerActive, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
add_task(function* () {
yield addTab(MAIN_DOMAIN + "doc_perf.html");

View file

@ -8,8 +8,10 @@
* addon was installed and automatically activated the profiler module).
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmIsProfilerActive, pmmStartProfiler, pmmStopProfiler, pmmLoadFrameScripts, pmmClearFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
const { pmmIsProfilerActive, pmmStartProfiler, pmmLoadFrameScripts, pmmClearFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
add_task(function* () {
// Ensure the profiler is already running when the test starts.
@ -29,7 +31,7 @@ add_task(function* () {
let firstFront = PerformanceFront(client, form);
yield firstFront.connect();
let recording = yield firstFront.startRecording();
yield firstFront.startRecording();
yield addTab(MAIN_DOMAIN + "doc_perf.html");
let client2 = new DebuggerClient(DebuggerServer.connectPipe());

View file

@ -5,11 +5,12 @@
* Test functionality of real time markers.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -34,7 +35,8 @@ add_task(function* () {
front.on("timeline-data", handler);
let rec = yield front.startRecording({ withMarkers: true, withMemory: true, withTicks: true });
let rec = yield front.startRecording(
{ withMarkers: true, withMemory: true, withTicks: true });
yield Promise.all(Object.keys(deferreds).map(type => deferreds[type].promise));
yield front.stopRecording(rec);
front.off("timeline-data", handler);
@ -49,15 +51,18 @@ add_task(function* () {
function handler(name, data) {
if (name === "markers") {
if (counters.markers.length >= 1) { return; }
if (counters.markers.length >= 1) {
return;
}
ok(data.markers[0].start, "received atleast one marker with `start`");
ok(data.markers[0].end, "received atleast one marker with `end`");
ok(data.markers[0].name, "received atleast one marker with `name`");
counters.markers.push(data.markers);
}
else if (name === "memory") {
if (counters.memory.length >= 3) { return; }
} else if (name === "memory") {
if (counters.memory.length >= 3) {
return;
}
let { delta, measurement } = data;
is(typeof delta, "number", "received `delta` in memory event");
ok(delta > lastMemoryDelta, "received `delta` in memory event");
@ -65,9 +70,10 @@ add_task(function* () {
counters.memory.push({ delta, measurement });
lastMemoryDelta = delta;
}
else if (name === "ticks") {
if (counters.ticks.length >= 3) { return; }
} else if (name === "ticks") {
if (counters.ticks.length >= 3) {
return;
}
let { delta, timestamps } = data;
ok(delta > lastTickDelta, "received `delta` in ticks event");
@ -76,11 +82,9 @@ add_task(function* () {
counters.ticks.push({ delta, timestamps });
lastTickDelta = delta;
}
else if (name === "frames") {
} else if (name === "frames") {
// Nothing to do here.
}
else {
} else {
ok(false, `Received unknown event: ${name}`);
}

View file

@ -6,11 +6,12 @@
* completed, and rec data.
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -18,7 +19,8 @@ add_task(function* () {
let front = PerformanceFront(client, form);
yield front.connect();
let rec = yield front.startRecording({ withMarkers: true, withTicks: true, withMemory: true });
let rec = yield front.startRecording(
{ withMarkers: true, withTicks: true, withMemory: true });
ok(rec.isRecording(), "RecordingModel is recording when created");
yield busyWait(100);
yield waitUntil(() => rec.getMemory().length);
@ -43,7 +45,8 @@ add_task(function* () {
ok(rec.isCompleted(), "recording is completed once it has profile data");
} else {
ok(!rec.isCompleted(), "recording is not yet completed on 'recording-stopping'");
ok(rec.isFinalizing(), "recording is considered finalizing between 'recording-stopping' and 'recording-stopped'");
ok(rec.isFinalizing(),
"recording is finalized between 'recording-stopping' and 'recording-stopped'");
}
yield stopped;

View file

@ -5,14 +5,15 @@
* Test that buffer status is correctly updated in recording models.
*/
"use strict";
var BUFFER_SIZE = 20000;
var config = { bufferSize: BUFFER_SIZE };
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -23,8 +24,10 @@ add_task(function* () {
yield front.setProfilerStatusInterval(10);
let model = yield front.startRecording(config);
let stats = yield once(front, "profiler-status");
is(stats.totalSize, BUFFER_SIZE, `profiler-status event has totalSize: ${stats.totalSize}`);
ok(stats.position < BUFFER_SIZE, `profiler-status event has position: ${stats.position}`);
is(stats.totalSize, BUFFER_SIZE,
`profiler-status event has totalSize: ${stats.totalSize}`);
ok(stats.position < BUFFER_SIZE,
`profiler-status event has position: ${stats.position}`);
ok(stats.generation >= 0, `profiler-status event has generation: ${stats.generation}`);
ok(stats.isActive, "profiler-status event is isActive");
is(typeof stats.currentTime, "number", "profiler-status event has currentTime");
@ -36,7 +39,8 @@ add_task(function* () {
let checkCount = 0;
while (lastBufferStatus < 1) {
let currentBufferStatus = front.getBufferUsageForRecording(model);
ok(currentBufferStatus > lastBufferStatus, `buffer is more filled than before: ${currentBufferStatus} > ${lastBufferStatus}`);
ok(currentBufferStatus > lastBufferStatus,
`buffer is more filled than before: ${currentBufferStatus} > ${lastBufferStatus}`);
lastBufferStatus = currentBufferStatus;
checkCount++;
yield once(front, "profiler-status");
@ -46,7 +50,8 @@ add_task(function* () {
is(lastBufferStatus, 1, "buffer usage cannot surpass 100%");
yield front.stopRecording(model);
is(front.getBufferUsageForRecording(model), null, "buffer usage should be null when no longer recording.");
is(front.getBufferUsageForRecording(model), null,
"buffer usage should be null when no longer recording.");
yield front.destroy();
yield client.close();

View file

@ -6,13 +6,15 @@
* normalized before passed to consumers.
*/
const WAIT_TIME = 1000; // ms
"use strict";
// time in ms
const WAIT_TIME = 1000;
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -26,7 +28,8 @@ add_task(function* () {
let firstRecordingStartTime = firstRecording._startTime;
info("Started profiling at: " + firstRecordingStartTime);
busyWait(WAIT_TIME); // allow the profiler module to sample some cpu activity
// allow the profiler module to sample some cpu activity
busyWait(WAIT_TIME);
yield front.stopRecording(firstRecording);
@ -39,7 +42,8 @@ add_task(function* () {
let secondRecordingStartTime = secondRecording._startTime;
info("Started profiling at: " + secondRecordingStartTime);
busyWait(WAIT_TIME); // allow the profiler module to sample more cpu activity
// allow the profiler module to sample more cpu activity
busyWait(WAIT_TIME);
yield front.stopRecording(secondRecording);
let secondRecordingProfile = secondRecording.getProfile();
@ -53,7 +57,9 @@ add_task(function* () {
"The second recorded sample times were normalized.");
ok(secondRecordingSamples[0][TIME_SLOT] > 0,
"The second recorded sample times were normalized correctly.");
ok(!secondRecordingSamples.find(e => e[TIME_SLOT] + secondRecordingStartTime <= firstRecording.getDuration()),
ok(!secondRecordingSamples.find(
e => e[TIME_SLOT] + secondRecordingStartTime <= firstRecording.getDuration()
),
"There should be no samples from the first recording in the second one, " +
"even though the total number of frames did not overflow.");

View file

@ -7,13 +7,15 @@
* devtools/client/performance/modules/logic/tree-model.js will have to be changed.
*/
const WAIT_TIME = 1000; // ms
"use strict";
// Time in ms
const WAIT_TIME = 1000;
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "doc_perf.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -22,7 +24,8 @@ add_task(function* () {
yield front.connect();
let rec = yield front.startRecording();
busyWait(WAIT_TIME); // allow the profiler module to sample some cpu activity
// allow the profiler module to sample some cpu activity
busyWait(WAIT_TIME);
yield front.stopRecording(rec);
let profile = rec.getProfile();

View file

@ -1,9 +1,11 @@
"use strict";
var gClient;
function test() {
waitForExplicitFinish();
var {ActorRegistryFront} = require("devtools/shared/fronts/actor-registry");
var actorURL = "chrome://mochitests/content/chrome/devtools/server/tests/mochitest/hello-actor.js";
let {ActorRegistryFront} = require("devtools/shared/fronts/actor-registry");
let actorURL = "chrome://mochitests/content/chrome/devtools/server/tests/mochitest/hello-actor.js";
if (!DebuggerServer.initialized) {
DebuggerServer.init();
@ -13,64 +15,60 @@ function test() {
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect()
.then(() => gClient.listTabs())
.then(aResponse => {
var options = {
.then(response => {
let options = {
prefix: "helloActor",
constructor: "HelloActor",
type: { tab: true }
};
var registry = ActorRegistryFront(gClient, aResponse);
let registry = ActorRegistryFront(gClient, response);
registry.registerActor(actorURL, options).then(actorFront => {
gClient.listTabs(response => {
var tab = response.tabs[response.selected];
gClient.listTabs(res => {
let tab = res.tabs[res.selected];
ok(!!tab.helloActor, "Hello actor must exist");
// Make sure actor's state is maintained across listTabs requests.
checkActorState(tab.helloActor, () => {
// Clean up
actorFront.unregister().then(() => {
gClient.close().then(() => {
DebuggerServer.destroy();
gClient = null;
finish();
});
});
});
checkActorState(tab.helloActor, cleanupActor.bind(this, actorFront));
});
});
});
}
function checkActorState(helloActor, callback) {
getCount(helloActor, response => {
ok(!response.error, "No error");
is(response.count, 1, "The counter must be valid");
getCount(helloActor, response => {
ok(!response.error, "No error");
is(response.count, 2, "The counter must be valid");
gClient.listTabs(response => {
var tab = response.tabs[response.selected];
is(tab.helloActor, helloActor, "Hello actor must be valid");
getCount(helloActor, response => {
ok(!response.error, "No error");
is(response.count, 3, "The counter must be valid");
callback();
});
});
function cleanupActor(actorFront) {
// Clean up
actorFront.unregister().then(() => {
gClient.close().then(() => {
DebuggerServer.destroy();
gClient = null;
finish();
});
});
}
function getCount(actor, callback) {
gClient.request({
return gClient.request({
to: actor,
type: "count"
}, callback);
}
var checkActorState = Task.async(function* (helloActor, callback) {
let response = yield getCount(helloActor);
ok(!response.error, "No error");
is(response.count, 1, "The counter must be valid");
response = yield getCount(helloActor);
ok(!response.error, "No error");
is(response.count, 2, "The counter must be valid");
let {tabs, selected} = yield gClient.listTabs();
let tab = tabs[selected];
is(tab.helloActor, helloActor, "Hello actor must be valid");
response = yield getCount(helloActor);
ok(!response.error, "No error");
is(response.count, 3, "The counter must be valid");
callback();
});

View file

@ -163,8 +163,10 @@ function testAddIframe(front) {
front.on("stores-update", onStoresUpdate);
// eslint-disable-next-line mozilla/no-cpows-in-tests
let iframe = content.document.createElement("iframe");
iframe.src = ALT_DOMAIN_SECURED + "storage-secured-iframe.html";
// eslint-disable-next-line mozilla/no-cpows-in-tests
content.document.querySelector("body").appendChild(iframe);
});
}
@ -229,12 +231,14 @@ function testRemoveIframe(front) {
front.on("stores-update", onStoresUpdate);
for (let iframe of content.document.querySelectorAll("iframe")) {
if (iframe.src.startsWith("http:")) {
iframe.remove();
break;
ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
for (let iframe of content.document.querySelectorAll("iframe")) {
if (iframe.src.startsWith("http:")) {
iframe.remove();
break;
}
}
}
});
});
}

View file

@ -228,7 +228,7 @@ const IDBValues = {
},
]
},
"http://sectest1.example.org" : {},
"http://sectest1.example.org": {},
"https://sectest1.example.org": {
"idb-s1 (default)": [
{
@ -297,7 +297,7 @@ const IDBValues = {
],
"idb2 (default)#obj3": []
},
"http://sectest1.example.org" : {},
"http://sectest1.example.org": {},
"https://sectest1.example.org": {
"idb-s1 (default)#obj-s1": [
{
@ -331,13 +331,6 @@ const IDBValues = {
}
};
function finishTests(client) {
let closeConnection = () => {
};
}
function* testStores(data) {
ok(data.cookies, "Cookies storage actor is present");
ok(data.localStorage, "Local Storage storage actor is present");
@ -514,8 +507,8 @@ var testIndexedDBs = Task.async(function* (index, hosts, indexedDBActor) {
yield testIndexedDBs(++index, hosts, indexedDBActor);
});
var testObjectStores = Task.async(function* (index, hosts, indexedDBActor) {
let host = Object.keys(hosts)[index];
var testObjectStores = Task.async(function* (ix, hosts, indexedDBActor) {
let host = Object.keys(hosts)[ix];
let matchItems = (data, db) => {
is(data.total, IDBValues.objectStoreDetails[host][db].length,
"Number of object stores in host " + host + " matches");
@ -559,10 +552,10 @@ var testObjectStores = Task.async(function* (index, hosts, indexedDBActor) {
yield indexedDBActor.getStoreObjects(host, [JSON.stringify(objName)])
), objName[0]);
}
if (index == Object.keys(hosts).length - 1) {
if (ix == Object.keys(hosts).length - 1) {
return;
}
yield testObjectStores(++index, hosts, indexedDBActor);
yield testObjectStores(++ix, hosts, indexedDBActor);
});
var testIDBEntries = Task.async(function* (index, hosts, indexedDBActor) {

View file

@ -5,11 +5,6 @@
"use strict";
const {StorageFront} = require("devtools/shared/fronts/storage");
const beforeReload = {
cookies: ["http://test1.example.org", "https://sectest1.example.org"],
localStorage: ["http://test1.example.org", "http://sectest1.example.org"],
sessionStorage: ["http://test1.example.org", "http://sectest1.example.org"],
};
const TESTS = [
// index 0
@ -303,6 +298,7 @@ function* finishTests(client) {
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "storage-updates.html");
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = browser.contentDocument;
initDebuggerServer();

View file

@ -10,8 +10,7 @@
const {StyleSheetsFront} = require("devtools/shared/fronts/stylesheets");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "stylesheets-nested-iframes.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "stylesheets-nested-iframes.html");
info("Initialising the debugger server and client.");
initDebuggerServer();

View file

@ -13,8 +13,7 @@
const {TimelineFront} = require("devtools/shared/fronts/timeline");
add_task(function* () {
let browser = yield addTab("data:text/html;charset=utf-8,mop");
let doc = browser.contentDocument;
yield addTab("data:text/html;charset=utf-8,mop");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -27,7 +26,10 @@ add_task(function* () {
ok(!isActive, "The TimelineFront is not initially recording");
info("Flush any pending reflows");
let forceSyncReflow = doc.body.innerHeight;
ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
// forceSyncReflow
content.document.body.innerHeight;
});
info("Start recording");
yield front.start({ withMarkers: true });
@ -37,18 +39,25 @@ add_task(function* () {
info("Change some style on the page to cause style/reflow/paint");
let onMarkers = once(front, "markers");
doc.body.style.padding = "10px";
ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
content.document.body.style.padding = "10px";
});
let markers = yield onMarkers;
ok(true, "The markers event was fired");
ok(markers.length > 0, "Markers were returned");
info("Flush pending reflows again");
forceSyncReflow = doc.body.innerHeight;
ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
// forceSyncReflow
content.document.body.innerHeight;
});
info("Change some style on the page to cause style/paint");
onMarkers = once(front, "markers");
doc.body.style.backgroundColor = "red";
ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
content.document.body.style.backgroundColor = "red";
});
markers = yield onMarkers;
ok(markers.length > 0, "markers were returned");

View file

@ -10,8 +10,7 @@
const {TimelineFront} = require("devtools/shared/fronts/timeline");
add_task(function* () {
let browser = yield addTab("data:text/html;charset=utf-8,mop");
let doc = browser.contentDocument;
yield addTab("data:text/html;charset=utf-8,mop");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

View file

@ -10,8 +10,7 @@
const {TimelineFront} = require("devtools/shared/fronts/timeline");
add_task(function* () {
let browser = yield addTab(MAIN_DOMAIN + "timeline-iframe-parent.html");
let doc = browser.contentDocument;
yield addTab(MAIN_DOMAIN + "timeline-iframe-parent.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -24,7 +23,8 @@ add_task(function* () {
// Check that we get markers for a few iterations of the timer that runs in
// the child frame.
for (let i = 0; i < 3; i++) {
yield wait(300); // That's the time the child frame waits before changing styles.
// That's the time the child frame waits before changing styles.
yield wait(300);
let markers = yield once(front, "markers");
ok(markers.length, "Markers were received for operations in the child frame");
}

View file

@ -1,11 +1,13 @@
<html>
<head>
<script>
// change the eval function to ensure the window object in the debug-script is correctly wrapped
/* exported globalAccessibleVar */
"use strict";
// change the eval function to ensure the window object
// in the debug-script is correctly wrapped
window.eval = function () {
return "unsecure-eval-called";
};
var globalAccessibleVar = "global-value";
</script>
</head>

View file

@ -5,11 +5,13 @@
</head>
<body>
<script>
"use strict";
window.allocs = [];
window.onload = function() {
window.onload = function () {
function allocator() {
for (var i = 0; i < 1000; i++) {
window.allocs.push(new Object);
for (let i = 0; i < 1000; i++) {
window.allocs.push(new Object());
}
}

View file

@ -10,6 +10,8 @@
<body>
<script type="text/javascript">
"use strict";
window.test = function () {
document.body.expando1 = { cycle: document.body };
SpecialPowers.Cu.forceCC();

View file

@ -10,12 +10,15 @@
<body>
<script type="text/javascript">
"use strict";
var x = 1;
window.test = function () {
SpecialPowers.Cu.forceGC();
document.body.style.borderTop = x + "px solid red";
x = 1^x;
document.body.innerHeight; // flush pending reflows
x = 1 ^ x;
// flush pending reflows
document.body.innerHeight;
// Prevent this script from being garbage collected.
setTimeout(window.test, 100);

View file

@ -10,11 +10,14 @@
<body>
<script type="text/javascript">
"use strict";
var x = 1;
function test() {
document.body.style.borderTop = x + "px solid red";
x = 1^x;
document.body.innerHeight; // flush pending reflows
x = 1 ^ x;
// flush pending reflows
document.body.innerHeight;
}
// Prevent this script from being garbage collected.

View file

@ -6,9 +6,9 @@
<body>
First
<script>
window.onbeforeunload=function(e){
e.returnValue="?";
"use strict";
window.onbeforeunload = function (e) {
e.returnValue = "?";
};
</script>
</body>

View file

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* exported openTabAndSetupStorage, clearStorage */
"use strict";
/**

View file

@ -8,6 +8,7 @@ Iframe for testing multiple host detetion in storage actor
</head>
<body>
<script>
"use strict";
document.cookie = "uc1=foobar; domain=.example.org; path=/; secure=true";
localStorage.setItem("iframe-u-ls1", "foobar");
@ -15,12 +16,13 @@ sessionStorage.setItem("iframe-u-ss1", "foobar1");
sessionStorage.setItem("iframe-u-ss2", "foobar2");
console.log("added cookies and stuff from unsecured iframe");
window.clear = function*() {
window.clear = function* () {
document.cookie = "uc1=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
localStorage.clear();
sessionStorage.clear();
console.log("removed cookies and stuff from unsecured iframe");
}
};
</script>
</body>
</html>

View file

@ -7,12 +7,13 @@
<body>
<h1>Child frame</h1>
<script>
"use strict";
var h1 = document.querySelector("h1");
setInterval(function() {
h1.style.backgroundColor = "rgb(" + ((Math.random()*255)|0) + "," +
((Math.random()*255)|0) + "," +
((Math.random()*255)|0) +")";
h1.style.width = ((Math.random()*500)|0) + "px";
setInterval(function () {
h1.style.backgroundColor = "rgb(" + ((Math.random() * 255)|0) + "," +
((Math.random() * 255)|0) + "," +
((Math.random() * 255)|0) + ")";
h1.style.width = ((Math.random() * 500)|0) + "px";
}, 300);
</script>
</body>

View file

@ -76,8 +76,6 @@
#include "ContentParent.h"
#include "TabParent.h"
#include "mozilla/plugins/PPluginWidgetParent.h"
#include "../plugins/ipc/PluginWidgetParent.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/GuardObjects.h"
@ -102,6 +100,11 @@
#include "nsPrincipal.h"
#ifdef XP_WIN
#include "mozilla/plugins/PPluginWidgetParent.h"
#include "../plugins/ipc/PluginWidgetParent.h"
#endif
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
#endif
@ -1424,6 +1427,7 @@ nsFrameLoader::SwapWithOtherRemoteLoader(nsFrameLoader* aOther,
aOther->mRemoteBrowser->SetBrowserDOMWindow(browserDOMWindow);
mRemoteBrowser->SetBrowserDOMWindow(otherBrowserDOMWindow);
#ifdef XP_WIN
// Native plugin windows used by this remote content need to be reparented.
if (nsPIDOMWindowOuter* newWin = ourDoc->GetWindow()) {
RefPtr<nsIWidget> newParent = nsGlobalWindow::Cast(newWin)->GetMainWidget();
@ -1433,6 +1437,7 @@ nsFrameLoader::SwapWithOtherRemoteLoader(nsFrameLoader* aOther,
static_cast<mozilla::plugins::PluginWidgetParent*>(iter.Get()->GetKey())->SetParent(newParent);
}
}
#endif // XP_WIN
MaybeUpdatePrimaryTabParent(eTabParentRemoved);
aOther->MaybeUpdatePrimaryTabParent(eTabParentRemoved);

View file

@ -68,8 +68,6 @@ nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
// and thus will be the same.
if (hasListeners) {
// save the old attribute so we can set up the mutation event properly
// XXXbz if the old rule points to the same declaration as the new one,
// this is getting the new attr value, not the old one....
nsAutoString oldValueStr;
modification = GetAttr(kNameSpaceID_None, nsGkAtoms::style,
oldValueStr);

View file

@ -65,7 +65,7 @@ tags = audiochannel
skip-if = true # bug 1332862
[test_browserElement_inproc_AudioChannel_nested.html]
tags = audiochannel
skip-if = toolkit == 'android' # bug 1332850
skip-if = true # bug 1332850, 1332862
[test_browserElement_inproc_BackForward.html]
[test_browserElement_inproc_BadScreenshot.html]
[test_browserElement_inproc_DocumentFirstPaint.html]

View file

@ -17,7 +17,7 @@ UNIFIED_SOURCES += [
LOCAL_INCLUDES += [
'/dom/canvas',
'/media/libyuv/include'
'/media/libyuv/libyuv/include'
]
FINAL_LIBRARY = 'xul-gtest'

View file

@ -210,7 +210,7 @@ LOCAL_INCLUDES += [
'/layout/generic',
'/layout/style',
'/layout/xul',
'/media/libyuv/include',
'/media/libyuv/libyuv/include',
]
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']

View file

@ -4,12 +4,13 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=545812
Test plugins with DOM full-screen API:
* Presence of plugins has no effect on request for full-screen on MacOS.
* Request for full-screen is denied when windowed plugin in current doc is present.
* Request for full-screen is denied when windowed plugin in subdocument is present.
* Request for full-screen is not denied when the only plugin present is windowless.
* Adding an existing (out-of-doc) windowed plugin to a full-screen document causes document to exit full-screen.
* Create windowed plugin and adding it to full-screen document caused exit from full-screen.
* On non-Windows, plugins can only be windowless, so the presence of plugins
should have no effect on request for full-screen.
-->
<head>
@ -65,7 +66,7 @@ function removeElement(e) {
e.remove();
}
const isMacOs = navigator.appVersion.indexOf("Macintosh") != -1;
const supportsWindowedMode = navigator.appVersion.indexOf("Windows") != -1;
var windowedPlugin = null;
@ -83,37 +84,38 @@ function startTest() {
ok(!document.fullscreenElement, "Should not be in full-screen mode initially");
document.body.requestFullscreen();
// Focus the windowed plugin. On MacOS we should still enter full-screen mode,
// on windows the pending request for full-screen should be denied.
// Focus the windowed plugin. On non-Windows we should still enter
// full-screen mode, on Windows the pending request for full-screen should
// be denied.
e("windowed-plugin").focus();
if (isMacOs) {
// Running on MacOS, all plugins are effectively windowless, request for full-screen should be granted.
// Continue test in the (mac-specific) "fullscreenchange" handler.
addFullscreenChangeContinuation("enter", macFullScreenChange1);
if (!supportsWindowedMode) {
// If all plugins are effectively windowless, request for full-screen should be granted.
// Continue test in the "fullscreenchange" handler.
addFullscreenChangeContinuation("enter", windowlessFullScreenChange1);
} else {
// Non-MacOS, request should be denied, carry on the test after receiving error event.
addFullscreenErrorContinuation(nonMacTest);
// On Windows, request should be denied, carry on the test after receiving error event.
addFullscreenErrorContinuation(windowsTest);
}
}
function nonMacTest() {
function windowsTest() {
ok(!document.fullscreenElement, "Request for full-screen with focused windowed plugin should be denied.");
// Focus a regular html element, and re-request full-screen, request should be granted.
e("windowless-plugin").focus();
addFullscreenChangeContinuation("enter", nonMacTest2);
addFullscreenChangeContinuation("enter", windowsTest2);
document.body.requestFullscreen();
}
function nonMacTest2() {
function windowsTest2() {
ok(document.fullscreenElement, "Request for full-screen with non-plugin focused should be granted.");
// Focus a windowed plugin, full-screen should be revoked.
addFullscreenChangeContinuation("exit", nonMacTest3);
addFullscreenChangeContinuation("exit", windowsTest3);
e("windowed-plugin").focus();
}
function nonMacTest3() {
function windowsTest3() {
ok(!document.fullscreenElement, "Full-screen should have been revoked when windowed-plugin was focused.");
// Remove windowed plugins before closing the window
// to work around bug 1237853.
@ -131,25 +133,25 @@ function createWindowedPlugin() {
return p;
}
function macFullScreenChange1(event) {
ok(document.fullscreenElement, "Requests for full-screen with focused windowed plugins should be granted on MacOS");
function windowlessFullScreenChange1(event) {
ok(document.fullscreenElement, "Requests for full-screen with focused windowed plugins should be granted on non-Windows");
// Create a new windowed plugin, and add that to the document. Should *not* exit full-screen mode on MacOS.
// Create a new windowed plugin, and add that to the document. Should *not* exit full-screen mode on MacOS/Linux.
windowedPlugin = createWindowedPlugin();
document.body.appendChild(windowedPlugin);
// Focus windowed plugin. Should not exit full-screen mode on MacOS.
// Focus windowed plugin. Should not exit full-screen mode on MacOS/Linux.
windowedPlugin.focus();
setTimeout(
function() {
ok(document.fullscreenElement, "Adding & focusing a windowed plugin to document should not cause full-screen to exit on MacOS.");
addFullscreenChangeContinuation("exit", macFullScreenChange2);
ok(document.fullscreenElement, "Adding & focusing a windowed plugin to document should not cause full-screen to exit on MacOS/Linux.");
addFullscreenChangeContinuation("exit", windowlessFullScreenChange2);
document.exitFullscreen();
}, 0);
}
function macFullScreenChange2(event) {
function windowlessFullScreenChange2(event) {
ok(!document.fullscreenElement, "Should have left full-screen mode after calling document.exitFullscreen().");
opener.nextTest();
}

View file

@ -131,8 +131,11 @@ support-files =
[test_blob_file_backed.html]
[test_blob_simple.html]
[test_blob_worker_crash.html]
skip-if = e10s && os == 'win' && os_version == '6.1' # Bug 1342415
[test_blob_worker_xhr_post.html]
skip-if = e10s && os == 'win' && os_version == '6.1' # Bug 1342415
[test_blob_worker_xhr_post_multifile.html]
skip-if = e10s && os == 'win' && os_version == '6.1' # Bug 1342415
[test_blob_worker_xhr_read.html]
[test_blob_worker_xhr_read_slice.html]
[test_blocked_order.html]

View file

@ -1,4 +1,4 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* 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/. */
@ -13,7 +13,7 @@ namespace plugins {
/**
* PPluginWidget - a nsIWidget'ish protocol for windowed plugins in e10s.
* On windows and linux we create native widgets in chrome which we then manage
* On windows we create native widgets in chrome which we then manage
* from content. On the content side there's PluginWidgetProxy which
* implements nsIWidget. We hand this around layout and plugins code. Anything
* not dealt with via PluginWidgetProxy falls through to PuppetWidget. Native

View file

@ -20,7 +20,6 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
#include "mozilla/plugins/PluginWidgetChild.h"
#include "mozilla/IMEStateManager.h"
#include "mozilla/ipc/DocumentRendererChild.h"
#include "mozilla/ipc/URIUtils.h"
@ -39,6 +38,7 @@
#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/plugins/PPluginWidgetChild.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Move.h"
@ -123,6 +123,10 @@
#include "nsISupportsPrimitives.h"
#include "mozilla/Telemetry.h"
#ifdef XP_WIN
#include "mozilla/plugins/PluginWidgetChild.h"
#endif
#ifdef NS_PRINTING
#include "nsIPrintSession.h"
#include "nsIPrintSettings.h"
@ -3143,16 +3147,22 @@ TabChild::StopAwaitingLargeAlloc()
mozilla::plugins::PPluginWidgetChild*
TabChild::AllocPPluginWidgetChild()
{
return new mozilla::plugins::PluginWidgetChild();
#ifdef XP_WIN
return new mozilla::plugins::PluginWidgetChild();
#else
MOZ_ASSERT_UNREACHABLE();
return nullptr;
#endif
}
bool
TabChild::DeallocPPluginWidgetChild(mozilla::plugins::PPluginWidgetChild* aActor)
{
delete aActor;
return true;
delete aActor;
return true;
}
#ifdef XP_WIN
nsresult
TabChild::CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut)
{
@ -3183,6 +3193,7 @@ TabChild::CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut)
pluginWidget.forget(aOut);
return rv;
}
#endif // XP_WIN
ScreenIntSize
TabChild::GetInnerSize()

View file

@ -62,10 +62,6 @@ namespace widget {
struct AutoCacheNativeKeyCommands;
} // namespace widget
namespace plugins {
class PluginWidgetChild;
} // namespace plugins
namespace dom {
class TabChild;
@ -609,7 +605,9 @@ public:
bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) override;
#ifdef XP_WIN
nsresult CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut);
#endif
LayoutDeviceIntPoint GetClientOffset() const { return mClientOffset; }
LayoutDeviceIntPoint GetChromeDisplacement() const { return mChromeDisp; };

View file

@ -20,7 +20,6 @@
#include "mozilla/dom/Event.h"
#include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/plugins/PluginWidgetParent.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
@ -32,6 +31,7 @@
#include "mozilla/layers/AsyncDragMetrics.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/plugins/PPluginWidgetParent.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/net/NeckoChild.h"
@ -100,6 +100,10 @@
#include "nsIGroupedSHistory.h"
#include "PartialSHistory.h"
#ifdef XP_WIN
#include "mozilla/plugins/PluginWidgetParent.h"
#endif
#if defined(XP_WIN) && defined(ACCESSIBILITY)
#include "mozilla/a11y/AccessibleWrap.h"
#include "mozilla/a11y/nsWinUtils.h"
@ -386,6 +390,7 @@ TabParent::DestroyInternal()
frame->Destroy();
}
#ifdef XP_WIN
// Let all PluginWidgets know we are tearing down. Prevents
// these objects from sending async events after the child side
// is shut down.
@ -395,6 +400,7 @@ TabParent::DestroyInternal()
static_cast<mozilla::plugins::PluginWidgetParent*>(
iter.Get()->GetKey())->ParentDestroy();
}
#endif
}
void
@ -937,18 +943,22 @@ TabParent::RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
auto parentDoc = static_cast<a11y::DocAccessibleParent*>(aParentDoc);
mozilla::ipc::IPCResult added = parentDoc->AddChildDoc(doc, aParentID);
if (!added) {
#ifdef DEBUG
return added;
#else
return IPC_OK();
#endif
}
#ifdef XP_WIN
MOZ_ASSERT(aDocCOMProxy.IsNull());
if (added) {
a11y::WrapperFor(doc)->SetID(aMsaaID);
if (a11y::nsWinUtils::IsWindowEmulationStarted()) {
doc->SetEmulatedWindowHandle(parentDoc->GetEmulatedWindowHandle());
}
a11y::WrapperFor(doc)->SetID(aMsaaID);
if (a11y::nsWinUtils::IsWindowEmulationStarted()) {
doc->SetEmulatedWindowHandle(parentDoc->GetEmulatedWindowHandle());
}
#endif
if (!added) {
return added;
}
return IPC_OK();
} else {
// null aParentDoc means this document is at the top level in the child
@ -2885,7 +2895,12 @@ TabParent::RecvRemotePaintIsReady()
mozilla::plugins::PPluginWidgetParent*
TabParent::AllocPPluginWidgetParent()
{
#ifdef XP_WIN
return new mozilla::plugins::PluginWidgetParent();
#else
MOZ_ASSERT_UNREACHABLE();
return nullptr;
#endif
}
bool

View file

@ -653,7 +653,6 @@ AudioCallbackDriver::Init()
} else {
if (cubeb_get_min_latency(cubebContext, output, &latency_frames) != CUBEB_OK) {
NS_WARNING("Could not get minimal latency from cubeb.");
return false;
}
}
@ -715,12 +714,16 @@ AudioCallbackDriver::Init()
if (!mFromFallback) {
CubebUtils::ReportCubebStreamInitFailure(firstStream);
}
// Fall back to a driver using a normal thread.
// Fall back to a driver using a normal thread. If needed,
// the graph will try to re-open an audio stream later.
MonitorAutoLock lock(GraphImpl()->GetMonitor());
SystemClockDriver* nextDriver = new SystemClockDriver(GraphImpl());
SetNextDriver(nextDriver);
nextDriver->MarkAsFallback();
nextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
// We're not using SwitchAtNextIteration here, because there
// won't be a next iteration if we don't restart things manually:
// the audio stream just signaled that it's in error state.
mGraphImpl->SetCurrentDriver(nextDriver);
nextDriver->Start();
return true;
@ -1049,6 +1052,21 @@ void
AudioCallbackDriver::StateCallback(cubeb_state aState)
{
LOG(LogLevel::Debug, ("AudioCallbackDriver State: %d", aState));
if (aState == CUBEB_STATE_ERROR) {
// Fall back to a driver using a normal thread. If needed,
// the graph will try to re-open an audio stream later.
MonitorAutoLock lock(GraphImpl()->GetMonitor());
SystemClockDriver* nextDriver = new SystemClockDriver(GraphImpl());
SetNextDriver(nextDriver);
RemoveCallback();
nextDriver->MarkAsFallback();
nextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
// We're not using SwitchAtNextIteration here, because there
// won't be a next iteration if we don't restart things manually:
// the audio stream just signaled that it's in error state.
mGraphImpl->SetCurrentDriver(nextDriver);
nextDriver->Start();
}
}
void

View file

@ -1813,13 +1813,14 @@ MediaDecoder::DumpDebugInfo()
return;
}
RefPtr<MediaDecoder> self = this;
GetStateMachine()->RequestDebugInfo()->Then(
AbstractThread::MainThread(), __func__,
[this, str] (const nsACString& aString) {
[this, self, str] (const nsACString& aString) {
DUMP_LOG("%s", str.get());
DUMP_LOG("%s", aString.Data());
},
[this, str] () {
[this, self, str] () {
DUMP_LOG("%s", str.get());
});
}

View file

@ -2805,6 +2805,11 @@ bool MediaDecoderStateMachine::IsPlaying() const
return mMediaSink->IsPlaying();
}
void MediaDecoderStateMachine::SetMediaNotSeekable()
{
mMediaSeekable = false;
}
nsresult MediaDecoderStateMachine::Init(MediaDecoder* aDecoder)
{
MOZ_ASSERT(NS_IsMainThread());
@ -2822,9 +2827,7 @@ nsresult MediaDecoderStateMachine::Init(MediaDecoder* aDecoder)
mMetadataManager.Connect(mReader->TimedMetadataEvent(), OwnerThread());
mOnMediaNotSeekable = mReader->OnMediaNotSeekable().Connect(
OwnerThread(), [this] () {
mMediaSeekable = false;
});
OwnerThread(), this, &MediaDecoderStateMachine::SetMediaNotSeekable);
mMediaSink = CreateMediaSink(mAudioCaptured);
@ -3112,9 +3115,10 @@ MediaDecoderStateMachine::RequestAudioData()
SAMPLE_LOG("Queueing audio task - queued=%" PRIuSIZE ", decoder-queued=%" PRIuSIZE,
AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
RefPtr<MediaDecoderStateMachine> self = this;
mReader->RequestAudioData()->Then(
OwnerThread(), __func__,
[this] (MediaData* aAudio) {
[this, self] (MediaData* aAudio) {
MOZ_ASSERT(aAudio);
mAudioDataRequest.Complete();
// audio->GetEndTime() is not always mono-increasing in chained ogg.
@ -3124,7 +3128,7 @@ MediaDecoderStateMachine::RequestAudioData()
aAudio->GetEndTime());
mStateObj->HandleAudioDecoded(aAudio);
},
[this] (const MediaResult& aError) {
[this, self] (const MediaResult& aError) {
SAMPLE_LOG("OnAudioNotDecoded aError=%" PRIu32, static_cast<uint32_t>(aError.Code()));
mAudioDataRequest.Complete();
switch (aError.Code()) {
@ -3158,9 +3162,10 @@ MediaDecoderStateMachine::RequestVideoData(bool aSkipToNextKeyframe,
aSkipToNextKeyframe, aCurrentTime.ToMicroseconds());
TimeStamp videoDecodeStartTime = TimeStamp::Now();
RefPtr<MediaDecoderStateMachine> self = this;
mReader->RequestVideoData(aSkipToNextKeyframe, aCurrentTime)->Then(
OwnerThread(), __func__,
[this, videoDecodeStartTime] (MediaData* aVideo) {
[this, self, videoDecodeStartTime] (MediaData* aVideo) {
MOZ_ASSERT(aVideo);
mVideoDataRequest.Complete();
// Handle abnormal or negative timestamps.
@ -3170,7 +3175,7 @@ MediaDecoderStateMachine::RequestVideoData(bool aSkipToNextKeyframe,
aVideo->GetEndTime());
mStateObj->HandleVideoDecoded(aVideo, videoDecodeStartTime);
},
[this] (const MediaResult& aError) {
[this, self] (const MediaResult& aError) {
SAMPLE_LOG("OnVideoNotDecoded aError=%" PRIu32 , static_cast<uint32_t>(aError.Code()));
mVideoDataRequest.Complete();
switch (aError.Code()) {
@ -3194,29 +3199,30 @@ MediaDecoderStateMachine::WaitForData(MediaData::Type aType)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(aType == MediaData::AUDIO_DATA || aType == MediaData::VIDEO_DATA);
RefPtr<MediaDecoderStateMachine> self = this;
if (aType == MediaData::AUDIO_DATA) {
mReader->WaitForData(MediaData::AUDIO_DATA)->Then(
OwnerThread(), __func__,
[this] (MediaData::Type aType) {
mAudioWaitRequest.Complete();
[self] (MediaData::Type aType) {
self->mAudioWaitRequest.Complete();
MOZ_ASSERT(aType == MediaData::AUDIO_DATA);
mStateObj->HandleAudioWaited(aType);
self->mStateObj->HandleAudioWaited(aType);
},
[this] (const WaitForDataRejectValue& aRejection) {
mAudioWaitRequest.Complete();
DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
[self] (const WaitForDataRejectValue& aRejection) {
self->mAudioWaitRequest.Complete();
self->DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
})->Track(mAudioWaitRequest);
} else {
mReader->WaitForData(MediaData::VIDEO_DATA)->Then(
OwnerThread(), __func__,
[this] (MediaData::Type aType) {
mVideoWaitRequest.Complete();
[self] (MediaData::Type aType) {
self->mVideoWaitRequest.Complete();
MOZ_ASSERT(aType == MediaData::VIDEO_DATA);
mStateObj->HandleVideoWaited(aType);
self->mStateObj->HandleVideoWaited(aType);
},
[this] (const WaitForDataRejectValue& aRejection) {
mVideoWaitRequest.Complete();
DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
[self] (const WaitForDataRejectValue& aRejection) {
self->mVideoWaitRequest.Complete();
self->DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
})->Track(mVideoWaitRequest);
}
}
@ -3577,9 +3583,10 @@ MediaDecoderStateMachine::ScheduleStateMachineIn(int64_t aMicroseconds)
// It is OK to capture 'this' without causing UAF because the callback
// always happens before shutdown.
mDelayedScheduler.Ensure(target, [this] () {
mDelayedScheduler.CompleteRequest();
RunStateMachine();
RefPtr<MediaDecoderStateMachine> self = this;
mDelayedScheduler.Ensure(target, [self] () {
self->mDelayedScheduler.CompleteRequest();
self->RunStateMachine();
}, [] () {
MOZ_DIAGNOSTIC_ASSERT(false);
});
@ -3796,8 +3803,9 @@ MediaDecoderStateMachine::RequestDebugInfo()
{
using PromiseType = MediaDecoder::DebugInfoPromise;
RefPtr<PromiseType::Private> p = new PromiseType::Private(__func__);
OwnerThread()->Dispatch(NS_NewRunnableFunction([this, p] () {
p->Resolve(GetDebugInfo(), __func__);
RefPtr<MediaDecoderStateMachine> self = this;
OwnerThread()->Dispatch(NS_NewRunnableFunction([self, p] () {
p->Resolve(self->GetDebugInfo(), __func__);
}), AbstractThread::AssertDispatchSuccess, AbstractThread::TailDispatch);
return p.forget();
}

View file

@ -297,6 +297,9 @@ private:
// be held.
bool IsPlaying() const;
// Sets mMediaSeekable to false.
void SetMediaNotSeekable();
// Resets all states related to decoding and aborts all pending requests
// to the decoders.
void ResetDecode(TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,

View file

@ -2295,23 +2295,23 @@ if (privileged) {
RefPtr<PledgeSourceSet> p = EnumerateDevicesImpl(windowID, videoType,
audioType, fake);
p->Then([this, onSuccess, onFailure, windowID, c, listener, askPermission,
RefPtr<MediaManager> self = this;
p->Then([self, onSuccess, onFailure, windowID, c, listener, askPermission,
prefs, isHTTPS, callID, principalInfo,
isChrome](SourceSet*& aDevices) mutable {
RefPtr<Refcountable<UniquePtr<SourceSet>>> devices(
new Refcountable<UniquePtr<SourceSet>>(aDevices)); // grab result
// Ensure that the captured 'this' pointer and our windowID are still good.
if (!MediaManager::Exists() ||
!nsGlobalWindow::GetInnerWindowWithId(windowID)) {
// Ensure that our windowID is still good.
if (!nsGlobalWindow::GetInnerWindowWithId(windowID)) {
return;
}
// Apply any constraints. This modifies the passed-in list.
RefPtr<PledgeChar> p2 = SelectSettings(c, isChrome, devices);
RefPtr<PledgeChar> p2 = self->SelectSettings(c, isChrome, devices);
p2->Then([this, onSuccess, onFailure, windowID, c,
p2->Then([self, onSuccess, onFailure, windowID, c,
listener, askPermission, prefs, isHTTPS, callID, principalInfo,
isChrome, devices](const char*& badConstraint) mutable {
@ -2359,13 +2359,13 @@ if (privileged) {
isChrome,
devices->release()));
// Store the task w/callbacks.
mActiveCallbacks.Put(callID, task.forget());
self->mActiveCallbacks.Put(callID, task.forget());
// Add a WindowID cross-reference so OnNavigation can tear things down
nsTArray<nsString>* array;
if (!mCallIds.Get(windowID, &array)) {
if (!self->mCallIds.Get(windowID, &array)) {
array = new nsTArray<nsString>();
mCallIds.Put(windowID, array);
self->mCallIds.Put(windowID, array);
}
array->AppendElement(callID);
@ -3002,7 +3002,9 @@ MediaManager::Shutdown()
// cleared until the lambda function clears it.
// note that this == sSingleton
RefPtr<MediaManager> that(sSingleton);
MOZ_ASSERT(this == sSingleton);
RefPtr<MediaManager> that = this;
// Release the backend (and call Shutdown()) from within the MediaManager thread
// Don't use MediaManager::PostTask() because we're sInShutdown=true here!
RefPtr<ShutdownTask> shutdown = new ShutdownTask(this,

View file

@ -30,7 +30,7 @@ if CONFIG['MOZ_WEBM_ENCODER']:
]
UNIFIED_SOURCES += ['VP8TrackEncoder.cpp',
]
LOCAL_INCLUDES += ['/media/libyuv/include']
LOCAL_INCLUDES += ['/media/libyuv/libyuv/include']
FINAL_LIBRARY = 'xul'

View file

@ -70,9 +70,10 @@ public:
void Forget()
{
mAbstractMainThread->Dispatch(NS_NewRunnableFunction([this] () {
RefPtr<DecodedStreamGraphListener> self = this;
mAbstractMainThread->Dispatch(NS_NewRunnableFunction([self] () {
MOZ_ASSERT(NS_IsMainThread());
mFinishPromise.ResolveIfExists(true, __func__);
self->mFinishPromise.ResolveIfExists(true, __func__);
}));
MutexAutoLock lock(mMutex);
mStream = nullptr;

View file

@ -128,8 +128,13 @@ OggDemuxer::~OggDemuxer()
// If we were able to initialize our decoders, report whether we encountered
// a chained stream or not.
bool isChained = mIsChained;
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([=]() -> void {
OGG_DEBUG("Reporting telemetry MEDIA_OGG_LOADED_IS_CHAINED=%d", isChained);
void* ptr = this;
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([ptr, isChained]() -> void {
// We can't use OGG_DEBUG here because it implicitly refers to `this`,
// which we can't capture in this runnable.
MOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug,
("OggDemuxer(%p)::%s: Reporting telemetry MEDIA_OGG_LOADED_IS_CHAINED=%d",
ptr, __func__, isChained));
Telemetry::Accumulate(Telemetry::HistogramID::MEDIA_OGG_LOADED_IS_CHAINED, isChained);
});
// Non-DocGroup version of AbstractThread::MainThread is fine for Telemetry.

View file

@ -285,12 +285,8 @@ CamerasChild::NumberOfCapabilities(CaptureEngine aCapEngine,
LOG(("NumberOfCapabilities for %s", deviceUniqueIdUTF8));
nsCString unique_id(deviceUniqueIdUTF8);
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine, unique_id]() -> nsresult {
if (this->SendNumberOfCapabilities(aCapEngine, unique_id)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString>
(this, &CamerasChild::SendNumberOfCapabilities, aCapEngine, unique_id);
LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
LOG(("Capture capability count: %d", dispatcher.ReturnValue()));
return dispatcher.ReturnValue();
@ -301,12 +297,8 @@ CamerasChild::NumberOfCaptureDevices(CaptureEngine aCapEngine)
{
LOG((__PRETTY_FUNCTION__));
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine]() -> nsresult {
if (this->SendNumberOfCaptureDevices(aCapEngine)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine>
(this, &CamerasChild::SendNumberOfCaptureDevices, aCapEngine);
LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
LOG(("Capture Devices: %d", dispatcher.ReturnValue()));
return dispatcher.ReturnValue();
@ -329,12 +321,8 @@ CamerasChild::EnsureInitialized(CaptureEngine aCapEngine)
{
LOG((__PRETTY_FUNCTION__));
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine]() -> nsresult {
if (this->SendEnsureInitialized(aCapEngine)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine>
(this, &CamerasChild::SendEnsureInitialized, aCapEngine);
LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
LOG(("Capture Devices: %d", dispatcher.ReturnValue()));
return dispatcher.ReturnValue();
@ -349,12 +337,8 @@ CamerasChild::GetCaptureCapability(CaptureEngine aCapEngine,
LOG(("GetCaptureCapability: %s %d", unique_idUTF8, capability_number));
nsCString unique_id(unique_idUTF8);
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine, unique_id, capability_number]() -> nsresult {
if (this->SendGetCaptureCapability(aCapEngine, unique_id, capability_number)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString, unsigned int>
(this, &CamerasChild::SendGetCaptureCapability, aCapEngine, unique_id, capability_number);
LockAndDispatch<> dispatcher(this, __func__, runnable);
if (dispatcher.Success()) {
capability = mReplyCapability;
@ -390,12 +374,8 @@ CamerasChild::GetCaptureDevice(CaptureEngine aCapEngine,
{
LOG((__PRETTY_FUNCTION__));
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine, list_number]() -> nsresult {
if (this->SendGetCaptureDevice(aCapEngine, list_number)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine, unsigned int>
(this, &CamerasChild::SendGetCaptureDevice, aCapEngine, list_number);
LockAndDispatch<> dispatcher(this, __func__, runnable);
if (dispatcher.Success()) {
base::strlcpy(device_nameUTF8, mReplyDeviceName.get(), device_nameUTF8Length);
@ -434,12 +414,8 @@ CamerasChild::AllocateCaptureDevice(CaptureEngine aCapEngine,
LOG((__PRETTY_FUNCTION__));
nsCString unique_id(unique_idUTF8);
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine, unique_id, aPrincipalInfo]() -> nsresult {
if (this->SendAllocateCaptureDevice(aCapEngine, unique_id, aPrincipalInfo)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString, const mozilla::ipc::PrincipalInfo&>
(this, &CamerasChild::SendAllocateCaptureDevice, aCapEngine, unique_id, aPrincipalInfo);
LockAndDispatch<> dispatcher(this, __func__, runnable);
if (dispatcher.Success()) {
LOG(("Capture Device allocated: %d", mReplyInteger));
@ -467,12 +443,8 @@ CamerasChild::ReleaseCaptureDevice(CaptureEngine aCapEngine,
{
LOG((__PRETTY_FUNCTION__));
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine, capture_id]() -> nsresult {
if (this->SendReleaseCaptureDevice(aCapEngine, capture_id)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine, int>
(this, &CamerasChild::SendReleaseCaptureDevice, aCapEngine, capture_id);
LockAndDispatch<> dispatcher(this, __func__, runnable);
return dispatcher.ReturnValue();
}
@ -518,12 +490,8 @@ CamerasChild::StartCapture(CaptureEngine aCapEngine,
webrtcCaps.codecType,
webrtcCaps.interlaced);
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine, capture_id, capCap]() -> nsresult {
if (this->SendStartCapture(aCapEngine, capture_id, capCap)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine, int, VideoCaptureCapability>
(this, &CamerasChild::SendStartCapture, aCapEngine, capture_id, capCap);
LockAndDispatch<> dispatcher(this, __func__, runnable);
return dispatcher.ReturnValue();
}
@ -533,12 +501,8 @@ CamerasChild::StopCapture(CaptureEngine aCapEngine, const int capture_id)
{
LOG((__PRETTY_FUNCTION__));
nsCOMPtr<nsIRunnable> runnable =
media::NewRunnableFrom([this, aCapEngine, capture_id]() -> nsresult {
if (this->SendStopCapture(aCapEngine, capture_id)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
});
mozilla::NewNonOwningRunnableMethod<CaptureEngine, int>
(this, &CamerasChild::SendStopCapture, aCapEngine, capture_id);
LockAndDispatch<> dispatcher(this, __func__, runnable);
if (dispatcher.Success()) {
RemoveCallback(aCapEngine, capture_id);
@ -599,13 +563,10 @@ CamerasChild::ShutdownParent()
if (CamerasSingleton::Thread()) {
LOG(("Dispatching actor deletion"));
// Delete the parent actor.
RefPtr<Runnable> deleteRunnable =
// CamerasChild (this) will remain alive and is only deleted by the
// IPC layer when SendAllDone returns.
media::NewRunnableFrom([this]() -> nsresult {
Unused << this->SendAllDone();
return NS_OK;
});
// CamerasChild (this) will remain alive and is only deleted by the
// IPC layer when SendAllDone returns.
nsCOMPtr<nsIRunnable> deleteRunnable =
mozilla::NewNonOwningRunnableMethod(this, &CamerasChild::SendAllDone);
CamerasSingleton::Thread()->Dispatch(deleteRunnable, NS_DISPATCH_NORMAL);
} else {
LOG(("ShutdownParent called without PBackground thread"));

View file

@ -316,10 +316,10 @@ MediaEngineRemoteVideoSource::SetLastCapability(
webrtc::CaptureCapability cap = aCapability;
RefPtr<MediaEngineRemoteVideoSource> that = this;
NS_DispatchToMainThread(media::NewRunnableFrom([this, that, cap]() mutable {
mSettings.mWidth.Value() = cap.width;
mSettings.mHeight.Value() = cap.height;
mSettings.mFrameRate.Value() = cap.maxFPS;
NS_DispatchToMainThread(media::NewRunnableFrom([that, cap]() mutable {
that->mSettings.mWidth.Value() = cap.width;
that->mSettings.mHeight.Value() = cap.height;
that->mSettings.mFrameRate.Value() = cap.maxFPS;
return NS_OK;
}));
}

View file

@ -373,10 +373,10 @@ MediaEngineWebRTCMicrophoneSource::SetLastPrefs(
RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
NS_DispatchToMainThread(media::NewRunnableFrom([this, that, aPrefs]() mutable {
mSettings.mEchoCancellation.Value() = aPrefs.mAecOn;
mSettings.mMozAutoGainControl.Value() = aPrefs.mAgcOn;
mSettings.mMozNoiseSuppression.Value() = aPrefs.mNoiseOn;
NS_DispatchToMainThread(media::NewRunnableFrom([that, aPrefs]() mutable {
that->mSettings.mEchoCancellation.Value() = aPrefs.mAecOn;
that->mSettings.mMozAutoGainControl.Value() = aPrefs.mAgcOn;
that->mSettings.mMozNoiseSuppression.Value() = aPrefs.mNoiseOn;
return NS_OK;
}));
}

View file

@ -42,7 +42,7 @@ if CONFIG['MOZ_WEBRTC']:
]
LOCAL_INCLUDES += [
'/dom/base',
'/media/libyuv/include',
'/media/libyuv/libyuv/include',
'/media/webrtc/signaling/src/common',
'/media/webrtc/signaling/src/common/browser_logging',
'/media/webrtc/trunk',

View file

@ -190,7 +190,7 @@ PluginPRLibrary::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error)
nsresult
PluginPRLibrary::NPP_New(NPMIMEType pluginType, NPP instance,
uint16_t mode, int16_t argc, char* argn[],
int16_t argc, char* argn[],
char* argv[], NPSavedData* saved,
NPError* error)
{
@ -198,7 +198,7 @@ PluginPRLibrary::NPP_New(NPMIMEType pluginType, NPP instance,
return NS_ERROR_FAILURE;
MAIN_THREAD_JNI_REF_GUARD;
*error = mNPP_New(pluginType, instance, mode, argc, argn, argv, saved);
*error = mNPP_New(pluginType, instance, NP_EMBED, argc, argn, argv, saved);
return NS_OK;
}

View file

@ -100,7 +100,7 @@ public:
#endif
virtual nsresult NPP_New(NPMIMEType aPluginType, NPP aInstance,
uint16_t aMode, int16_t aArgc, char* aArgn[],
int16_t aArgc, char* aArgn[],
char* aArgv[], NPSavedData* aSaved,
NPError* aError) override;

View file

@ -31,7 +31,6 @@ EXPORTS += [
'nsPluginInstanceOwner.h',
'nsPluginLogging.h',
'nsPluginNativeWindow.h',
'nsPluginNativeWindowGtk.h',
'nsPluginsCID.h',
'nsPluginsDir.h',
'nsPluginTags.h',
@ -70,17 +69,9 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
]
else:
UNIFIED_SOURCES += [
'nsPluginNativeWindow.cpp',
'nsPluginsDirUnix.cpp',
]
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
# This file cannot be built in unified mode because of name clashes in X11 headers.
SOURCES += [
'nsPluginNativeWindowGtk.cpp',
]
else:
UNIFIED_SOURCES += [
'nsPluginNativeWindow.cpp',
]
LOCAL_INCLUDES += [
'/dom/base',

View file

@ -341,15 +341,6 @@ nsNPAPIPluginInstance::GetTagType(nsPluginTagType *result)
return mOwner->GetTagType(result);
}
nsresult
nsNPAPIPluginInstance::GetMode(int32_t *result)
{
if (mOwner)
return mOwner->GetMode(result);
else
return NS_ERROR_FAILURE;
}
nsTArray<nsNPAPIPluginStreamListener*>*
nsNPAPIPluginInstance::StreamListeners()
{
@ -418,11 +409,9 @@ nsNPAPIPluginInstance::Start()
pos++;
}
int32_t mode;
const char* mimetype;
NPError error = NPERR_GENERIC_ERROR;
GetMode(&mode);
GetMIMEType(&mimetype);
CheckJavaC2PJSObjectQuirk(quirkParamLength, mCachedParamNames, mCachedParamValues);
@ -446,14 +435,14 @@ nsNPAPIPluginInstance::Start()
// before returning. If the plugin returns failure, we'll clear it out below.
mRunning = RUNNING;
nsresult newResult = library->NPP_New((char*)mimetype, &mNPP, (uint16_t)mode,
nsresult newResult = library->NPP_New((char*)mimetype, &mNPP,
quirkParamLength, mCachedParamNames,
mCachedParamValues, nullptr, &error);
mInPluginInitCall = oldVal;
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP New called: this=%p, npp=%p, mime=%s, mode=%d, argc=%d, return=%d\n",
this, &mNPP, mimetype, mode, quirkParamLength, error));
("NPP New called: this=%p, npp=%p, mime=%s, argc=%d, return=%d\n",
this, &mNPP, mimetype, quirkParamLength, error));
if (NS_FAILED(newResult) || error != NPERR_NO_ERROR) {
mRunning = DESTROYED;
@ -1589,49 +1578,6 @@ nsNPAPIPluginInstance::SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *c
}
}
class CarbonEventModelFailureEvent : public Runnable {
public:
nsCOMPtr<nsIContent> mContent;
explicit CarbonEventModelFailureEvent(nsIContent* aContent)
: mContent(aContent)
{}
~CarbonEventModelFailureEvent() {}
NS_IMETHOD Run();
};
NS_IMETHODIMP
CarbonEventModelFailureEvent::Run()
{
nsString type = NS_LITERAL_STRING("npapi-carbon-event-model-failure");
nsContentUtils::DispatchTrustedEvent(mContent->GetComposedDoc(), mContent,
type, true, true);
return NS_OK;
}
void
nsNPAPIPluginInstance::CarbonNPAPIFailure()
{
nsCOMPtr<nsIDOMElement> element;
GetDOMElement(getter_AddRefs(element));
if (!element) {
return;
}
nsCOMPtr<nsIContent> content(do_QueryInterface(element));
if (!content) {
return;
}
nsCOMPtr<nsIRunnable> e = new CarbonEventModelFailureEvent(content);
nsresult rv = NS_DispatchToCurrentThread(e);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch CarbonEventModelFailureEvent.");
}
}
static bool
GetJavaVersionFromMimetype(nsPluginTag* pluginTag, nsCString& version)
{

View file

@ -302,10 +302,6 @@ public:
NPError FinalizeAsyncSurface(NPAsyncSurface *surface);
void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed);
// Called when the instance fails to instantiate beceause the Carbon
// event model is not supported.
void CarbonNPAPIFailure();
// Returns the contents scale factor of the screen the plugin is drawn on.
double GetContentsScaleFactor();
@ -334,7 +330,6 @@ protected:
virtual ~nsNPAPIPluginInstance();
nsresult GetTagType(nsPluginTagType *result);
nsresult GetMode(int32_t *result);
// check if this is a Java applet and affected by bug 750480
void CheckJavaC2PJSObjectQuirk(uint16_t paramCount,

View file

@ -3344,8 +3344,6 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
{
NS_ENSURE_TRUE(mPluginWindow, NS_ERROR_NULL_POINTER);
nsresult rv = NS_ERROR_FAILURE;
// Can't call this twice!
if (mWidget) {
NS_WARNING("Trying to create a plugin widget twice!");
@ -3355,15 +3353,21 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
bool windowless = false;
mInstance->IsWindowless(&windowless);
if (!windowless) {
#ifndef XP_WIN
// Only Windows supports windowed mode!
MOZ_ASSERT_UNREACHABLE();
return NS_ERROR_FAILURE;
#else
// Try to get a parent widget, on some platforms widget creation will fail without
// a parent.
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIWidget> parentWidget;
nsIDocument *doc = nullptr;
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
if (content) {
doc = content->OwnerDoc();
parentWidget = nsContentUtils::WidgetForDocument(doc);
#ifndef XP_MACOSX
// If we're running in the content process, we need a remote widget created in chrome.
if (XRE_IsContentProcess()) {
if (nsCOMPtr<nsPIDOMWindowOuter> window = doc->GetWindow()) {
@ -3379,16 +3383,13 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
}
}
}
#endif // XP_MACOSX
}
#ifndef XP_MACOSX
// A failure here is terminal since we can't fall back on the non-e10s code
// path below.
if (!mWidget && XRE_IsContentProcess()) {
return NS_ERROR_UNEXPECTED;
}
#endif // XP_MACOSX
if (!mWidget) {
// native (single process)
@ -3410,6 +3411,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
mWidget->EnableDragDrop(true);
mWidget->Show(false);
mWidget->Enable(false);
#endif // XP_WIN
}
if (mPluginFrame) {

View file

@ -12,42 +12,54 @@
#include "nsDebug.h"
#include "nsPluginNativeWindow.h"
class nsPluginNativeWindowPLATFORM : public nsPluginNativeWindow {
public:
nsPluginNativeWindowPLATFORM();
virtual ~nsPluginNativeWindowPLATFORM();
class nsPluginNativeWindowImpl : public nsPluginNativeWindow
{
public:
nsPluginNativeWindowImpl();
virtual ~nsPluginNativeWindowImpl();
#ifdef MOZ_WIDGET_GTK
NPSetWindowCallbackStruct mWsInfo;
#endif
};
nsPluginNativeWindowPLATFORM::nsPluginNativeWindowPLATFORM() : nsPluginNativeWindow()
nsPluginNativeWindowImpl::nsPluginNativeWindowImpl() : nsPluginNativeWindow()
{
// initialize the struct fields
window = nullptr;
x = 0;
y = 0;
width = 0;
height = 0;
window = nullptr;
x = 0;
y = 0;
width = 0;
height = 0;
memset(&clipRect, 0, sizeof(clipRect));
#if defined(XP_UNIX) && !defined(XP_MACOSX)
type = NPWindowTypeWindow;
#ifdef MOZ_WIDGET_GTK
ws_info = &mWsInfo;
mWsInfo.type = 0;
mWsInfo.display = nullptr;
mWsInfo.visual = nullptr;
mWsInfo.colormap = 0;
mWsInfo.depth = 0;
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
ws_info = nullptr;
#endif
type = NPWindowTypeWindow;
}
nsPluginNativeWindowPLATFORM::~nsPluginNativeWindowPLATFORM()
nsPluginNativeWindowImpl::~nsPluginNativeWindowImpl()
{
}
nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
{
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
*aPluginNativeWindow = new nsPluginNativeWindowPLATFORM();
*aPluginNativeWindow = new nsPluginNativeWindowImpl();
return NS_OK;
}
nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
{
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
nsPluginNativeWindowPLATFORM *p = (nsPluginNativeWindowPLATFORM *)aPluginNativeWindow;
delete p;
delete static_cast<nsPluginNativeWindowImpl*>(aPluginNativeWindow);
return NS_OK;
}

View file

@ -1,356 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* 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 the Gtk2 implementation of plugin native window.
*/
#include "nsDebug.h"
#include "nsPluginNativeWindowGtk.h"
#include "nsNPAPIPlugin.h"
#include "npapi.h"
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#if (GTK_MAJOR_VERSION == 3)
#include <gtk/gtkx.h>
#else
#include "gtk2xtbin.h"
#endif
#include "mozilla/X11Util.h"
static void plug_added_cb(GtkWidget *widget, gpointer data);
static gboolean plug_removed_cb (GtkWidget *widget, gpointer data);
static void socket_unrealize_cb (GtkWidget *widget, gpointer data);
nsPluginNativeWindowGtk::nsPluginNativeWindowGtk() : nsPluginNativeWindow()
{
// initialize the struct fields
window = nullptr;
x = 0;
y = 0;
width = 0;
height = 0;
memset(&clipRect, 0, sizeof(clipRect));
ws_info = &mWsInfo;
type = NPWindowTypeWindow;
mSocketWidget = 0;
mWsInfo.type = 0;
mWsInfo.display = nullptr;
mWsInfo.visual = nullptr;
mWsInfo.colormap = 0;
mWsInfo.depth = 0;
}
nsPluginNativeWindowGtk::~nsPluginNativeWindowGtk()
{
if(mSocketWidget) {
gtk_widget_destroy(mSocketWidget);
}
}
nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
{
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
*aPluginNativeWindow = new nsPluginNativeWindowGtk();
return NS_OK;
}
nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
{
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
nsPluginNativeWindowGtk *p = (nsPluginNativeWindowGtk *)aPluginNativeWindow;
delete p;
return NS_OK;
}
nsresult nsPluginNativeWindowGtk::CallSetWindow(RefPtr<nsNPAPIPluginInstance> &aPluginInstance)
{
if (aPluginInstance) {
if (type == NPWindowTypeWindow &&
XRE_IsContentProcess()) {
// In this case, most of the initialization code here has already happened
// in the chrome process. The window we have in content is the XID of the
// socket widget we need to hand to plugins.
SetWindow((XID)window);
} else if (type == NPWindowTypeWindow) {
if (!mSocketWidget) {
nsresult rv;
// The documentation on the types for many variables in NP(N|P)_GetValue
// is vague. Often boolean values are NPBool (1 byte), but
// https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins
// treats NPPVpluginNeedsXEmbed as PRBool (int), and
// on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|.
// thus we can't use NPBool for needsXEmbed, or the three bytes above
// it on the stack would get clobbered. so protect with the larger bool.
int needsXEmbed = 0;
rv = aPluginInstance->GetValueFromPlugin(NPPVpluginNeedsXEmbed, &needsXEmbed);
// If the call returned an error code make sure we still use our default value.
if (NS_FAILED(rv)) {
needsXEmbed = 0;
}
#ifdef DEBUG
printf("nsPluginNativeWindowGtk: NPPVpluginNeedsXEmbed=%d\n", needsXEmbed);
#endif
bool isOOPPlugin = aPluginInstance->GetPlugin()->GetLibrary()->IsOOP();
if (needsXEmbed || isOOPPlugin) {
bool enableXtFocus = !needsXEmbed;
rv = CreateXEmbedWindow(enableXtFocus);
}
else {
#if (MOZ_WIDGET_GTK == 2)
rv = CreateXtWindow();
#else
return NS_ERROR_FAILURE;
#endif
}
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
}
if (!mSocketWidget) {
return NS_ERROR_FAILURE;
}
// Make sure to resize and re-place the window if required.
SetAllocation();
// Need to reset "window" each time as nsPluginFrame::DidReflow sets it
// to the ancestor window.
#if (MOZ_WIDGET_GTK == 2)
if (GTK_IS_XTBIN(mSocketWidget)) {
// Point the NPWindow structures window to the actual X window
SetWindow(GTK_XTBIN(mSocketWidget)->xtwindow);
}
else { // XEmbed or OOP&Xt
SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget)));
}
#else
// Gtk3 supports only OOP by GtkSocket
SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget)));
#endif
#ifdef DEBUG
printf("nsPluginNativeWindowGtk: call SetWindow with xid=%p\n", (void *)window);
#endif
} // NPWindowTypeWindow
aPluginInstance->SetWindow(this);
} else if (mPluginInstance) {
mPluginInstance->SetWindow(nullptr);
}
SetPluginInstance(aPluginInstance);
return NS_OK;
}
nsresult nsPluginNativeWindowGtk::CreateXEmbedWindow(bool aEnableXtFocus) {
NS_ASSERTION(!mSocketWidget,"Already created a socket widget!");
GdkDisplay *display = gdk_display_get_default();
GdkWindow *parent_win = gdk_x11_window_lookup_for_display(display, GetWindow());
mSocketWidget = gtk_socket_new();
//attach the socket to the container widget
gtk_widget_set_parent_window(mSocketWidget, parent_win);
// enable/disable focus event handlers,
// see plugin_window_filter_func() for details
g_object_set_data(G_OBJECT(mSocketWidget), "enable-xt-focus", (void *)aEnableXtFocus);
g_signal_connect(mSocketWidget, "plug_added",
G_CALLBACK(plug_added_cb), nullptr);
// Make sure to handle the plug_removed signal. If we don't the
// socket will automatically be destroyed when the plug is
// removed, which means we're destroying it more than once.
// SYNTAX ERROR.
g_signal_connect(mSocketWidget, "plug_removed",
G_CALLBACK(plug_removed_cb), nullptr);
g_signal_connect(mSocketWidget, "unrealize",
G_CALLBACK(socket_unrealize_cb), nullptr);
g_signal_connect(mSocketWidget, "destroy",
G_CALLBACK(gtk_widget_destroyed), &mSocketWidget);
gpointer user_data = nullptr;
gdk_window_get_user_data(parent_win, &user_data);
GtkContainer *container = GTK_CONTAINER(user_data);
gtk_container_add(container, mSocketWidget);
gtk_widget_realize(mSocketWidget);
// The GtkSocket has a visible window, but the plugin's XEmbed plug will
// cover this window. Normally GtkSockets let the X server paint their
// background and this would happen immediately (before the plug is
// created). Setting the background to None prevents the server from
// painting this window, avoiding flicker.
// TODO GTK3
#if (MOZ_WIDGET_GTK == 2)
gdk_window_set_back_pixmap(gtk_widget_get_window(mSocketWidget), nullptr, FALSE);
#endif
// Resize before we show
SetAllocation();
gtk_widget_show(mSocketWidget);
gdk_flush();
SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget)));
// Fill out the ws_info structure.
// (The windowless case is done in nsPluginFrame.cpp.)
GdkWindow *gdkWindow = gdk_x11_window_lookup_for_display(display, GetWindow());
if(!gdkWindow)
return NS_ERROR_FAILURE;
mWsInfo.display = GDK_WINDOW_XDISPLAY(gdkWindow);
#if (MOZ_WIDGET_GTK == 2)
mWsInfo.colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(gdkWindow));
GdkVisual* gdkVisual = gdk_drawable_get_visual(gdkWindow);
mWsInfo.depth = gdkVisual->depth;
#else
mWsInfo.colormap = X11None;
GdkVisual* gdkVisual = gdk_window_get_visual(gdkWindow);
mWsInfo.depth = gdk_visual_get_depth(gdkVisual);
#endif
mWsInfo.visual = GDK_VISUAL_XVISUAL(gdkVisual);
return NS_OK;
}
void nsPluginNativeWindowGtk::SetAllocation() {
if (!mSocketWidget)
return;
GtkAllocation new_allocation;
new_allocation.x = 0;
new_allocation.y = 0;
new_allocation.width = width;
new_allocation.height = height;
gtk_widget_size_allocate(mSocketWidget, &new_allocation);
}
#if (MOZ_WIDGET_GTK == 2)
nsresult nsPluginNativeWindowGtk::CreateXtWindow() {
NS_ASSERTION(!mSocketWidget,"Already created a socket widget!");
#ifdef DEBUG
printf("About to create new xtbin of %i X %i from %p...\n",
width, height, (void*)window);
#endif
GdkDisplay *display = gdk_display_get_default();
GdkWindow *gdkWindow = gdk_x11_window_lookup_for_display(display, GetWindow());
mSocketWidget = gtk_xtbin_new(gdkWindow, 0);
// Check to see if creating the xtbin failed for some reason.
// if it did, we can't go any further.
if (!mSocketWidget)
return NS_ERROR_FAILURE;
g_signal_connect(mSocketWidget, "destroy",
G_CALLBACK(gtk_widget_destroyed), &mSocketWidget);
gtk_widget_set_size_request(mSocketWidget, width, height);
#ifdef DEBUG
printf("About to show xtbin(%p)...\n", (void*)mSocketWidget); fflush(nullptr);
#endif
gtk_widget_show(mSocketWidget);
#ifdef DEBUG
printf("completed gtk_widget_show(%p)\n", (void*)mSocketWidget); fflush(nullptr);
#endif
// Fill out the ws_info structure.
GtkXtBin* xtbin = GTK_XTBIN(mSocketWidget);
// The xtbin has its own Display structure.
mWsInfo.display = xtbin->xtdisplay;
mWsInfo.colormap = xtbin->xtclient.xtcolormap;
mWsInfo.visual = xtbin->xtclient.xtvisual;
mWsInfo.depth = xtbin->xtclient.xtdepth;
// Leave mWsInfo.type = 0 - Who knows what this is meant to be?
XFlush(mWsInfo.display);
return NS_OK;
}
#endif
static void
plug_window_finalize_cb(gpointer socket, GObject* plug_window)
{
g_object_unref(socket);
}
static void
plug_added_cb(GtkWidget *socket, gpointer data)
{
// The plug window has been embedded, and gtk_socket_add_window() has added
// a filter to the socket's plug_window, passing the socket as data for the
// filter, so the socket must live as long as events may be received on the
// plug window.
//
// https://git.gnome.org/browse/gtk+/tree/gtk/gtksocket.c?h=3.18.7#n1124
g_object_ref(socket);
// When the socket is unrealized, perhaps during gtk_widget_destroy() from
// ~nsPluginNativeWindowGtk, the plug is removed. The plug in the child
// process then destroys its widget and window. When the browser process
// receives the DestroyNotify event for the plug window, GDK releases its
// reference to plugWindow. This is typically the last reference and so the
// weak ref callback triggers release of the socket.
GdkWindow* plugWindow = gtk_socket_get_plug_window(GTK_SOCKET(socket));
g_object_weak_ref(G_OBJECT(plugWindow), plug_window_finalize_cb, socket);
}
/* static */
gboolean
plug_removed_cb (GtkWidget *widget, gpointer data)
{
// Gee, thanks for the info!
return TRUE;
}
static void
socket_unrealize_cb(GtkWidget *widget, gpointer data)
{
// Unmap and reparent any child windows that GDK does not yet know about.
// (See bug 540114 comment 10.)
GdkWindow* socket_window = gtk_widget_get_window(widget);
GdkDisplay* gdkDisplay = gdk_display_get_default();
Display* display = GDK_DISPLAY_XDISPLAY(gdkDisplay);
// Ignore X errors that may happen if windows get destroyed (possibly
// requested by the plugin) between XQueryTree and when we operate on them.
gdk_error_trap_push();
Window root, parent;
Window* children;
unsigned int nchildren;
if (!XQueryTree(display, gdk_x11_window_get_xid(socket_window),
&root, &parent, &children, &nchildren))
return;
for (unsigned int i = 0; i < nchildren; ++i) {
Window child = children[i];
if (!gdk_x11_window_lookup_for_display(gdkDisplay, child)) {
// This window is not known to GDK.
XUnmapWindow(display, child);
XReparentWindow(display, child, DefaultRootWindow(display), 0, 0);
}
}
if (children) XFree(children);
mozilla::FinishX(display);
#if (MOZ_WIDGET_GTK == 3)
gdk_error_trap_pop_ignored();
#else
gdk_error_trap_pop();
#endif
}

View file

@ -1,51 +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/. */
#ifndef _nsPluginNativeWindowGdk_h_
#define _nsPluginNativeWindowGdk_h_
#include "nsPluginNativeWindow.h"
#include "npapi.h"
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#if (GTK_MAJOR_VERSION == 3)
#include <gtk/gtkx.h>
#else
#include "gtk2xtbin.h"
#endif
#include "mozilla/X11Util.h"
class nsPluginNativeWindowGtk : public nsPluginNativeWindow {
public:
nsPluginNativeWindowGtk();
virtual ~nsPluginNativeWindowGtk();
virtual nsresult CallSetWindow(RefPtr<nsNPAPIPluginInstance> &aPluginInstance);
nsresult CreateXEmbedWindow(bool aEnableXtFocus);
void SetAllocation();
XID GetWindow() const
{
return static_cast<XID>(reinterpret_cast<uintptr_t>(window));
}
private:
void SetWindow(XID aWindow)
{
window = reinterpret_cast<void*>(static_cast<uintptr_t>(aWindow));
}
NPSetWindowCallbackStruct mWsInfo;
/**
* Either a GtkSocket or a special GtkXtBin widget (derived from GtkSocket)
* that encapsulates the Xt toolkit within a Gtk Application.
*/
GtkWidget* mSocketWidget;
#if (MOZ_WIDGET_GTK == 2)
nsresult CreateXtWindow();
#endif
};
#endif

View file

@ -87,10 +87,6 @@ child:
intr NPP_GetValue_NPPVpluginWantsAllNetworkStreams()
returns (bool value, NPError result);
// this message is not used on non-X platforms
intr NPP_GetValue_NPPVpluginNeedsXEmbed()
returns (bool value, NPError result);
intr NPP_GetValue_NPPVpluginScriptableNPObject()
returns (nullable PPluginScriptableObject value, NPError result);
@ -262,11 +258,6 @@ parent:
async RedrawPlugin();
// Send notification that a plugin tried to negotiate Carbon NPAPI so that
// users can be notified that restarting the browser in i386 mode may allow
// them to use the plugin.
sync NegotiatedCarbon();
// Notifies the parent of its NPP_New result code.
async AsyncNPP_NewResult(NPError aResult);

View file

@ -63,7 +63,6 @@ child:
async AsyncNP_Initialize(PluginSettings settings);
async PPluginInstance(nsCString aMimeType,
uint16_t aMode,
nsCString[] aNames,
nsCString[] aValues);

View file

@ -101,7 +101,6 @@ bool RecursionGuard::sHasEntered = false;
PluginAsyncSurrogate::PluginAsyncSurrogate(PluginModuleParent* aParent)
: mParent(aParent)
, mMode(0)
, mWindow(nullptr)
, mAcceptCalls(false)
, mInstantiated(false)
@ -118,7 +117,7 @@ PluginAsyncSurrogate::~PluginAsyncSurrogate()
}
bool
PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode,
PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance,
int16_t aArgc, char* aArgn[], char* aArgv[])
{
mMimeType = aPluginType;
@ -126,7 +125,6 @@ PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode
static_cast<nsNPAPIPluginInstance*>(aInstance->ndata);
MOZ_ASSERT(instance);
mInstance = instance;
mMode = aMode;
for (int i = 0; i < aArgc; ++i) {
mNames.AppendElement(NullableString(aArgn[i]));
mValues.AppendElement(NullableString(aArgv[i]));
@ -136,11 +134,11 @@ PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode
/* static */ bool
PluginAsyncSurrogate::Create(PluginModuleParent* aParent, NPMIMEType aPluginType,
NPP aInstance, uint16_t aMode, int16_t aArgc,
NPP aInstance, int16_t aArgc,
char* aArgn[], char* aArgv[])
{
RefPtr<PluginAsyncSurrogate> surrogate(new PluginAsyncSurrogate(aParent));
if (!surrogate->Init(aPluginType, aInstance, aMode, aArgc, aArgn, aArgv)) {
if (!surrogate->Init(aPluginType, aInstance, aArgc, aArgn, aArgv)) {
return false;
}
PluginAsyncSurrogate* rawSurrogate = nullptr;
@ -169,7 +167,7 @@ PluginAsyncSurrogate::NPP_New(NPError* aError)
}
nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), GetNPP(),
mMode, mNames, mValues, nullptr,
mNames, mValues, nullptr,
aError);
if (NS_FAILED(rv)) {
return rv;

View file

@ -29,7 +29,7 @@ class PluginAsyncSurrogate : public PluginDataResolver
public:
NS_INLINE_DECL_REFCOUNTING(PluginAsyncSurrogate)
bool Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode,
bool Init(NPMIMEType aPluginType, NPP aInstance,
int16_t aArgc, char* aArgn[], char* aArgv[]);
nsresult NPP_New(NPError* aError);
NPError NPP_Destroy(NPSavedData** aSave);
@ -45,7 +45,7 @@ public:
NPError NPP_DestroyStream(NPStream* aStream, NPReason aReason);
void OnInstanceCreated(PluginInstanceParent* aInstance);
static bool Create(PluginModuleParent* aParent, NPMIMEType aPluginType,
NPP aInstance, uint16_t aMode, int16_t aArgc,
NPP aInstance, int16_t aArgc,
char* aArgn[], char* aArgv[]);
static const NPClass* GetClass() { return &sNPClass; }
static void NP_GetEntryPoints(NPPluginFuncs* aFuncs);
@ -141,7 +141,6 @@ private:
// These values are used to construct the plugin instance
nsCString mMimeType;
mozilla::WeakPtr<nsNPAPIPluginInstance> mInstance;
uint16_t mMode;
InfallibleTArray<nsCString> mNames;
InfallibleTArray<nsCString> mValues;
// This is safe to store as a pointer because the spec says it will remain

Some files were not shown because too many files have changed in this diff Show more