[PTZ] Expose image capture pan & tilt only if PTZ permission is granted
This CL makes sure the pan/tilt capabilities/constraints/settings
are available only if PTZ permission is granted to the website when the
the MediaCapturePanTilt feature is enabled.
If the MediaCapturePanTilt feature is disabled, the pan/tilt (not zoom)
capabilities/constraints/settings are not available due to the presence
of [RuntimeEnabled=MediaCapturePanTilt] attributes in WebIDLs while the
zoom capabilities/constraints/settings is still available regardless of
the PTZ permission.
An upcoming CL regarding PTZ support in getUserMedia will address a
potential race condition that may happen if PTZ permission status is not
retrieved when getting pan/tilt capabilities/constraints/settings.
Manual test: https://ptz.glitch.me/
Explainer: https://github.com/w3c/mediacapture-image/blob/master/ptz-explainer.md
Change-Id: Ieaefb0e239dd6921cdd4de5441afb7cd4050bf5b
Bug: 934063
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2151567
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Reviewed-by: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: Andy Paicu <andypaicu@chromium.org>
Reviewed-by: Rijubrata Bhaumik <rijubrata.bhaumik@intel.com>
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Commit-Queue: François Beaufort <beaufort.francois@gmail.com>
Cr-Commit-Position: refs/heads/master@{#769235}
diff --git a/lint.ignore b/lint.ignore
index 8cfef1e..ddb9f9f 100644
--- a/lint.ignore
+++ b/lint.ignore
@@ -262,7 +262,9 @@
GENERATE_TESTS: domxpath/001.html
GENERATE_TESTS: domxpath/002.html
GENERATE_TESTS: mediacapture-image/MediaStreamTrack-applyConstraints-reject.html
+GENERATE_TESTS: mediacapture-image/MediaStreamTrack-getCapabilities.html
GENERATE_TESTS: mediacapture-image/MediaStreamTrack-getConstraints-fast.html
+GENERATE_TESTS: mediacapture-image/MediaStreamTrack-getSettings.html
GENERATE_TESTS: mediacapture-image/setOptions-reject.html
GENERATE_TESTS: html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html
GENERATE_TESTS: html/syntax/parsing/Document.getElementsByTagName-foreign-01.html
diff --git a/mediacapture-image/MediaStreamTrack-applyConstraints-getSettings.html b/mediacapture-image/MediaStreamTrack-applyConstraints-getSettings.html
index 9d985de..a1695b1 100644
--- a/mediacapture-image/MediaStreamTrack-applyConstraints-getSettings.html
+++ b/mediacapture-image/MediaStreamTrack-applyConstraints-getSettings.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<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 src="/mediacapture-image/resources/imagecapture-helpers.js"></script>
<body>
<canvas id='canvas' width=10 height=10/>
@@ -11,6 +13,9 @@
// service implementation, are returned by MediaStreamTrack.getSettings().
image_capture_test(async t => {
+ await test_driver.set_permission({name: 'camera', panTiltZoom: true},
+ 'granted', false);
+
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
context.fillStyle = 'red';
@@ -98,6 +103,40 @@
assert_equals(constraints.advanced[0].torch, settings.torch, 'torch');
-}, 'exercises an applyConstraints() - getSettings() cycle');
+}, 'exercises an applyConstraints() - getSettings() cycle with PTZ permission granted');
+
+
+// This test verifies that the PTZ |constraints| configured in the mock Mojo
+// service implementation can't be applied if PTZ permission is denied.
+
+image_capture_test(async t => {
+ await test_driver.set_permission({name: 'camera', panTiltZoom: true},
+ 'denied', false);
+
+ let canvas = document.getElementById('canvas');
+ let context = canvas.getContext('2d');
+ context.fillStyle = 'red';
+ context.fillRect(0, 0, 10, 10);
+
+ let stream = canvas.captureStream();
+ let videoTrack = stream.getVideoTracks()[0];
+
+ // |videoTrack|'s capabilities gathering, just like the actual capture, is
+ // a process kicked off right after creation, we introduce a small delay
+ // to allow for those to be collected, since they are needed to understand
+ // which constraints are supported in applyConstraints().
+ // TODO(mcasas): this shouldn't be needed, https://crbug.com/711524.
+ await new Promise(resolve => step_timeout(resolve, 100));
+
+ const constraints = [{ pan: 8 }, { tilt: 9 }];
+ await Promise.all(constraints.map(async constraint =>
+ promise_rejects_dom(
+ t, 'NotAllowedError',
+ videoTrack.applyConstraints({ advanced: [constraint] }),
+ "applyConstraints should throw a NotAllowedError for " +
+ JSON.stringify(constraint))
+ ));
+
+}, 'exercises an applyConstraints() with PTZ permission denied');
</script>
\ No newline at end of file
diff --git a/mediacapture-image/MediaStreamTrack-applyConstraints-reject.html b/mediacapture-image/MediaStreamTrack-applyConstraints-reject.html
index 2171963..45599c0 100644
--- a/mediacapture-image/MediaStreamTrack-applyConstraints-reject.html
+++ b/mediacapture-image/MediaStreamTrack-applyConstraints-reject.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<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 src="/mediacapture-image/resources/imagecapture-helpers.js"></script>
<body>
<canvas id='canvas' width=10 height=10/>
@@ -16,6 +18,9 @@
// passed constraint is unsupported or outside its allowed range.
var makePromiseTest = function(getConstraint) {
image_capture_test(async (t, imageCaptureTest) => {
+ await test_driver.set_permission({name: 'camera', panTiltZoom: true},
+ 'granted', false);
+
imageCaptureTest.mockImageCapture().state().supportsTorch = false;
let stream = canvas.captureStream();
diff --git a/mediacapture-image/MediaStreamTrack-applyConstraints.html b/mediacapture-image/MediaStreamTrack-applyConstraints.html
index da3de3e..3c5c05a 100644
--- a/mediacapture-image/MediaStreamTrack-applyConstraints.html
+++ b/mediacapture-image/MediaStreamTrack-applyConstraints.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<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 src="/mediacapture-image/resources/imagecapture-helpers.js"></script>
<body>
<canvas id='canvas' width=10 height=10/>
@@ -13,6 +15,9 @@
// a mock Mojo service implementation.
image_capture_test(async (t, imageCaptureTest) => {
+ await test_driver.set_permission({name: 'camera', panTiltZoom: true},
+ 'granted', false);
+
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
context.fillStyle = 'red';
@@ -113,6 +118,7 @@
assert_equals(constraintsDict.pan, theMock.options().pan, 'pan');
assert_equals(constraintsDict.tilt, theMock.options().tilt, 'tilt');
+ assert_equals(constraintsDict.zoom, theMock.options().zoom, 'zoom');
assert_equals(constraintsDict.torch, theMock.options().torch, 'torch');
diff --git a/mediacapture-image/MediaStreamTrack-getCapabilities.html b/mediacapture-image/MediaStreamTrack-getCapabilities.html
index e7b196f..c569283 100644
--- a/mediacapture-image/MediaStreamTrack-getCapabilities.html
+++ b/mediacapture-image/MediaStreamTrack-getCapabilities.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<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 src="/mediacapture-image/resources/imagecapture-helpers.js"></script>
<body>
<canvas id='canvas' width=10 height=10/>
@@ -11,154 +13,174 @@
// This test verifies that MediaTrackCapabilities are returned upon
// MediaStreamTrack.getCapabilities(), with a mock Mojo service implementation.
+// When PTZ permission is denied though, PTZ capabilities are not available.
-image_capture_test(async (t, imageCaptureTest) => {
- let canvas = document.getElementById('canvas');
- let context = canvas.getContext('2d');
- context.fillStyle = 'red';
- context.fillRect(0, 0, 10, 10);
+function makeImageCaptureTest(hasPanTiltZoomPermissionGranted) {
+ image_capture_test(async (t, imageCaptureTest) => {
+ const ptzPermission = hasPanTiltZoomPermissionGranted ? 'granted' : 'denied';
+ await test_driver.set_permission({name: 'camera', panTiltZoom: true},
+ ptzPermission, false);
- let mockCapabilities = imageCaptureTest.mockImageCapture().state();
+ let canvas = document.getElementById('canvas');
+ let context = canvas.getContext('2d');
+ context.fillStyle = 'red';
+ context.fillRect(0, 0, 10, 10);
- // |stream| must be created _after_ |mock| is constructed to give the
- // latter time to override the bindings.
- let stream = canvas.captureStream();
- assert_equals(stream.getAudioTracks().length, 0);
- assert_equals(stream.getVideoTracks().length, 1);
+ let mockCapabilities = imageCaptureTest.mockImageCapture().state();
- let videoTrack = stream.getVideoTracks()[0];
- assert_equals(typeof videoTrack.getCapabilities, 'function');
+ // |stream| must be created _after_ |mock| is constructed to give the
+ // latter time to override the bindings.
+ let stream = canvas.captureStream();
+ assert_equals(stream.getAudioTracks().length, 0);
+ assert_equals(stream.getVideoTracks().length, 1);
- // |videoTrack|'s capabilities gathering, just like the actual capture, is
- // a process kicked off right after creation, we introduce a small delay
- // to allow for those to be collected.
- // TODO(mcasas): this shouldn't be needed, https://crbug.com/711524.
- await new Promise(resolve => step_timeout(resolve, 100));
+ let videoTrack = stream.getVideoTracks()[0];
+ assert_equals(typeof videoTrack.getCapabilities, 'function');
- let capabilities = videoTrack.getCapabilities();
- assert_equals(typeof capabilities, 'object');
+ // |videoTrack|'s capabilities gathering, just like the actual capture, is
+ // a process kicked off right after creation, we introduce a small delay
+ // to allow for those to be collected.
+ // TODO(mcasas): this shouldn't be needed, https://crbug.com/711524.
+ await new Promise(resolve => step_timeout(resolve, 100));
- assert_equals(capabilities.whiteBalanceMode.length,
- mockCapabilities.supportedWhiteBalanceModes.length,
- 'whiteBalanceMode');
- for (i = 0; i < capabilities.whiteBalanceMode.length; ++i) {
- assert_equals(
- capabilities.whiteBalanceMode[i],
- meteringModeNames[mockCapabilities
- .supportedWhiteBalanceModes[i]],
- 'whiteBalanceMode');
- }
+ let capabilities = videoTrack.getCapabilities();
+ assert_equals(typeof capabilities, 'object');
- assert_equals(capabilities.exposureMode.length,
- mockCapabilities.supportedExposureModes.length,
- 'exposureMode');
- for (i = 0; i < capabilities.exposureMode.length; ++i) {
- assert_equals(
- capabilities.exposureMode[i],
- meteringModeNames[mockCapabilities.supportedExposureModes[i]],
- 'exposureMode');
- }
+ assert_equals(capabilities.whiteBalanceMode.length,
+ mockCapabilities.supportedWhiteBalanceModes.length,
+ 'whiteBalanceMode');
+ for (i = 0; i < capabilities.whiteBalanceMode.length; ++i) {
+ assert_equals(
+ capabilities.whiteBalanceMode[i],
+ meteringModeNames[mockCapabilities
+ .supportedWhiteBalanceModes[i]],
+ 'whiteBalanceMode');
+ }
- assert_equals(capabilities.focusMode.length,
- mockCapabilities.supportedFocusModes.length,
- 'focusMode');
- for (i = 0; i < capabilities.focusMode.length; ++i) {
- assert_equals(
- capabilities.focusMode[i],
- meteringModeNames[mockCapabilities.supportedFocusModes[i]],
- 'focusMode');
- }
+ assert_equals(capabilities.exposureMode.length,
+ mockCapabilities.supportedExposureModes.length,
+ 'exposureMode');
+ for (i = 0; i < capabilities.exposureMode.length; ++i) {
+ assert_equals(
+ capabilities.exposureMode[i],
+ meteringModeNames[mockCapabilities.supportedExposureModes[i]],
+ 'exposureMode');
+ }
- assert_true(capabilities.exposureCompensation instanceof
- MediaSettingsRange);
- assert_equals(capabilities.exposureCompensation.max,
- mockCapabilities.exposureCompensation.max);
- assert_equals(capabilities.exposureCompensation.min,
- mockCapabilities.exposureCompensation.min);
- assert_equals(capabilities.exposureCompensation.step,
- mockCapabilities.exposureCompensation.step);
+ assert_equals(capabilities.focusMode.length,
+ mockCapabilities.supportedFocusModes.length,
+ 'focusMode');
+ for (i = 0; i < capabilities.focusMode.length; ++i) {
+ assert_equals(
+ capabilities.focusMode[i],
+ meteringModeNames[mockCapabilities.supportedFocusModes[i]],
+ 'focusMode');
+ }
- assert_true(capabilities.exposureTime instanceof
- MediaSettingsRange);
- assert_equals(capabilities.exposureTime.max,
- mockCapabilities.exposureTime.max);
- assert_equals(capabilities.exposureTime.min,
- mockCapabilities.exposureTime.min);
- assert_equals(capabilities.exposureTime.step,
- mockCapabilities.exposureTime.step);
+ assert_true(capabilities.exposureCompensation instanceof
+ MediaSettingsRange);
+ assert_equals(capabilities.exposureCompensation.max,
+ mockCapabilities.exposureCompensation.max);
+ assert_equals(capabilities.exposureCompensation.min,
+ mockCapabilities.exposureCompensation.min);
+ assert_equals(capabilities.exposureCompensation.step,
+ mockCapabilities.exposureCompensation.step);
- assert_true(capabilities.colorTemperature instanceof
- MediaSettingsRange);
- assert_equals(capabilities.colorTemperature.max,
- mockCapabilities.colorTemperature.max);
- assert_equals(capabilities.colorTemperature.min,
- mockCapabilities.colorTemperature.min);
- assert_equals(capabilities.colorTemperature.step,
- mockCapabilities.colorTemperature.step);
+ assert_true(capabilities.exposureTime instanceof
+ MediaSettingsRange);
+ assert_equals(capabilities.exposureTime.max,
+ mockCapabilities.exposureTime.max);
+ assert_equals(capabilities.exposureTime.min,
+ mockCapabilities.exposureTime.min);
+ assert_equals(capabilities.exposureTime.step,
+ mockCapabilities.exposureTime.step);
- assert_true(capabilities.iso instanceof MediaSettingsRange);
- assert_equals(capabilities.iso.max, mockCapabilities.iso.max);
- assert_equals(capabilities.iso.min, mockCapabilities.iso.min);
- assert_equals(capabilities.iso.step, mockCapabilities.iso.step);
+ assert_true(capabilities.colorTemperature instanceof
+ MediaSettingsRange);
+ assert_equals(capabilities.colorTemperature.max,
+ mockCapabilities.colorTemperature.max);
+ assert_equals(capabilities.colorTemperature.min,
+ mockCapabilities.colorTemperature.min);
+ assert_equals(capabilities.colorTemperature.step,
+ mockCapabilities.colorTemperature.step);
- assert_true(capabilities.brightness instanceof MediaSettingsRange);
- assert_equals(capabilities.brightness.max,
- mockCapabilities.brightness.max);
- assert_equals(capabilities.brightness.min,
- mockCapabilities.brightness.min);
- assert_equals(capabilities.brightness.step,
- mockCapabilities.brightness.step);
+ assert_true(capabilities.iso instanceof MediaSettingsRange);
+ assert_equals(capabilities.iso.max, mockCapabilities.iso.max);
+ assert_equals(capabilities.iso.min, mockCapabilities.iso.min);
+ assert_equals(capabilities.iso.step, mockCapabilities.iso.step);
- assert_true(capabilities.contrast instanceof MediaSettingsRange);
- assert_equals(capabilities.contrast.max,
- mockCapabilities.contrast.max);
- assert_equals(capabilities.contrast.min,
- mockCapabilities.contrast.min);
- assert_equals(capabilities.contrast.step,
- mockCapabilities.contrast.step);
+ assert_true(capabilities.brightness instanceof MediaSettingsRange);
+ assert_equals(capabilities.brightness.max,
+ mockCapabilities.brightness.max);
+ assert_equals(capabilities.brightness.min,
+ mockCapabilities.brightness.min);
+ assert_equals(capabilities.brightness.step,
+ mockCapabilities.brightness.step);
- assert_true(capabilities.saturation instanceof MediaSettingsRange);
- assert_equals(capabilities.saturation.max,
- mockCapabilities.saturation.max);
- assert_equals(capabilities.saturation.min,
- mockCapabilities.saturation.min);
- assert_equals(capabilities.saturation.step,
- mockCapabilities.saturation.step);
+ assert_true(capabilities.contrast instanceof MediaSettingsRange);
+ assert_equals(capabilities.contrast.max,
+ mockCapabilities.contrast.max);
+ assert_equals(capabilities.contrast.min,
+ mockCapabilities.contrast.min);
+ assert_equals(capabilities.contrast.step,
+ mockCapabilities.contrast.step);
- assert_true(capabilities.sharpness instanceof MediaSettingsRange);
- assert_equals(capabilities.sharpness.max,
- mockCapabilities.sharpness.max);
- assert_equals(capabilities.sharpness.min,
- mockCapabilities.sharpness.min);
- assert_equals(capabilities.sharpness.step,
- mockCapabilities.sharpness.step);
+ assert_true(capabilities.saturation instanceof MediaSettingsRange);
+ assert_equals(capabilities.saturation.max,
+ mockCapabilities.saturation.max);
+ assert_equals(capabilities.saturation.min,
+ mockCapabilities.saturation.min);
+ assert_equals(capabilities.saturation.step,
+ mockCapabilities.saturation.step);
- assert_true(capabilities.focusDistance instanceof MediaSettingsRange);
- assert_equals(capabilities.focusDistance.max,
- mockCapabilities.focusDistance.max);
- assert_equals(capabilities.focusDistance.min,
- mockCapabilities.focusDistance.min);
- assert_equals(capabilities.focusDistance.step,
- mockCapabilities.focusDistance.step);
+ assert_true(capabilities.sharpness instanceof MediaSettingsRange);
+ assert_equals(capabilities.sharpness.max,
+ mockCapabilities.sharpness.max);
+ assert_equals(capabilities.sharpness.min,
+ mockCapabilities.sharpness.min);
+ assert_equals(capabilities.sharpness.step,
+ mockCapabilities.sharpness.step);
- assert_true(capabilities.pan instanceof MediaSettingsRange);
- assert_equals(capabilities.pan.max, mockCapabilities.pan.max);
- assert_equals(capabilities.pan.min, mockCapabilities.pan.min);
- assert_equals(capabilities.pan.step, mockCapabilities.pan.step);
+ assert_true(capabilities.focusDistance instanceof MediaSettingsRange);
+ assert_equals(capabilities.focusDistance.max,
+ mockCapabilities.focusDistance.max);
+ assert_equals(capabilities.focusDistance.min,
+ mockCapabilities.focusDistance.min);
+ assert_equals(capabilities.focusDistance.step,
+ mockCapabilities.focusDistance.step);
- assert_true(capabilities.tilt instanceof MediaSettingsRange);
- assert_equals(capabilities.tilt.max, mockCapabilities.tilt.max);
- assert_equals(capabilities.tilt.min, mockCapabilities.tilt.min);
- assert_equals(capabilities.tilt.step, mockCapabilities.tilt.step);
+ if (ptzPermission === 'granted') {
+ assert_true(capabilities.pan instanceof MediaSettingsRange);
+ assert_equals(capabilities.pan.max, mockCapabilities.pan.max);
+ assert_equals(capabilities.pan.min, mockCapabilities.pan.min);
+ assert_equals(capabilities.pan.step, mockCapabilities.pan.step);
- assert_true(capabilities.zoom instanceof MediaSettingsRange);
- assert_equals(capabilities.zoom.max, mockCapabilities.zoom.max);
- assert_equals(capabilities.zoom.min, mockCapabilities.zoom.min);
- assert_equals(capabilities.zoom.step, mockCapabilities.zoom.step);
+ assert_true(capabilities.tilt instanceof MediaSettingsRange);
+ assert_equals(capabilities.tilt.max, mockCapabilities.tilt.max);
+ assert_equals(capabilities.tilt.min, mockCapabilities.tilt.min);
+ assert_equals(capabilities.tilt.step, mockCapabilities.tilt.step);
+ } else if (ptzPermission === 'denied') {
+ assert_false('pan' in capabilities);
+ assert_false('tilt' in capabilities);
+ }
+ assert_true(capabilities.zoom instanceof MediaSettingsRange);
+ assert_equals(capabilities.zoom.max, mockCapabilities.zoom.max);
+ assert_equals(capabilities.zoom.min, mockCapabilities.zoom.min);
+ assert_equals(capabilities.zoom.step, mockCapabilities.zoom.step);
- assert_equals(capabilities.torch, mockCapabilities.supportsTorch,
- 'torch');
+ assert_equals(capabilities.torch, mockCapabilities.supportsTorch,
+ 'torch');
+ });
+}
-}, 'exercises MediaStreamTrack.getCapabilities()');
-
+generate_tests(makeImageCaptureTest, [
+ [
+ "exercises MediaStreamTrack.getCapabilities() with PTZ permission denied",
+ false,
+ ],
+ [
+ "exercises MediaStreamTrack.getCapabilities() with PTZ permission granted",
+ true,
+ ],
+]);
</script>
diff --git a/mediacapture-image/MediaStreamTrack-getSettings.html b/mediacapture-image/MediaStreamTrack-getSettings.html
index a1a864c..8fc2c82 100644
--- a/mediacapture-image/MediaStreamTrack-getSettings.html
+++ b/mediacapture-image/MediaStreamTrack-getSettings.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<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 src="/mediacapture-image/resources/imagecapture-helpers.js"></script>
<body>
<canvas id='canvas' width=10 height=10/>
@@ -11,63 +13,84 @@
// This test verifies that the settings defined in the mock Mojo service
// implementation are the same as those returned by the corresponding
-// MediaStreamTrack.getSettings().
+// MediaStreamTrack.getSettings(), except for PTZ settings when PTZ
+// permission is denied.
-image_capture_test(async (t, imageCaptureTest) => {
- let canvas = document.getElementById('canvas');
- let context = canvas.getContext('2d');
- context.fillStyle = 'red';
- context.fillRect(0, 0, 10, 10);
+function makeImageCaptureTest(hasPanTiltZoomPermissionGranted) {
+ image_capture_test(async (t, imageCaptureTest) => {
+ const ptzPermission = hasPanTiltZoomPermissionGranted ? 'granted' : 'denied';
+ await test_driver.set_permission({name: 'camera', panTiltZoom: true},
+ ptzPermission, false);
- let mockSettings = imageCaptureTest.mockImageCapture().state();
+ let canvas = document.getElementById('canvas');
+ let context = canvas.getContext('2d');
+ context.fillStyle = 'red';
+ context.fillRect(0, 0, 10, 10);
- // |stream| must be created _after_ |mock| is constructed to give the
- // latter time to override the bindings.
- let stream = canvas.captureStream();
- let videoTrack = stream.getVideoTracks()[0];
+ let mockSettings = imageCaptureTest.mockImageCapture().state();
- // |videoTrack|s settings retrieval, just like the actual capture, is a
- // process kicked right after creation, we introduce a small delay to
- // allow for those to be collected.
- await new Promise(resolve => step_timeout(resolve, 100));
+ // |stream| must be created _after_ |mock| is constructed to give the
+ // latter time to override the bindings.
+ let stream = canvas.captureStream();
+ let videoTrack = stream.getVideoTracks()[0];
- let settings = videoTrack.getSettings();
- assert_equals(typeof settings, 'object');
+ // |videoTrack|s settings retrieval, just like the actual capture, is a
+ // process kicked right after creation, we introduce a small delay to
+ // allow for those to be collected.
+ await new Promise(resolve => step_timeout(resolve, 100));
- assert_equals(settings.whiteBalanceMode,
- meteringModeNames[mockSettings.currentWhiteBalanceMode],
- 'whiteBalanceMode');
- assert_equals(settings.exposureMode,
- meteringModeNames[mockSettings.currentExposureMode],
- 'exposureMode;');
- assert_equals(settings.focusMode,
- meteringModeNames[mockSettings.currentFocusMode],
- 'focusMode');
+ let settings = videoTrack.getSettings();
+ assert_equals(typeof settings, 'object');
- assert_point2d_array_approx_equals(
- settings.pointsOfInterest, mockSettings.pointsOfInterest, 0.01);
+ assert_equals(settings.whiteBalanceMode,
+ meteringModeNames[mockSettings.currentWhiteBalanceMode],
+ 'whiteBalanceMode');
+ assert_equals(settings.exposureMode,
+ meteringModeNames[mockSettings.currentExposureMode],
+ 'exposureMode;');
+ assert_equals(settings.focusMode,
+ meteringModeNames[mockSettings.currentFocusMode],
+ 'focusMode');
- assert_equals(settings.exposureCompensation,
- mockSettings.exposureCompensation.current);
- assert_equals(settings.exposureTime,
- mockSettings.exposureTime.current);
- assert_equals(settings.colorTemperature,
- mockSettings.colorTemperature.current);
- assert_equals(settings.iso, mockSettings.iso.current);
+ assert_point2d_array_approx_equals(
+ settings.pointsOfInterest, mockSettings.pointsOfInterest, 0.01);
- assert_equals(settings.brightness, mockSettings.brightness.current);
- assert_equals(settings.contrast, mockSettings.contrast.current);
- assert_equals(settings.saturation, mockSettings.saturation.current);
- assert_equals(settings.sharpness, mockSettings.sharpness.current);
+ assert_equals(settings.exposureCompensation,
+ mockSettings.exposureCompensation.current);
+ assert_equals(settings.exposureTime,
+ mockSettings.exposureTime.current);
+ assert_equals(settings.colorTemperature,
+ mockSettings.colorTemperature.current);
+ assert_equals(settings.iso, mockSettings.iso.current);
- assert_equals(settings.focusDistance, mockSettings.focusDistance.current);
+ assert_equals(settings.brightness, mockSettings.brightness.current);
+ assert_equals(settings.contrast, mockSettings.contrast.current);
+ assert_equals(settings.saturation, mockSettings.saturation.current);
+ assert_equals(settings.sharpness, mockSettings.sharpness.current);
- assert_equals(settings.pan, mockSettings.pan.current);
- assert_equals(settings.tilt, mockSettings.tilt.current);
- assert_equals(settings.zoom, mockSettings.zoom.current);
+ assert_equals(settings.focusDistance, mockSettings.focusDistance.current);
- assert_equals(settings.torch, mockSettings.torch, 'torch');
+ if (ptzPermission === 'granted') {
+ assert_equals(settings.pan, mockSettings.pan.current);
+ assert_equals(settings.tilt, mockSettings.tilt.current);
+ } else if (ptzPermission === 'denied') {
+ assert_false('pan' in settings);
+ assert_false('tilt' in settings);
+ }
+ assert_equals(settings.zoom, mockSettings.zoom.current);
-}, 'exercises MediaStreamTrack.getSettings()');
+ assert_equals(settings.torch, mockSettings.torch, 'torch');
+ });
+}
+generate_tests(makeImageCaptureTest, [
+ [
+ "exercises MediaStreamTrack.getSettings() with PTZ permission denied",
+ false,
+ ],
+ [
+ "exercises MediaStreamTrack.getSettings() with PTZ permission granted",
+ true,
+ ],
+]);
</script>