Skip to content

Commit

Permalink
Bug 1814902 [wpt PR 38347] - Reject getDisplayMedia calls without use…
Browse files Browse the repository at this point in the history
…r activation, a=testonly

Automatic update from web-platform-tests
Reject getDisplayMedia calls without user activation

This CL makes sure getDisplayMedia() returned promise reject with
InvalidStateError when called without user activation. This is now gated
by an experimental blink feature as it was revered several times before.

Note that speculation rules tests are updated as well[1].

[1] WICG/nav-speculation#225

Intent to remove: https://groups.google.com/a/chromium.org/g/blink-dev/c/YGmuAVOqftI

Bug: 1198918
Change-Id: I9517012e76478b108d74bff432b71095ac7ba4d2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4219093
Commit-Queue: Fr <beaufort.francois@gmail.com>
Reviewed-by: Elad Alon <eladalon@chromium.org>
Reviewed-by: Yoav Weiss <yoavweiss@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1101098}

--

wpt-commits: ac2ff07ac0041f03bc8c8f8481cb5729b8086b25
wpt-pr: 38347
  • Loading branch information
beaufortfrancois authored and moz-wptsync-bot committed Feb 4, 2023
1 parent cf1be4f commit 6906c16
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
<title>MediaStreamTrack transfer to iframe</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script>
promise_test(async () => {
const iframe = document.createElement("iframe");
await test_driver.bless('getDisplayMedia');
const stream = await navigator.mediaDevices.getDisplayMedia({audio:true, video: true});
const track = stream.getAudioTracks()[0];
const result = new Promise((resolve, reject) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
<title>MediaStreamTrack transfer to iframe</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script>
promise_test(async () => {
const iframe = document.createElement("iframe");
await test_driver.bless('getDisplayMedia');
const stream = await navigator.mediaDevices.getDisplayMedia({video: true});
const track = stream.getVideoTracks()[0];
const iframeLoaded = new Promise((resolve) => {iframe.onload = resolve});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
var feature_name = 'permissions policy "payment"';
var header = 'allow="payment" attribute';

async_test(t => {
test_feature_availability_with_post_message_result(
promise_test(t => {
return test_feature_availability_with_post_message_result(
t, cross_origin_src, "NotSupportedError#The 'payment' feature is not " +
"enabled in this document. Permissions Policy may be used to " +
"delegate Web Payment capabilities to cross-origin child frames.");
}, feature_name + ' is not supported in cross-origin iframe without ' + header);

async_test(t => {
test_feature_availability_with_post_message_result(
promise_test(t => {
return test_feature_availability_with_post_message_result(
t, cross_origin_src, 'OK', 'payment');
}, feature_name + ' can be enabled in cross-origin iframe using ' + header);
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ function assert_permissions_policy_supported() {
// https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md
// allow_attribute: Optional argument, only used for testing fullscreen or
// payment: either "allowfullscreen" or "allowpaymentrequest" is passed.
// is_promise_test: Optional argument, true if this call should return a
// promise. Used by test_feature_availability_with_post_message_result()
function test_feature_availability(
feature_description, test, src, expect_feature_available, feature_name,
allow_attribute) {
allow_attribute, is_promise_test = false) {
let frame = document.createElement('iframe');
frame.src = src;

Expand All @@ -40,16 +42,26 @@ function test_feature_availability(
frame.setAttribute(allow_attribute, true);
}

window.addEventListener('message', test.step_func(evt => {
function expectFeatureAvailable(evt) {
if (evt.source === frame.contentWindow &&
evt.data.type === 'availability-result') {
expect_feature_available(evt.data, feature_description);
document.body.removeChild(frame);
test.done();
}
}));
}

if (!is_promise_test) {
window.addEventListener('message', test.step_func(expectFeatureAvailable));
document.body.appendChild(frame);
return;
}

const promise = new Promise((resolve) => {
window.addEventListener('message', resolve);
}).then(expectFeatureAvailable);
document.body.appendChild(frame);
return promise;
}

// Default helper functions to test a feature's availability:
Expand All @@ -76,7 +88,8 @@ function test_feature_availability_with_post_message_result(
const test_result = ({ name, message }, feature_description) => {
assert_equals(name, expected_result, message + '.');
};
test_feature_availability(null, test, src, test_result, allow_attribute);
return test_feature_availability(
null, test, src, test_result, allow_attribute, undefined, true);
}

// If this page is intended to test the named feature (according to the URL),
Expand Down Expand Up @@ -163,39 +176,39 @@ function run_all_fp_tests_allow_self(

// 2. Allowed in same-origin iframe.
const same_origin_frame_pathname = same_origin_url(feature_name);
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
return test_feature_availability_with_post_message_result(
t, same_origin_frame_pathname, '#OK');
},
'Default "' + feature_name +
'" permissions policy ["self"] allows same-origin iframes.');

// 3. Blocked in cross-origin iframe.
const cross_origin_frame_url = cross_origin_url(cross_origin, feature_name);
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
return test_feature_availability_with_post_message_result(
t, cross_origin_frame_url, error_name);
},
'Default "' + feature_name +
'" permissions policy ["self"] disallows cross-origin iframes.');

// 4. Allowed in cross-origin iframe with "allow" attribute.
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
return test_feature_availability_with_post_message_result(
t, cross_origin_frame_url, '#OK', feature_name);
},
'permissions policy "' + feature_name +
'" can be enabled in cross-origin iframes using "allow" attribute.');

// 5. Blocked in same-origin iframe with "allow" attribute set to 'none'.
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
return test_feature_availability_with_post_message_result(
t, same_origin_frame_pathname, error_name,
feature_name + " 'none'");
feature_name + ' \'none\'');
},
'permissions policy "' + feature_name +
'" can be disabled in same-origin iframes using "allow" attribute.');
Expand Down Expand Up @@ -246,40 +259,39 @@ function run_all_fp_tests_allow_all(

// 2. Allowed in same-origin iframe.
const same_origin_frame_pathname = same_origin_url(feature_name);
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
return test_feature_availability_with_post_message_result(
t, same_origin_frame_pathname, '#OK');
},
'Default "' + feature_name +
'" permissions policy ["*"] allows same-origin iframes.');

// 3. Allowed in cross-origin iframe.
const cross_origin_frame_url = cross_origin_url(cross_origin, feature_name);
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
return test_feature_availability_with_post_message_result(
t, cross_origin_frame_url, '#OK');
},
'Default "' + feature_name +
'" permissions policy ["*"] allows cross-origin iframes.');

// 4. Blocked in cross-origin iframe with "allow" attribute set to 'none'.
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
t, cross_origin_frame_url, error_name,
feature_name + " 'none'");
return test_feature_availability_with_post_message_result(
t, cross_origin_frame_url, error_name, feature_name + ' \'none\'');
},
'permissions policy "' + feature_name +
'" can be disabled in cross-origin iframes using "allow" attribute.');

// 5. Blocked in same-origin iframe with "allow" attribute set to 'none'.
async_test(
promise_test(
t => {
test_feature_availability_with_post_message_result(
return test_feature_availability_with_post_message_result(
t, same_origin_frame_pathname, error_name,
feature_name + " 'none'");
feature_name + ' \'none\'');
},
'permissions policy "' + feature_name +
'" can be disabled in same-origin iframes using "allow" attribute.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,23 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/speculation-rules/prerender/resources/utils.js"></script>
<script src="/speculation-rules/prerender/resources/deferred-promise-utils.js"></script>
<script>

const params = new URLSearchParams(location.search);
assert_true(document.prerendering);

// The main test page (restriction-screen-capture.https.html) loads the
// initiator page, then the initiator page will prerender itself with the
// `prerendering` parameter.
const isPrerendering = params.has('prerendering');
async function invokeScreenCaptureAPI(){
const bc = new PrerenderChannel('prerender-channel');

if (!isPrerendering) {
loadInitiatorPage();
} else {
const prerenderEventCollector = new PrerenderEventCollector();
const promise = new Promise(async (resolve, reject) => {
try {
await navigator.mediaDevices.getDisplayMedia({video: true});
resolve();
} catch (e) {
reject(`navigator.mediaDevices.getDisplayMedia error: ${e.toString()}`);
}
});
prerenderEventCollector.start(
promise, 'navigator.mediaDevices.getDisplayMedia');
try {
await navigator.mediaDevices.getDisplayMedia();
bc.postMessage('unexpected success');
} catch (err){
bc.postMessage(err.name);
} finally {
bc.close();
}
}

invokeScreenCaptureAPI();

</script>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<title>Access to the Screen Capture API is deferred</title>
<title>Prerendering cannot invoke the Screen Capture API</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
Expand All @@ -12,8 +12,7 @@

promise_test(async t => {
const uid = token();
const bc = new PrerenderChannel('test-channel', uid);
t.add_cleanup(_ => bc.close());
const bc = new PrerenderChannel('prerender-channel', uid);

const gotMessage = new Promise(resolve => {
bc.addEventListener('message', e => {
Expand All @@ -22,35 +21,15 @@
once: true
});
});
const url = `resources/screen-capture.https.html?uid=${uid}`;
window.open(url, '_blank', 'noopener');

// Start prerendering a page that attempts to invoke the Screen Capture API.
// This API is activated-gated so it's expected to fail:
// https://wicg.github.io/nav-speculation/prerendering.html#implicitly-restricted
startPrerendering(`resources/screen-capture.https.html?uid=${uid}`);
const result = await gotMessage;
const expected = [
{
event: 'started waiting navigator.mediaDevices.getDisplayMedia',
prerendering: true
},
{
event: 'prerendering change',
prerendering: false
},
{
event: 'finished waiting navigator.mediaDevices.getDisplayMedia',
prerendering: false
},
];
assert_equals(result.length, expected.length);
for (let i = 0; i < result.length; i++) {
assert_equals(result[i].event, expected[i].event, `event[${i}]`);
assert_equals(result[i].prerendering, expected[i].prerendering,
`prerendering[${i}]`);
}

// Send a close signal to PrerenderEventCollector on the prerendered page.
new PrerenderChannel('close', uid).postMessage('');
}, `The access to the Screen Capture API should be deferred until the
prerendered page is activated`);
assert_equals(result, 'InvalidStateError');
bc.close();
}, `prerendering pages should not be able to invoke the Screen Capture API`);

</script>
</body>

0 comments on commit 6906c16

Please sign in to comment.