[dart:html] Unsuppress MediaDevices.getUserMedia

Bug: https://github.com/dart-lang/sdk/issues/35253

This API was suppressed initially due to issues with conversions
between promises and futures. Now that that has been resolved, this
should be unsuppressed. Tests have been refactored to use both
navigator.getUserMedia and navigator.mediaDevices.getUserMedia.

Change-Id: Ia131b303192c7eaa3f08475cf700a53665ab3584
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147640
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
Srujan Gaddam 2020-05-12 16:59:49 +00:00 committed by commit-bot@chromium.org
parent 7329ebe25e
commit 0afd7a6907
5 changed files with 146 additions and 141 deletions

View file

@ -20445,6 +20445,15 @@ class MediaDevices extends EventTarget {
@JSName('getSupportedConstraints')
_getSupportedConstraints_1() native;
Future<MediaStream> getUserMedia([Map constraints]) {
var constraints_dict = null;
if (constraints != null) {
constraints_dict = convertDartToNative_Dictionary(constraints);
}
return promiseToFuture<MediaStream>(
JS("", "#.getUserMedia(#)", this, constraints_dict));
}
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a

View file

@ -20484,6 +20484,15 @@ class MediaDevices extends EventTarget {
@JSName('getSupportedConstraints')
_getSupportedConstraints_1() native;
Future<MediaStream> getUserMedia([Map? constraints]) {
var constraints_dict = null;
if (constraints != null) {
constraints_dict = convertDartToNative_Dictionary(constraints);
}
return promiseToFuture<MediaStream>(
JS("", "#.getUserMedia(#)", this, constraints_dict));
}
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a

View file

@ -12,85 +12,81 @@ import 'package:async_helper/async_helper.dart';
// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
main() async {
testUserMediaAudio(Future userMediaFuture) async {
try {
var mediaStream = await userMediaFuture;
expect(mediaStream, isNotNull);
expect(mediaStream is MediaStream, true);
var devices = window.navigator.mediaDevices;
var enumDevices = await devices.enumerateDevices();
expect(enumDevices.length > 1, true);
for (var device in enumDevices) {
var goodDevLabel = device.label.endsWith('Built-in Output') ||
device.label.endsWith('Built-in Microphone');
expect(goodDevLabel, true);
}
} on DomException catch (e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
}
}
testUserMediaVideo(Future userMediaFuture) async {
try {
var mediaStream = await userMediaFuture;
expect(mediaStream, isNotNull);
var url = Url.createObjectUrlFromStream(mediaStream);
expect(url, isNotNull);
var video = new VideoElement()..autoplay = true;
var completer = new Completer();
video.onError.listen((e) {
completer.completeError(e);
});
video.onPlaying.first.then((e) {
completer.complete(video);
});
document.body!.append(video);
video.src = url;
await completer.future;
} on DomException catch (e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
}
}
main() {
if (MediaStream.supported) {
test('getUserMedia audio', () async {
try {
var mediaStream = await window.navigator.getUserMedia(audio: true);
expect(mediaStream, isNotNull);
expect(mediaStream is MediaStream, true);
var devices = window.navigator.mediaDevices;
var enumDevices = await devices.enumerateDevices();
expect(enumDevices.length > 1, true);
for (var device in enumDevices) {
var goodDevLabel = device.label.endsWith('Built-in Output') ||
device.label.endsWith('Built-in Microphone');
expect(goodDevLabel, true);
}
} on DomException catch (e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
}
await testUserMediaAudio(window.navigator
.getUserMedia(audio: true)); // Deprecated way to get a media stream.
await testUserMediaAudio(
window.navigator.mediaDevices.getUserMedia({'audio': true}));
});
test('getUserMedia', () {
return window.navigator.getUserMedia(video: true).then((stream) {
expect(stream, isNotNull);
var url = Url.createObjectUrlFromStream(stream);
expect(url, isNotNull);
var video = new VideoElement()..autoplay = true;
var completer = new Completer();
video.onError.listen((e) {
completer.completeError(e);
});
video.onPlaying.first.then((e) {
completer.complete(video);
});
document.body!.append(video);
video.src = url;
return completer.future;
}).catchError((dynamic e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
});
test('getUserMedia', () async {
await testUserMediaVideo(window.navigator
.getUserMedia(video: true)); // Deprecated way to get a media stream.
await testUserMediaVideo(
window.navigator.mediaDevices.getUserMedia({'video': true}));
});
test('getUserMediaComplexConstructor', () {
return window.navigator.getUserMedia(video: {
test('getUserMediaComplexConstructor', () async {
var videoOptions = {
'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
'optional': [
{'minFrameRate': 60},
{'maxWidth': 640}
]
}).then((stream) {
expect(stream, isNotNull);
var url = Url.createObjectUrlFromStream(stream);
expect(url, isNotNull);
var video = new VideoElement()..autoplay = true;
var completer = new Completer();
video.onError.listen((e) {
completer.completeError(e);
});
video.onPlaying.first.then((e) {
completer.complete(video);
});
document.body!.append(video);
video.src = url;
return completer.future;
}).catchError((dynamic e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
});
};
await testUserMediaVideo(window.navigator.getUserMedia(
video: videoOptions)); // Deprecated way to get a media stream.
await testUserMediaVideo(
window.navigator.mediaDevices.getUserMedia({'video': videoOptions}));
});
}
}

View file

@ -12,85 +12,81 @@ import 'package:async_helper/async_helper.dart';
// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
main() async {
testUserMediaAudio(Future userMediaFuture) async {
try {
var mediaStream = await userMediaFuture;
expect(mediaStream, isNotNull);
expect(mediaStream is MediaStream, true);
var devices = window.navigator.mediaDevices;
var enumDevices = await devices.enumerateDevices();
expect(enumDevices.length > 1, true);
for (var device in enumDevices) {
var goodDevLabel = device.label.endsWith('Built-in Output') ||
device.label.endsWith('Built-in Microphone');
expect(goodDevLabel, true);
}
} on DomException catch (e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
}
}
testUserMediaVideo(Future userMediaFuture) async {
try {
var mediaStream = await userMediaFuture;
expect(mediaStream, isNotNull);
var url = Url.createObjectUrlFromStream(mediaStream);
expect(url, isNotNull);
var video = new VideoElement()..autoplay = true;
var completer = new Completer();
video.onError.listen((e) {
completer.completeError(e);
});
video.onPlaying.first.then((e) {
completer.complete(video);
});
document.body.append(video);
video.src = url;
await completer.future;
} on DomException catch (e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
}
}
main() {
if (MediaStream.supported) {
test('getUserMedia audio', () async {
try {
var mediaStream = await window.navigator.getUserMedia(audio: true);
expect(mediaStream, isNotNull);
expect(mediaStream is MediaStream, true);
var devices = window.navigator.mediaDevices;
var enumDevices = await devices.enumerateDevices();
expect(enumDevices.length > 1, true);
for (var device in enumDevices) {
var goodDevLabel = device.label.endsWith('Built-in Output') ||
device.label.endsWith('Built-in Microphone');
expect(goodDevLabel, true);
}
} catch (e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
}
await testUserMediaAudio(window.navigator
.getUserMedia(audio: true)); // Deprecated way to get a media stream.
await testUserMediaAudio(
window.navigator.mediaDevices.getUserMedia({'audio': true}));
});
test('getUserMedia', () {
return window.navigator.getUserMedia(video: true).then((stream) {
expect(stream, isNotNull);
var url = Url.createObjectUrlFromStream(stream);
expect(url, isNotNull);
var video = new VideoElement()..autoplay = true;
var completer = new Completer();
video.onError.listen((e) {
completer.completeError(e);
});
video.onPlaying.first.then((e) {
completer.complete(video);
});
document.body.append(video);
video.src = url;
return completer.future;
}).catchError((e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
});
test('getUserMedia', () async {
await testUserMediaVideo(window.navigator
.getUserMedia(video: true)); // Deprecated way to get a media stream.
await testUserMediaVideo(
window.navigator.mediaDevices.getUserMedia({'video': true}));
});
test('getUserMediaComplexConstructor', () {
return window.navigator.getUserMedia(video: {
test('getUserMediaComplexConstructor', () async {
var videoOptions = {
'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
'optional': [
{'minFrameRate': 60},
{'maxWidth': 640}
]
}).then((stream) {
expect(stream, isNotNull);
var url = Url.createObjectUrlFromStream(stream);
expect(url, isNotNull);
var video = new VideoElement()..autoplay = true;
var completer = new Completer();
video.onError.listen((e) {
completer.completeError(e);
});
video.onPlaying.first.then((e) {
completer.complete(video);
});
document.body.append(video);
video.src = url;
return completer.future;
}).catchError((e) {
// Could fail if bot machine doesn't support audio or video.
expect(e.name == DomException.NOT_FOUND, true);
});
};
await testUserMediaVideo(window.navigator.getUserMedia(
video: videoOptions)); // Deprecated way to get a media stream.
await testUserMediaVideo(
window.navigator.mediaDevices.getUserMedia({'video': videoOptions}));
});
}
}

View file

@ -315,11 +315,6 @@ interface SVGNumber {
[DartStrictTypeChecking, Custom] attribute float value;
};
[DartSupplemental]
interface MediaDevices {
[DartSuppress] Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
};
[DartSupplemental]
interface Navigator {
[DartSuppress] void getUserMedia(MediaStreamConstraints constraints,