Bug 1028200 - Plugins that are fullscreen'd should exit fullscreen mode on crash. r=mconley

MozReview-Commit-ID: HiDyiPCPiV1
This commit is contained in:
s7hoang 2016-12-13 13:44:39 -05:00
Родитель 5297375b79
Коммит 0333e3b828
15 изменённых файлов: 855 добавлений и 0 удалений

Просмотреть файл

@ -972,6 +972,47 @@ PluginContent.prototype = {
this.global.sendAsyncMessage("PluginContent:HideNotificationBar", { name: name });
},
/**
* Determines whether or not the crashed plugin is contained within current
* full screen DOM element.
* @param fullScreenElement (DOM element)
* The DOM element that is currently full screen, or null.
* @param domElement
* The DOM element which contains the crashed plugin, or the crashed plugin
* itself.
* @returns bool
* True if the plugin is a descendant of the full screen DOM element, false otherwise.
**/
isWithinFullScreenElement: function(fullScreenElement, domElement) {
/**
* Traverses down iframes until it find a non-iframe full screen DOM element.
* @param fullScreenIframe
* Target iframe to begin searching from.
* @returns DOM element
* The full screen DOM element contained within the iframe (could be inner iframe), or the original iframe if no inner DOM element is found.
**/
let getTrueFullScreenElement = fullScreenIframe => {
if (typeof fullScreenIframe.contentDocument !== 'undefined' && fullScreenIframe.contentDocument.mozFullScreenElement) {
return getTrueFullScreenElement(fullScreenIframe.contentDocument.mozFullScreenElement);
}
return fullScreenIframe;
}
if (fullScreenElement.tagName === "IFRAME") {
fullScreenElement = getTrueFullScreenElement(fullScreenElement);
}
if (fullScreenElement.contains(domElement)) {
return true;
}
let parentIframe = domElement.ownerGlobal.frameElement;
if (parentIframe) {
return this.isWithinFullScreenElement(fullScreenElement, parentIframe);
}
return false;
},
/**
* The PluginCrashed event handler. Note that the PluginCrashed event is
* fired for both NPAPI and Gecko Media plugins. In the latter case, the
@ -981,6 +1022,13 @@ PluginContent.prototype = {
if (!(aEvent instanceof this.content.PluginCrashedEvent))
return;
let fullScreenElement = this.content.document.mozFullScreenElement;
if (fullScreenElement) {
if (this.isWithinFullScreenElement(fullScreenElement, target)) {
this.content.document.mozCancelFullScreen();
}
}
if (aEvent.gmpPlugin) {
this.GMPCrashed(aEvent);
return;

Просмотреть файл

@ -0,0 +1,9 @@
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>1028200 subpageA</h1>
<iframe id="iframe2" src="1028200-subpageA1.html" width="400" height="400"></iframe>
</body>
</html>

Просмотреть файл

@ -0,0 +1,9 @@
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>1028200 subpageA1</h1>
<embed id="plugin1" type="application/x-test" />
</body>
</html>

Просмотреть файл

@ -0,0 +1,9 @@
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>1028200 subpageB</h1>
<iframe id="iframe2" src="1028200-subpageB1.html" width="400" height="400"></iframe>
</body>
</html>

Просмотреть файл

@ -0,0 +1,11 @@
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>1028200 subpageB1</h1>
<div id="div1">
<embed id="plugin1" type="application/x-test" />
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,9 @@
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>1028200 subpageC</h1>
<div id="div1"> </div>
</body>
</html>

Просмотреть файл

@ -3,6 +3,11 @@ subsuite = clipboard
support-files =
307-xo-redirect.sjs
crashing_subpage.html
1028200-subpageA.html
1028200-subpageA1.html
1028200-subpageB.html
1028200-subpageB1.html
1028200-subpageC.html
file_authident.js
file_bug738396.html
file_bug771202.html
@ -25,6 +30,13 @@ support-files =
plugin-utils.js
!/toolkit/components/passwordmgr/test/authenticate.sjs
[test_bug1028200-1.html]
[test_bug1028200-2.html]
[test_bug1028200-3.html]
[test_bug1028200-4.html]
[test_bug1028200-5.html]
[test_bug1028200-6.html]
[test_bug1028200-7.html]
[test_bug406541.html]
[test_bug532208.html]
[test_bug539565-1.html]

Просмотреть файл

@ -93,3 +93,32 @@ function crashAndGetCrashServiceRecord(crashMethodName, callback) {
SimpleTest.finish();
});
}
/**
* Returns a promise which resolves on `mozFullScreenChange`.
*/
function promiseFullScreenChange(){
return new Promise(resolve => {
document.addEventListener("fullscreenchange", function onFullScreen(e) {
document.removeEventListener("fullscreenchange", onFullScreen);
resolve();
});
});
}
/**
* Crashes target plugin. Returns a promise; resolves on successful crash,
* rejects otherwise.
* @param plugin Target plugin to attempt to crash.
*/
function crashPlugin(plugin) {
return new Promise( (resolve, reject) => {
try {
plugin.crash();
reject();
}
catch (e) {
resolve();
}
});
}

Просмотреть файл

@ -0,0 +1,104 @@
<head>
<meta charset="utf-8">
<title>Plugin Crash, FullScreenElement Cancelled, div[F] -> iframe -> iframe -> plugin</title>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
</head>
<body onLoad="load()">
<script class="testbody" type="application/javascript">
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
SimpleTest.expectChildProcessCrash();
SimpleTest.requestFlakyTimeout("This is needed in the event the " +
"fullscreen element fails to cancel fullscreen. The fullscreen " +
"element is expected to exit fullscreen but takes some time to " +
"register as having exited when using `mozCancelFullScreen`. So we " +
"can't just check that `mozFullScreenElement` is true or false after " +
"having called `mozCancelFullScreen` without the timeout because it " +
"will return the value prior to actually cancelling. A timeout is " +
"preferred here as opposed to polling methods similar to " +
"`SimpleTest.waitForCondition` in `SimpleTest.js` for reasons of" +
"idiomaticity."
);
/**
* FullScreen element is expected to remain alive after the test ends; this
* stops it.
*/
SimpleTest.registerCleanupFunction(() => {
if (this.document.mozFullScreenElement) {
let fullScreenChange = promiseFullScreenChange();
this.document.mozCancelFullScreen();
return fullScreenChange;
}
});
/**
* Start with a fullscreen element.
* Then crash the plugin - which is expected to be a child of the full
* screen element - and therefore exit out of the fullscreen element.
*/
let load = function testCrashChildPlugin_expectFullScreenElementToBeCancelled() {
add_task(function* () {
/* Needed to be able to programatically (without user interaction) enter
* fullscreen (has been deemed a security issue otherwise and therefore
* disabled by default)
*/
yield SpecialPowers.pushPrefEnv(
{ "set": [ ["full-screen-api.allow-trusted-requests-only", false] ] });
});
add_task(function* () {
let fullScreenElement = document.getElementById('div1');
let plugin = document.getElementById('iframe1')
.contentDocument.getElementById('iframe2')
.contentDocument.getElementById('plugin1');
let fullScreenChange = promiseFullScreenChange();
fullScreenElement.mozRequestFullScreen();
yield fullScreenChange;
ok(true, "Element is fullscreen");
yield crashPlugin(plugin)
.then(() => {
ok(true, "Plugin was crashed");
})
.catch(() => {
ok(false, "Plugin was crashed");
});
});
add_task(function* () {
/**
* We expect the fullscreen mode to change in this test. We'll wait
* 5 seconds for any kind of fullscreen change to occur, and fail if it
* doesn't.
*/
yield new Promise((resolve, reject) => {
let timeoutId;
let onFullScreenChange = () => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
clearTimeout(timeoutId);
resolve();
}
document.addEventListener("fullscreenchange", onFullScreenChange);
timeoutId = setTimeout(() => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
reject();
}, 5000);
})
.then(() => {
ok(true, "Element is no longer fullscreen");
})
.catch(() => {
ok(false, "Element is no longer fullscreen");
});
});
}
</script>
<div id="div1">
<iframe id="iframe1" src="1028200-subpageA.html" height="600" width="600"></iframe>
</div>
</body>

Просмотреть файл

@ -0,0 +1,102 @@
<head>
<meta charset="utf-8">
<title>Plugin Crash, FullScreenElement Remains, div[F];plugin</title>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
</head>
<body onLoad="load()">
<script class="testbody" type="application/javascript">
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
SimpleTest.expectChildProcessCrash();
SimpleTest.requestFlakyTimeout("This is needed in the event the " +
"fullscreen element fails to cancel fullscreen. The fullscreen " +
"element is expected to exit fullscreen but takes some time to " +
"register as having exited when using `mozCancelFullScreen`. So we " +
"can't just check that `mozFullScreenElement` is true or false after " +
"having called `mozCancelFullScreen` without the timeout because it " +
"will return the value prior to actually cancelling. A timeout is " +
"preferred here as opposed to polling methods similar to " +
"`SimpleTest.waitForCondition` in `SimpleTest.js` for reasons of" +
"idiomaticity."
);
/**
* FullScreen element is expected to remain alive after the test ends; this
* stops it.
*/
SimpleTest.registerCleanupFunction(() => {
if (this.document.mozFullScreenElement) {
let fullScreenChange = promiseFullScreenChange();
this.document.mozCancelFullScreen();
return fullScreenChange;
}
});
/**
* Start with a fullscreen element.
* Then crash the plugin - which is expected to not be a child of the full
* screen element - and therefore remain in the fullscreen element.
*/
let load = function testCrashChildPlugin_expectFullScreenElementToRemain() {
add_task(function* () {
/* Needed to be able to programatically (without user interaction) enter
* fullscreen (has been deemed a security issue otherwise and therefore
* disabled by default)
*/
yield SpecialPowers.pushPrefEnv(
{ "set": [ ["full-screen-api.allow-trusted-requests-only", false] ] });
});
add_task(function* () {
let fullScreenElement = document.getElementById('div1');
let plugin = document.getElementById('plugin1');
let fullScreenChange = promiseFullScreenChange();
fullScreenElement.mozRequestFullScreen();
yield fullScreenChange;
ok(true, "Element is fullscreen");
yield crashPlugin(plugin)
.then(() => {
ok(true, "Plugin was crashed");
})
.catch(() => {
ok(false, "Plugin was crashed");
});
});
add_task(function* () {
/**
* We expect the fullscreen mode to _not_ change in this test. We'll wait
* 5 seconds for any kind of fullscreen change to occur, and fail if it
* does. Otherwise, we'll assume fullscreen didn't change and finish the
* test.
*/
yield new Promise((resolve, reject) => {
let timeoutId;
let onFullScreenChange = () => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
clearTimeout(timeoutId);
reject();
}
document.addEventListener("fullscreenchange", onFullScreenChange);
timeoutId = setTimeout(() => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
resolve();
}, 5000);
})
.then(() => {
ok(true, "Element is still fullscreen");
})
.catch(() => {
ok(false, "Element is still fullscreen");
});
});
}
</script>
<div id="div1"></div>
<embed id="plugin1" type="application/x-test" />
</body>

Просмотреть файл

@ -0,0 +1,102 @@
<head>
<meta charset="utf-8">
<title>Plugin Crash, FullScreenElement Cancelled, iframe[F] -> iframe -> div -> plugin</title>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
</head>
<body onLoad="load()">
<script class="testbody" type="application/javascript">
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
SimpleTest.expectChildProcessCrash();
SimpleTest.requestFlakyTimeout("This is needed in the event the " +
"fullscreen element fails to cancel fullscreen. The fullscreen " +
"element is expected to exit fullscreen but takes some time to " +
"register as having exited when using `mozCancelFullScreen`. So we " +
"can't just check that `mozFullScreenElement` is true or false after " +
"having called `mozCancelFullScreen` without the timeout because it " +
"will return the value prior to actually cancelling. A timeout is " +
"preferred here as opposed to polling methods similar to " +
"`SimpleTest.waitForCondition` in `SimpleTest.js` for reasons of" +
"idiomaticity."
);
/**
* FullScreen element is expected to remain alive after the test ends; this
* stops it.
*/
SimpleTest.registerCleanupFunction(() => {
if (this.document.mozFullScreenElement) {
let fullScreenChange = promiseFullScreenChange();
this.document.mozCancelFullScreen();
return fullScreenChange;
}
});
/**
* Start with a fullscreen element.
* Then crash the plugin - which is expected to be a child of the full
* screen element - and therefore exit out of the fullscreen element.
*/
let load = function testCrashChildPlugin_expectFullScreenElementToBeCancelled() {
add_task(function* () {
/* Needed to be able to programatically (without user interaction) enter
* fullscreen (has been deemed a security issue otherwise and therefore
* disabled by default)
*/
yield SpecialPowers.pushPrefEnv(
{ "set": [ ["full-screen-api.allow-trusted-requests-only", false] ] });
});
add_task(function* () {
let fullScreenElement = document.getElementById('iframe1');
let plugin = document.getElementById('iframe1')
.contentDocument.getElementById('iframe2')
.contentDocument.getElementById('plugin1');
let fullScreenChange = promiseFullScreenChange();
fullScreenElement.mozRequestFullScreen();
yield fullScreenChange;
ok(true, "Element is fullscreen");
yield crashPlugin(plugin)
.then(() => {
ok(true, "Plugin was crashed");
})
.catch(() => {
ok(false, "Plugin was crashed");
});
});
add_task(function* () {
/**
* We expect the fullscreen mode to change in this test. We'll wait
* 5 seconds for any kind of fullscreen change to occur, and fail if it
* doesn't.
*/
yield new Promise((resolve, reject) => {
let timeoutId;
let onFullScreenChange = () => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
clearTimeout(timeoutId);
resolve();
}
document.addEventListener("fullscreenchange", onFullScreenChange);
timeoutId = setTimeout(() => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
reject();
}, 5000);
})
.then(() => {
ok(true, "Element is no longer fullscreen");
})
.catch(() => {
ok(false, "Element is no longer fullscreen");
});
});
}
</script>
<iframe id="iframe1" src="1028200-subpageB.html" height="600" width="600"></iframe>
</body>

Просмотреть файл

@ -0,0 +1,102 @@
<head>
<meta charset="utf-8">
<title>Plugin Crash, FullScreenElement Cancelled, iframe[F] -> iframe -> div -> plugin</title>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
</head>
<body onLoad="load()">
<script class="testbody" type="application/javascript">
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
SimpleTest.expectChildProcessCrash();
SimpleTest.requestFlakyTimeout("This is needed in the event the " +
"fullscreen element fails to cancel fullscreen. The fullscreen " +
"element is expected to exit fullscreen but takes some time to " +
"register as having exited when using `mozCancelFullScreen`. So we " +
"can't just check that `mozFullScreenElement` is true or false after " +
"having called `mozCancelFullScreen` without the timeout because it " +
"will return the value prior to actually cancelling. A timeout is " +
"preferred here as opposed to polling methods similar to " +
"`SimpleTest.waitForCondition` in `SimpleTest.js` for reasons of" +
"idiomaticity."
);
/**
* FullScreen element is expected to remain alive after the test ends; this
* stops it.
*/
SimpleTest.registerCleanupFunction(() => {
if (this.document.mozFullScreenElement) {
let fullScreenChange = promiseFullScreenChange();
this.document.mozCancelFullScreen();
return fullScreenChange;
}
});
/**
* Start with a fullscreen element.
* Then crash the plugin - which is expected to be a child of the full
* screen element - and therefore exit out of the fullscreen element.
*/
let load = function testCrashChildPlugin_expectFullScreenElementToBeCancelled() {
add_task(function* () {
/* Needed to be able to programatically (without user interaction) enter
* fullscreen (has been deemed a security issue otherwise and therefore
* disabled by default)
*/
yield SpecialPowers.pushPrefEnv(
{ "set": [ ["full-screen-api.allow-trusted-requests-only", false] ] });
});
add_task(function* () {
let fullScreenElement = document.getElementById('iframe1');
let plugin = document.getElementById('iframe1')
.contentDocument.getElementById('iframe2')
.contentDocument.getElementById('plugin1');
let fullScreenChange = promiseFullScreenChange();
fullScreenElement.mozRequestFullScreen();
yield fullScreenChange;
ok(true, "Element is fullscreen");
yield crashPlugin(plugin)
.then(() => {
ok(true, "Plugin was crashed");
})
.catch(() => {
ok(false, "Plugin was crashed");
});
});
add_task(function* () {
/**
* We expect the fullscreen mode to change in this test. We'll wait
* 5 seconds for any kind of fullscreen change to occur, and fail if it
* doesn't.
*/
yield new Promise((resolve, reject) => {
let timeoutId;
let onFullScreenChange = () => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
clearTimeout(timeoutId);
resolve();
}
document.addEventListener("fullscreenchange", onFullScreenChange);
timeoutId = setTimeout(() => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
reject();
}, 5000);
})
.then(() => {
ok(true, "Element is no longer fullscreen");
})
.catch(() => {
ok(false, "Element is no longer fullscreen");
});
});
}
</script>
<iframe id="iframe1" src="1028200-subpageB.html" height="600" width="600"></iframe>
</body>

Просмотреть файл

@ -0,0 +1,102 @@
<head>
<meta charset="utf-8">
<title>Plugin Crash, FullScreenElement Cancelled, div[F] -> plugin</title>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
</head>
<body onLoad="load()">
<script class="testbody" type="application/javascript">
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
SimpleTest.expectChildProcessCrash();
SimpleTest.requestFlakyTimeout("This is needed in the event the " +
"fullscreen element fails to cancel fullscreen. The fullscreen " +
"element is expected to exit fullscreen but takes some time to " +
"register as having exited when using `mozCancelFullScreen`. So we " +
"can't just check that `mozFullScreenElement` is true or false after " +
"having called `mozCancelFullScreen` without the timeout because it " +
"will return the value prior to actually cancelling. A timeout is " +
"preferred here as opposed to polling methods similar to " +
"`SimpleTest.waitForCondition` in `SimpleTest.js` for reasons of" +
"idiomaticity."
);
/**
* FullScreen element is expected to remain alive after the test ends; this
* stops it.
*/
SimpleTest.registerCleanupFunction(() => {
if (this.document.mozFullScreenElement) {
let fullScreenChange = promiseFullScreenChange();
this.document.mozCancelFullScreen();
return fullScreenChange;
}
});
/**
* Start with a fullscreen element.
* Then crash the plugin - which is expected to be a child of the full
* screen element - and therefore exit out of the fullscreen element.
*/
let load = function testCrashChildPlugin_expectFullScreenElementToBeCancelled() {
add_task(function* () {
/* Needed to be able to programatically (without user interaction) enter
* fullscreen (has been deemed a security issue otherwise and therefore
* disabled by default)
*/
yield SpecialPowers.pushPrefEnv(
{ "set": [ ["full-screen-api.allow-trusted-requests-only", false] ] });
});
add_task(function* () {
let fullScreenElement = document.getElementById('div1');
let plugin = document.getElementById('plugin1');
let fullScreenChange = promiseFullScreenChange();
fullScreenElement.mozRequestFullScreen();
yield fullScreenChange;
ok(true, "Element is fullscreen");
yield crashPlugin(plugin)
.then(() => {
ok(true, "Plugin was crashed");
})
.catch(() => {
ok(false, "Plugin was crashed");
});
});
add_task(function* () {
/**
* We expect the fullscreen mode to change in this test. We'll wait
* 5 seconds for any kind of fullscreen change to occur, and fail if it
* doesn't.
*/
yield new Promise((resolve, reject) => {
let timeoutId;
let onFullScreenChange = () => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
clearTimeout(timeoutId);
resolve();
}
document.addEventListener("fullscreenchange", onFullScreenChange);
timeoutId = setTimeout(() => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
reject();
}, 5000);
})
.then(() => {
ok(true, "Element is no longer fullscreen");
})
.catch(() => {
ok(false, "Element is no longer fullscreen");
});
});
}
</script>
<div id="div1">
<embed id="plugin1" type="application/x-test" />
</div>
</body>

Просмотреть файл

@ -0,0 +1,102 @@
<head>
<meta charset="utf-8">
<title>Plugin Crash, FullScreenElement Remains, iframe[F];plugin</title>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
</head>
<body onLoad="load()">
<script class="testbody" type="application/javascript">
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
SimpleTest.expectChildProcessCrash();
SimpleTest.requestFlakyTimeout("This is needed in the event the " +
"fullscreen element fails to cancel fullscreen. The fullscreen " +
"element is expected to exit fullscreen but takes some time to " +
"register as having exited when using `mozCancelFullScreen`. So we " +
"can't just check that `mozFullScreenElement` is true or false after " +
"having called `mozCancelFullScreen` without the timeout because it " +
"will return the value prior to actually cancelling. A timeout is " +
"preferred here as opposed to polling methods similar to " +
"`SimpleTest.waitForCondition` in `SimpleTest.js` for reasons of" +
"idiomaticity."
);
/**
* FullScreen element is expected to remain alive after the test ends; this
* stops it.
*/
SimpleTest.registerCleanupFunction(() => {
if (this.document.mozFullScreenElement) {
let fullScreenChange = promiseFullScreenChange();
this.document.mozCancelFullScreen();
return fullScreenChange;
}
});
/**
* Start with a fullscreen element.
* Then crash the plugin - which is expected to not be a child of the full
* screen element - and therefore remain in the fullscreen element.
*/
let load = function testCrashChildPlugin_expectFullScreenElementToRemain() {
add_task(function* () {
/* Needed to be able to programatically (without user interaction) enter
* fullscreen (has been deemed a security issue otherwise and therefore
* disabled by default)
*/
yield SpecialPowers.pushPrefEnv(
{ "set": [ ["full-screen-api.allow-trusted-requests-only", false] ] });
});
add_task(function* () {
let fullScreenElement = document.getElementById('iframe1');
let plugin = document.getElementById('plugin1');
let fullScreenChange = promiseFullScreenChange();
fullScreenElement.mozRequestFullScreen();
yield fullScreenChange;
ok(true, "Element is fullscreen");
yield crashPlugin(plugin)
.then(() => {
ok(true, "Plugin was crashed");
})
.catch(() => {
ok(false, "Plugin was crashed");
});
});
add_task(function* () {
/**
* We expect the fullscreen mode to _not_ change in this test. We'll wait
* 5 seconds for any kind of fullscreen change to occur, and fail if it
* does. Otherwise, we'll assume fullscreen didn't change and finish the
* test.
*/
yield new Promise((resolve, reject) => {
let timeoutId;
let onFullScreenChange = () => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
clearTimeout(timeoutId);
reject();
}
document.addEventListener("fullscreenchange", onFullScreenChange);
timeoutId = setTimeout(() => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
resolve();
}, 5000);
})
.then(() => {
ok(true, "Element is still fullscreen");
})
.catch(() => {
ok(false, "Element is still fullscreen");
});
});
}
</script>
<iframe id="iframe1"></iframe>
<embed id="plugin1" type="application/x-test" />
</body>

Просмотреть файл

@ -0,0 +1,105 @@
<head>
<meta charset="utf-8">
<title>Plugin Crash, FullScreenElement Remains, iframe -> div[F]; iframe -> iframe -> plugin</title>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
</head>
<body onLoad="load()">
<script class="testbody" type="application/javascript">
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
SimpleTest.expectChildProcessCrash();
SimpleTest.requestFlakyTimeout("This is needed in the event the " +
"fullscreen element fails to cancel fullscreen. The fullscreen " +
"element is expected to exit fullscreen but takes some time to " +
"register as having exited when using `mozCancelFullScreen`. So we " +
"can't just check that `mozFullScreenElement` is true or false after " +
"having called `mozCancelFullScreen` without the timeout because it " +
"will return the value prior to actually cancelling. A timeout is " +
"preferred here as opposed to polling methods similar to " +
"`SimpleTest.waitForCondition` in `SimpleTest.js` for reasons of" +
"idiomaticity."
);
/**
* FullScreen element is expected to remain alive after the test ends; this
* stops it.
*/
SimpleTest.registerCleanupFunction(() => {
if (this.document.mozFullScreenElement) {
let fullScreenChange = promiseFullScreenChange();
this.document.mozCancelFullScreen();
return fullScreenChange;
}
});
/**
* Start with a fullscreen element.
* Then crash the plugin - which is expected to not be a child of the full
* screen element - and therefore remain in the fullscreen element.
*/
let load = function testCrashChildPlugin_expectFullScreenElementToRemain() {
add_task(function* () {
/* Needed to be able to programatically (without user interaction) enter
* fullscreen (has been deemed a security issue otherwise and therefore
* disabled by default)
*/
yield SpecialPowers.pushPrefEnv(
{ "set": [ ["full-screen-api.allow-trusted-requests-only", false] ] });
});
add_task(function* () {
let fullScreenElement = document.getElementById('iframeA')
let plugin = document.getElementById('iframe1')
.contentDocument.getElementById('iframe2')
.contentDocument.getElementById('plugin1');
let fullScreenChange = promiseFullScreenChange();
fullScreenElement.mozRequestFullScreen();
yield fullScreenChange;
ok(true, "Element is fullscreen");
yield crashPlugin(plugin)
.then(() => {
ok(true, "Plugin was crashed");
})
.catch(() => {
ok(false, "Plugin was crashed");
});
});
add_task(function* () {
/**
* We expect the fullscreen mode to _not_ change in this test. We'll wait
* 5 seconds for any kind of fullscreen change to occur, and fail if it
* does. Otherwise, we'll assume fullscreen didn't change and finish the
* test.
*/
yield new Promise((resolve, reject) => {
let timeoutId;
let onFullScreenChange = () => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
clearTimeout(timeoutId);
reject();
}
document.addEventListener("fullscreenchange", onFullScreenChange);
timeoutId = setTimeout(() => {
document.removeEventListener("fullscreenchange", onFullScreenChange);
resolve();
}, 5000);
})
.then(() => {
ok(true, "Element is still fullscreen");
})
.catch(() => {
ok(false, "Element is still fullscreen");
});
});
}
</script>
<iframe id="iframeA" src="1028200-subpageC.html" allowfullscreen="true"></iframe>
<iframe id="iframe1" src="1028200-subpageA.html" height="600" width="600"></iframe>
</body>